0
# Environment Detection
1
2
Automatically detects and configures for virtual environments including venv, virtualenv, conda, and Poetry with robust path resolution and interpreter discovery.
3
4
## Capabilities
5
6
### Main Detection Function
7
8
Primary function for automatically detecting active virtual environments.
9
10
```python { .api }
11
def detect_active_interpreter() -> str:
12
"""
13
Attempt to detect a venv, virtualenv, poetry, or conda environment.
14
15
Tries multiple detection methods in order:
16
1. venv/virtualenv (via VIRTUAL_ENV environment variable)
17
2. conda (via CONDA_PREFIX environment variable)
18
3. Poetry (via poetry CLI command)
19
20
Returns:
21
Path to the detected Python interpreter
22
23
Raises:
24
SystemExit: If unable to detect any virtual environment
25
"""
26
```
27
28
### Individual Detection Functions
29
30
Specific detection methods for different environment types.
31
32
```python { .api }
33
def detect_venv_or_virtualenv_interpreter() -> Path | None:
34
"""
35
Detect venv or virtualenv using VIRTUAL_ENV environment variable.
36
37
Both venv (Python 3.3+) and virtualenv set the VIRTUAL_ENV variable
38
when activated, pointing to the environment root directory.
39
40
Returns:
41
Path to Python interpreter in the virtual environment, or None if not detected
42
"""
43
44
def detect_conda_env_interpreter() -> Path | None:
45
"""
46
Detect conda environment using CONDA_PREFIX environment variable.
47
48
Conda sets CONDA_PREFIX to the active environment path when activated.
49
Handles platform differences in interpreter location.
50
51
Returns:
52
Path to Python interpreter in conda environment, or None if not detected
53
"""
54
55
def detect_poetry_env_interpreter() -> Path | None:
56
"""
57
Detect Poetry environment by executing 'poetry env info --executable'.
58
59
Poetry doesn't set environment variables like other tools, so we query
60
the Poetry CLI directly to get the active interpreter path.
61
62
Returns:
63
Path to Python interpreter in Poetry environment, or None if not detected
64
"""
65
```
66
67
### Utility Functions
68
69
Helper functions for path and platform handling.
70
71
```python { .api }
72
def determine_bin_dir() -> str:
73
"""
74
Determine the correct binary directory name for the current platform.
75
76
Returns:
77
'Scripts' on Windows, 'bin' on POSIX systems
78
"""
79
80
def determine_interpreter_file_name() -> str | None:
81
"""
82
Determine the correct Python interpreter filename for the platform.
83
84
Handles different Python implementations and platform-specific extensions.
85
86
Returns:
87
Interpreter filename ('python', 'python.exe', 'pypy', 'pypy.exe', etc.)
88
or None if implementation not recognized
89
"""
90
```
91
92
## Usage Examples
93
94
### Basic Environment Detection
95
96
```python
97
from pipdeptree._detect_env import detect_active_interpreter
98
from pipdeptree._discovery import get_installed_distributions
99
100
try:
101
# Auto-detect current virtual environment
102
interpreter = detect_active_interpreter()
103
print(f"Detected interpreter: {interpreter}")
104
105
# Use detected interpreter for package discovery
106
packages = get_installed_distributions(interpreter=interpreter)
107
print(f"Found {len(packages)} packages in environment")
108
109
except SystemExit:
110
print("No virtual environment detected")
111
# Fall back to system Python
112
packages = get_installed_distributions()
113
```
114
115
### Manual Detection Methods
116
117
```python
118
from pipdeptree._detect_env import (
119
detect_venv_or_virtualenv_interpreter,
120
detect_conda_env_interpreter,
121
detect_poetry_env_interpreter
122
)
123
124
# Try each detection method individually
125
venv_path = detect_venv_or_virtualenv_interpreter()
126
if venv_path:
127
print(f"Found venv/virtualenv: {venv_path}")
128
129
conda_path = detect_conda_env_interpreter()
130
if conda_path:
131
print(f"Found conda environment: {conda_path}")
132
133
poetry_path = detect_poetry_env_interpreter()
134
if poetry_path:
135
print(f"Found Poetry environment: {poetry_path}")
136
```
137
138
### Integration with CLI
139
140
```python
141
from pipdeptree._cli import get_options
142
from pipdeptree._detect_env import detect_active_interpreter
143
144
# CLI automatically uses environment detection when --python auto is specified
145
options = get_options(['--python', 'auto'])
146
147
# This triggers environment detection internally:
148
if options.python == "auto":
149
resolved_path = detect_active_interpreter()
150
options.python = resolved_path
151
print(f"Resolved python: {resolved_path}")
152
```
153
154
## Environment Types Supported
155
156
### venv (Python 3.3+)
157
158
Built-in virtual environment support using the `venv` module:
159
160
```bash
161
python -m venv myenv
162
source myenv/bin/activate # Linux/Mac
163
# or myenv\Scripts\activate # Windows
164
165
# Detection uses VIRTUAL_ENV environment variable
166
echo $VIRTUAL_ENV # /path/to/myenv
167
```
168
169
Detection logic:
170
- Checks `VIRTUAL_ENV` environment variable
171
- Appends appropriate `bin/` or `Scripts/` directory
172
- Adds correct interpreter filename with platform extension
173
174
### virtualenv
175
176
Third-party virtual environment tool with broader Python version support:
177
178
```bash
179
pip install virtualenv
180
virtualenv myenv
181
source myenv/bin/activate
182
183
# Also sets VIRTUAL_ENV like venv
184
echo $VIRTUAL_ENV # /path/to/myenv
185
```
186
187
Uses the same detection logic as venv since both tools set `VIRTUAL_ENV`.
188
189
### conda/mamba Environments
190
191
Anaconda/Miniconda/Mamba package and environment management:
192
193
```bash
194
conda create -n myenv python=3.9
195
conda activate myenv
196
197
# Detection uses CONDA_PREFIX environment variable
198
echo $CONDA_PREFIX # /path/to/miniconda3/envs/myenv
199
```
200
201
Detection logic:
202
- Checks `CONDA_PREFIX` environment variable
203
- On POSIX: interpreter in `bin/` subdirectory
204
- On Windows: interpreter in root directory
205
- Handles different Python implementations (CPython, PyPy)
206
207
### Poetry Environments
208
209
Poetry dependency management with automatic virtual environments:
210
211
```bash
212
poetry install
213
poetry shell
214
215
# Poetry doesn't set environment variables
216
# Detection queries Poetry CLI directly
217
poetry env info --executable
218
```
219
220
Detection logic:
221
- Executes `poetry env info --executable` command
222
- Captures stdout containing interpreter path
223
- Returns None if Poetry not available or command fails
224
- Handles all Poetry configuration methods (in-project, cached, etc.)
225
226
## Platform Handling
227
228
### Directory Structure Differences
229
230
**POSIX (Linux, macOS, etc.):**
231
```
232
venv/
233
├── bin/
234
│ ├── python
235
│ └── activate
236
└── lib/python3.x/site-packages/
237
```
238
239
**Windows:**
240
```
241
venv/
242
├── Scripts/
243
│ ├── python.exe
244
│ └── activate.bat
245
└── Lib/site-packages/
246
```
247
248
### Python Implementation Support
249
250
Detects different Python implementations:
251
252
- **CPython**: `python` / `python.exe`
253
- **PyPy**: `pypy` / `pypy.exe`
254
- **Other implementations**: Returns None (not supported)
255
256
### Error Handling
257
258
The detection system gracefully handles various error conditions:
259
260
```python
261
# Environment variable not set
262
if not os.environ.get("VIRTUAL_ENV"):
263
return None
264
265
# Interpreter file doesn't exist
266
if not interpreter_path.exists():
267
return None # Detection continues with next method
268
269
# Poetry command fails
270
try:
271
result = subprocess.run(["poetry", "env", "info", "--executable"], ...)
272
except Exception:
273
return None # Poetry not available or failed
274
```
275
276
## Integration Points
277
278
### CLI Integration
279
280
The `--python auto` option triggers automatic detection:
281
282
```bash
283
pipdeptree --python auto
284
# (resolved python: /path/to/detected/interpreter)
285
```
286
287
### Discovery Integration
288
289
Environment detection integrates with package discovery:
290
291
```python
292
# Auto-detection in get_installed_distributions
293
if interpreter_path != sys.executable:
294
# Query the detected interpreter for its packages
295
computed_paths = query_interpreter_for_paths(interpreter_path)
296
```
297
298
### Error Messages
299
300
Clear error reporting when detection fails:
301
302
```
303
Unable to detect virtual environment.
304
```
305
306
The detection system exits with code 1 when no environment is found, allowing users to fall back to explicit interpreter specification.