|
| 1 | +# Search Paths and Glob Patterns |
| 2 | + |
| 3 | +This guide explains how to configure where the Python Environments extension searches for Python environments using search paths and glob patterns. By the end, you'll understand how to effectively customize environment discovery to match your development workflow. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +By default, the Python Environments extension automatically discovers environments in well-known locations like the workspace folders, common virtual environment directories, and system Python installations. However, you can customize where the extension searches using two settings: |
| 8 | + |
| 9 | +- **`python-envs.globalSearchPaths`**: Global search paths applied to all workspaces |
| 10 | +- **`python-envs.workspaceSearchPaths`**: Search paths specific to the current workspace |
| 11 | + |
| 12 | +Both settings support **glob patterns**, which allow you to specify flexible search patterns that match multiple directories. |
| 13 | + |
| 14 | +## When to Use Custom Search Paths |
| 15 | + |
| 16 | +Consider configuring custom search paths when: |
| 17 | + |
| 18 | +| Scenario | Example | |
| 19 | +| ------------------------------- | -------------------------------------------------------------- | |
| 20 | +| Centralized environment storage | All environments stored in `~/python-envs/` | |
| 21 | +| Mono-repo structure | Multiple projects with nested `.venv` folders | |
| 22 | +| Non-standard locations | Environments in `/opt/`, network drives, or custom directories | |
| 23 | +| Team conventions | Standardized environment naming patterns | |
| 24 | +| Testing scenarios | Temporary environments in test directories | |
| 25 | + |
| 26 | +## Configuring Search Paths |
| 27 | + |
| 28 | +### Global search paths |
| 29 | + |
| 30 | +Global search paths apply across all your VS Code workspaces. Use these for environment locations that are consistent across projects. |
| 31 | + |
| 32 | +1. Open Settings (`Cmd+,` on macOS, `Ctrl+,` on Windows/Linux). |
| 33 | +2. Search for `python-envs.globalSearchPaths`. |
| 34 | +3. Click **Add Item** to add a new path. |
| 35 | +4. Enter an absolute path or glob pattern. |
| 36 | + |
| 37 | +Example configuration: |
| 38 | + |
| 39 | +```json |
| 40 | +{ |
| 41 | + "python-envs.globalSearchPaths": [ |
| 42 | + "/Users/username/python-envs", |
| 43 | + "/Users/username/projects/*/venv", |
| 44 | + "/opt/python-environments/**" |
| 45 | + ] |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +### Workspace search paths |
| 50 | + |
| 51 | +Workspace search paths apply only to the current workspace. Use these for project-specific environment locations. |
| 52 | + |
| 53 | +1. Open Settings (`Cmd+,` on macOS, `Ctrl+,` on Windows/Linux). |
| 54 | +2. Switch to **Workspace** scope (not User). |
| 55 | +3. Search for `python-envs.workspaceSearchPaths`. |
| 56 | +4. Click **Add Item** to add a new path. |
| 57 | +5. Enter a relative path (from workspace root) or absolute path. |
| 58 | + |
| 59 | +Example configuration: |
| 60 | + |
| 61 | +```json |
| 62 | +{ |
| 63 | + "python-envs.workspaceSearchPaths": [".venv", "tests/**/.venv", "services/*/env"] |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +> **Note**: Relative paths in `workspaceSearchPaths` are resolved from the workspace root directory. |
| 68 | +
|
| 69 | +## Glob Pattern Syntax |
| 70 | + |
| 71 | +Glob patterns provide a flexible way to match multiple directories using wildcards. The extension supports standard glob syntax: |
| 72 | + |
| 73 | +### Basic wildcards |
| 74 | + |
| 75 | +| Pattern | Matches | Example | |
| 76 | +| ------- | --------------------------------------------------------- | ------------------------------------------------------------------ | |
| 77 | +| `*` | Any sequence of characters within a single path component | `envs/*` matches `envs/project1` but not `envs/nested/project2` | |
| 78 | +| `**` | Any sequence of path components (recursive) | `projects/**/.venv` matches `.venv` at any depth under `projects/` | |
| 79 | +| `?` | Any single character | `project?` matches `project1`, `projectA` | |
| 80 | +| `[...]` | Any character inside the brackets | `project[0-9]` matches `project0` through `project9` | |
| 81 | + |
| 82 | +### Pattern examples |
| 83 | + |
| 84 | +```json |
| 85 | +{ |
| 86 | + "python-envs.globalSearchPaths": [ |
| 87 | + // Specific directory (no wildcard needed) |
| 88 | + "/Users/username/main-env", |
| 89 | + |
| 90 | + // All direct subdirectories of envs/ |
| 91 | + "/Users/username/envs/*", |
| 92 | + |
| 93 | + // All .venv directories at any depth |
| 94 | + "/Users/username/projects/**/.venv", |
| 95 | + |
| 96 | + // All venv directories at any depth |
| 97 | + "/Users/username/projects/**/venv", |
| 98 | + |
| 99 | + // Numbered project directories |
| 100 | + "/Users/username/project[0-9]", |
| 101 | + |
| 102 | + // Multiple levels with wildcards |
| 103 | + "/Users/username/clients/*/projects/*/env" |
| 104 | + ] |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +## How Glob Expansion Works |
| 109 | + |
| 110 | +When you specify a glob pattern, the extension: |
| 111 | + |
| 112 | +1. **Expands the pattern** to find all matching directories |
| 113 | +2. **Filters to directories only** (files are ignored unless they're Python executables) |
| 114 | +3. **Searches each directory** recursively for Python environments |
| 115 | + |
| 116 | +### Example expansion |
| 117 | + |
| 118 | +Given the pattern `/Users/username/projects/**/.venv`: |
| 119 | + |
| 120 | +``` |
| 121 | +projects/ |
| 122 | +├── backend/ |
| 123 | +│ └── .venv/ ← Matches |
| 124 | +├── frontend/ |
| 125 | +│ └── scripts/ |
| 126 | +│ └── .venv/ ← Matches |
| 127 | +└── ml-pipeline/ |
| 128 | + ├── training/ |
| 129 | + │ └── .venv/ ← Matches |
| 130 | + └── inference/ |
| 131 | + └── .venv/ ← Matches |
| 132 | +``` |
| 133 | + |
| 134 | +All four `.venv` directories are added to the search paths. |
| 135 | + |
| 136 | +## Performance Considerations |
| 137 | + |
| 138 | +⚠️ **Important**: Glob patterns can significantly impact discovery performance if used incorrectly. |
| 139 | + |
| 140 | +### What to avoid |
| 141 | + |
| 142 | +| Pattern | Problem | Impact | |
| 143 | +| -------------------- | ------------------------------ | -------------------------- | |
| 144 | +| `/**` | Searches the entire filesystem | Very slow, may time out | |
| 145 | +| `/Users/username/**` | Searches all user files | Extremely slow | |
| 146 | +| `path/to/project/**` | Lists every subdirectory | Redundant, slows discovery | |
| 147 | + |
| 148 | +### Best practices |
| 149 | + |
| 150 | +✅ **DO**: Use specific patterns |
| 151 | + |
| 152 | +```json |
| 153 | +{ |
| 154 | + "python-envs.workspaceSearchPaths": [ |
| 155 | + ".venv", // Root-level .venv |
| 156 | + "tests/**/.venv", // .venv directories under tests/ |
| 157 | + "services/*/env" // env directories one level under services/ |
| 158 | + ] |
| 159 | +} |
| 160 | +``` |
| 161 | + |
| 162 | +❌ **DON'T**: Use overly broad patterns |
| 163 | + |
| 164 | +```json |
| 165 | +{ |
| 166 | + "python-envs.workspaceSearchPaths": [ |
| 167 | + "**", // Every directory! Very slow |
| 168 | + "/Users/username/**" // Entire home directory! Extremely slow |
| 169 | + ] |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +### Understanding `**` vs. no pattern |
| 174 | + |
| 175 | +| Configuration | Behavior | |
| 176 | +| ----------------------- | ------------------------------------------------------------------------------ | |
| 177 | +| `"/path/to/project"` | ✅ Extension searches this directory recursively for environments | |
| 178 | +| `"/path/to/project/**"` | ⚠️ Extension treats EVERY subdirectory as a separate search path (inefficient) | |
| 179 | + |
| 180 | +> **Tip**: In most cases, you don't need `**` alone. Just specify the root directory and let the extension search recursively. |
| 181 | +
|
| 182 | +## Common Use Cases |
| 183 | + |
| 184 | +### Find all .venv directories in a mono-repo |
| 185 | + |
| 186 | +```json |
| 187 | +{ |
| 188 | + "python-envs.workspaceSearchPaths": ["**/.venv"] |
| 189 | +} |
| 190 | +``` |
| 191 | + |
| 192 | +This finds `.venv` directories at any depth without treating every subdirectory as a search path. |
| 193 | + |
| 194 | +### Centralized environment storage |
| 195 | + |
| 196 | +```json |
| 197 | +{ |
| 198 | + "python-envs.globalSearchPaths": ["/Users/username/python-environments/*"] |
| 199 | +} |
| 200 | +``` |
| 201 | + |
| 202 | +This searches all direct subdirectories of your centralized environment folder. |
| 203 | + |
| 204 | +### Team convention: environments named "env" or "venv" |
| 205 | + |
| 206 | +```json |
| 207 | +{ |
| 208 | + "python-envs.workspaceSearchPaths": ["**/env", "**/venv"] |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +### Multiple project structures |
| 213 | + |
| 214 | +```json |
| 215 | +{ |
| 216 | + "python-envs.workspaceSearchPaths": [ |
| 217 | + ".venv", // Root workspace environment |
| 218 | + "backend/.venv", // Backend service environment |
| 219 | + "services/*/venv", // Service-specific environments |
| 220 | + "tests/**/test-env" // Test environments at any depth |
| 221 | + ] |
| 222 | +} |
| 223 | +``` |
| 224 | + |
| 225 | +### Development and testing environments |
| 226 | + |
| 227 | +```json |
| 228 | +{ |
| 229 | + "python-envs.globalSearchPaths": ["/opt/python/dev/*", "/opt/python/test/*", "/Users/username/temp/envs/*"] |
| 230 | +} |
| 231 | +``` |
| 232 | + |
| 233 | +## Integration with Legacy Settings |
| 234 | + |
| 235 | +The extension merges custom search paths with legacy Python extension settings for backward compatibility. |
| 236 | + |
| 237 | +### Settings that are merged |
| 238 | + |
| 239 | +| Legacy Setting | Equivalent Modern Setting | |
| 240 | +| -------------------- | ------------------------------------------- | |
| 241 | +| `python.venvPath` | Merged into `python-envs.globalSearchPaths` | |
| 242 | +| `python.venvFolders` | Merged into `python-envs.globalSearchPaths` | |
| 243 | + |
| 244 | +If you have both configured, the extension combines all paths into one search list. |
| 245 | + |
| 246 | +### Migration example |
| 247 | + |
| 248 | +**Before** (legacy Python extension): |
| 249 | + |
| 250 | +```json |
| 251 | +{ |
| 252 | + "python.venvPath": "/Users/username/envs", |
| 253 | + "python.venvFolders": ["venv", ".venv"] |
| 254 | +} |
| 255 | +``` |
| 256 | + |
| 257 | +**After** (modern Python Environments): |
| 258 | + |
| 259 | +```json |
| 260 | +{ |
| 261 | + "python-envs.globalSearchPaths": ["/Users/username/envs/*", "**/venv", "**/.venv"] |
| 262 | +} |
| 263 | +``` |
| 264 | + |
| 265 | +> **Note**: You can continue using legacy settings, but migrating to `python-envs.globalSearchPaths` provides more flexibility with glob patterns. |
| 266 | +
|
| 267 | +## Troubleshooting |
| 268 | + |
| 269 | +### Environments not appearing |
| 270 | + |
| 271 | +If your environments aren't discovered: |
| 272 | + |
| 273 | +1. **Verify paths are absolute** (for global search paths) or relative to workspace root (for workspace search paths) |
| 274 | +2. **Check path separators**: Use `/` even on Windows |
| 275 | +3. **Test without glob patterns first**: Start with a simple directory path, then add patterns |
| 276 | +4. **Check extension logs**: Open **Output** panel and select **Python Environments** to see discovery logs |
| 277 | +5. **Verify directory exists**: Glob patterns that match nothing are silently ignored |
| 278 | + |
| 279 | +### Slow environment discovery |
| 280 | + |
| 281 | +If discovery is taking too long: |
| 282 | + |
| 283 | +1. **Review glob patterns**: Look for overly broad patterns like `**` or `/Users/**` |
| 284 | +2. **Be more specific**: Replace `projects/**` with `projects/**/.venv` to target specific directories |
| 285 | +3. **Reduce search paths**: Remove paths that don't contain environments |
| 286 | +4. **Use root directories**: Instead of `path/**`, use `path` and let the extension search recursively |
| 287 | + |
| 288 | +### Duplicate environments |
| 289 | + |
| 290 | +If environments appear multiple times: |
| 291 | + |
| 292 | +1. **Check for overlapping paths**: Ensure patterns don't match the same directories |
| 293 | +2. **Remove redundant patterns**: If you specify both `projects/` and `projects/**/.venv`, the latter is sufficient |
| 294 | +3. **Review workspace vs. global settings**: Ensure you're not duplicating paths across scopes |
| 295 | + |
| 296 | +## Quick Reference: Settings |
| 297 | + |
| 298 | +| Setting | Scope | Description | |
| 299 | +| ---------------------------------- | ----------------- | -------------------------------------------------------------------------- | |
| 300 | +| `python-envs.globalSearchPaths` | User or Workspace | Array of absolute paths or glob patterns searched across all workspaces | |
| 301 | +| `python-envs.workspaceSearchPaths` | Workspace | Array of relative or absolute paths searched in the current workspace only | |
| 302 | +| `python.venvPath` | User or Workspace | Legacy setting merged into global search paths | |
| 303 | +| `python.venvFolders` | User or Workspace | Legacy setting merged into global search paths | |
| 304 | + |
| 305 | +## Pattern Reference |
| 306 | + |
| 307 | +### Quick pattern guide |
| 308 | + |
| 309 | +```json |
| 310 | +{ |
| 311 | + "python-envs.globalSearchPaths": [ |
| 312 | + "/absolute/path", // Specific directory |
| 313 | + "/parent/*", // Direct children only |
| 314 | + "/parent/**/target", // Target directories at any depth |
| 315 | + "/parent/child[0-9]", // Numbered children |
| 316 | + "/parent/child?", // Single character wildcard |
| 317 | + "/parent/{option1,option2}/env" // Alternative branches (if supported) |
| 318 | + ] |
| 319 | +} |
| 320 | +``` |
| 321 | + |
| 322 | +### Platform-specific examples |
| 323 | + |
| 324 | +**macOS/Linux**: |
| 325 | + |
| 326 | +```json |
| 327 | +{ |
| 328 | + "python-envs.globalSearchPaths": [ |
| 329 | + "/opt/python-envs/*", |
| 330 | + "~/.local/share/virtualenvs/*", |
| 331 | + "/usr/local/python-environments/*" |
| 332 | + ] |
| 333 | +} |
| 334 | +``` |
| 335 | + |
| 336 | +**Windows**: |
| 337 | + |
| 338 | +```json |
| 339 | +{ |
| 340 | + "python-envs.globalSearchPaths": [ |
| 341 | + "C:/Python/Environments/*", |
| 342 | + "C:/Users/username/python-envs/*", |
| 343 | + "D:/Development/*/venv" |
| 344 | + ] |
| 345 | +} |
| 346 | +``` |
| 347 | + |
| 348 | +> **Note**: Use forward slashes `/` even on Windows. |
| 349 | +
|
| 350 | +## Related Resources |
| 351 | + |
| 352 | +- [Managing Python Projects](managing-python-projects.md): Learn how to organize projects with their own environments |
| 353 | +- [Environment Management](../README.md#environment-management): Learn about creating and managing Python environments |
| 354 | +- [Settings Reference](../README.md#settings-reference): Complete list of extension settings |
0 commit comments