0
# Environment Management
1
2
Python environment detection and management supporting virtualenvs, system environments, and custom Python installations. Provides environment-aware analysis and completion with proper isolation and version-specific behavior.
3
4
## Capabilities
5
6
### Environment Discovery
7
8
Discover available Python environments including virtual environments and system installations.
9
10
```python { .api }
11
def find_virtualenvs(paths=None, *, safe=True, use_environment_vars=True):
12
"""
13
Find virtual environments.
14
15
Parameters:
16
- paths (list, optional): Paths to search for virtual environments.
17
- safe (bool): Only return safe/valid environments. Default True.
18
- use_environment_vars (bool): Use environment variables in search. Default True.
19
20
Returns:
21
Generator of Environment objects.
22
"""
23
24
def find_system_environments(*, env_vars=None):
25
"""
26
Find system Python environments.
27
28
Parameters:
29
- env_vars (dict, optional): Environment variables to use.
30
31
Returns:
32
Generator of Environment objects.
33
"""
34
```
35
36
**Usage Example:**
37
```python
38
import jedi
39
from jedi.api.environment import find_virtualenvs, find_system_environments
40
41
# Find all virtual environments
42
print("Virtual environments:")
43
for env in find_virtualenvs():
44
print(f" {env.path} - Python {env.version_info}")
45
print(f" Executable: {env.executable}")
46
47
# Find system Python installations
48
print("\nSystem environments:")
49
for env in find_system_environments():
50
print(f" {env.path} - Python {env.version_info}")
51
print(f" Executable: {env.executable}")
52
53
# Search specific paths for virtual environments
54
custom_paths = ["/home/user/.virtualenvs", "/opt/venvs"]
55
for env in find_virtualenvs(paths=custom_paths):
56
print(f"Custom env: {env.path}")
57
```
58
59
### Environment Creation and Selection
60
61
Create and configure environments for jedi analysis.
62
63
```python { .api }
64
def create_environment(path, *, safe=True, env_vars=None):
65
"""
66
Create an environment from a path.
67
68
Parameters:
69
- path (str or Path): Path to Python executable or environment.
70
- safe (bool): Validate environment safety. Default True.
71
- env_vars (dict, optional): Environment variables.
72
73
Returns:
74
Environment object.
75
"""
76
77
def get_default_environment():
78
"""
79
Get the default Python environment.
80
81
Returns:
82
Environment object for current Python.
83
"""
84
85
def get_system_environment(version, *, env_vars=None):
86
"""
87
Get a specific system environment by version.
88
89
Parameters:
90
- version (str): Python version (e.g., '3.9', '3.10').
91
- env_vars (dict, optional): Environment variables.
92
93
Returns:
94
Environment object or None if not found.
95
"""
96
```
97
98
**Usage Example:**
99
```python
100
import jedi
101
from jedi.api.environment import (
102
create_environment, get_default_environment, get_system_environment
103
)
104
105
# Get default environment
106
default_env = get_default_environment()
107
print(f"Default: Python {default_env.version_info} at {default_env.executable}")
108
109
# Create environment from specific path
110
venv_path = "/path/to/venv/bin/python"
111
try:
112
custom_env = create_environment(venv_path)
113
print(f"Custom env: Python {custom_env.version_info}")
114
except jedi.InvalidPythonEnvironment:
115
print("Invalid environment path")
116
117
# Get specific Python version
118
py39_env = get_system_environment("3.9")
119
if py39_env:
120
print(f"Python 3.9: {py39_env.executable}")
121
else:
122
print("Python 3.9 not found")
123
124
# Use environment with Script
125
script = jedi.Script(
126
code="import sys; sys.version",
127
environment=custom_env
128
)
129
```
130
131
### Environment Properties and Information
132
133
Access environment properties and system information.
134
135
```python { .api }
136
class Environment:
137
executable: Path # Python executable path
138
path: Path # Environment path (sys.prefix)
139
version_info: tuple # Python version tuple (major, minor, micro)
140
141
def get_sys_path(self):
142
"""Get sys.path for this environment."""
143
144
def get_grammar(self):
145
"""
146
Get parso grammar for this Python version.
147
148
Returns:
149
Grammar: Parso grammar object for parsing Python code.
150
"""
151
```
152
153
**Usage Example:**
154
```python
155
import jedi
156
from jedi.api.environment import find_virtualenvs
157
158
for env in find_virtualenvs():
159
print(f"Environment: {env.path}")
160
print(f"Executable: {env.executable}")
161
print(f"Python version: {env.version_info}")
162
163
# Get environment-specific sys.path
164
sys_path = env.get_sys_path()
165
print(f"Sys path entries: {len(sys_path)}")
166
for path in sys_path[:3]: # Show first 3 entries
167
print(f" {path}")
168
169
# Get grammar for this Python version
170
grammar = env.get_grammar()
171
print(f"Grammar version: {grammar.version}")
172
print("---")
173
```
174
175
### Environment-Aware Analysis
176
177
Use specific environments for version-appropriate analysis and completions.
178
179
**Usage Example:**
180
```python
181
import jedi
182
from jedi.api.environment import get_system_environment
183
184
# Code that uses Python 3.8+ features
185
code = '''
186
# Python 3.8+ walrus operator
187
if (n := len([1, 2, 3])) > 2:
188
print(f"Length is {n}")
189
190
# Type hints
191
from typing import List, Dict
192
def process_data(items: List[str]) -> Dict[str, int]:
193
return {item: len(item) for item in items}
194
'''
195
196
# Analyze with Python 3.8
197
py38_env = get_system_environment("3.8")
198
if py38_env:
199
script = jedi.Script(code=code, environment=py38_env)
200
errors = script.get_syntax_errors()
201
print(f"Python 3.8 syntax errors: {len(errors)}")
202
203
# Analyze with Python 3.7 (should have syntax errors)
204
py37_env = get_system_environment("3.7")
205
if py37_env:
206
script = jedi.Script(code=code, environment=py37_env)
207
errors = script.get_syntax_errors()
208
print(f"Python 3.7 syntax errors: {len(errors)}")
209
for error in errors:
210
print(f" Line {error.line}: {error.get_message()}")
211
```
212
213
### Virtual Environment Integration
214
215
Integrate with virtual environments for isolated package analysis.
216
217
**Usage Example:**
218
```python
219
import jedi
220
from jedi.api.environment import find_virtualenvs
221
222
# Find virtual environment with specific packages
223
def find_env_with_package(package_name):
224
for env in find_virtualenvs():
225
# Test if package is available in environment
226
test_code = f"import {package_name}"
227
script = jedi.Script(code=test_code, environment=env)
228
229
# If no import errors, package is likely available
230
errors = script.get_syntax_errors()
231
if not errors:
232
# Try to get completions to verify package availability
233
completions = script.complete(line=1, column=len(f"import {package_name}."))
234
if completions:
235
return env
236
return None
237
238
# Find environment with Django
239
django_env = find_env_with_package("django")
240
if django_env:
241
print(f"Found Django in: {django_env.path}")
242
243
# Analyze Django-specific code
244
django_code = '''
245
from django.http import HttpResponse
246
from django.shortcuts import render
247
248
def my_view(request):
249
return HttpResponse("Hello")
250
'''
251
252
script = jedi.Script(code=django_code, environment=django_env)
253
completions = script.complete(line=4, column=20) # At HttpResponse
254
print(f"Django completions: {len(completions)}")
255
```
256
257
### Environment-Specific Completions
258
259
Get environment-appropriate completions and type information.
260
261
**Usage Example:**
262
```python
263
import jedi
264
from jedi.api.environment import get_default_environment, find_virtualenvs
265
266
code = '''
267
import sys
268
sys.'''
269
270
# Compare completions across environments
271
environments = [get_default_environment()]
272
environments.extend(list(find_virtualenvs())[:2]) # Add first 2 venvs
273
274
for i, env in enumerate(environments):
275
if env:
276
script = jedi.Script(code=code, environment=env)
277
completions = script.complete(line=2, column=4)
278
279
print(f"Environment {i+1} (Python {env.version_info}):")
280
print(f" Path: {env.path}")
281
print(f" Completions: {len(completions)}")
282
283
# Show version-specific attributes
284
version_attrs = [c for c in completions if 'version' in c.name.lower()]
285
for attr in version_attrs[:3]:
286
print(f" {attr.name}: {attr.description}")
287
print()
288
```
289
290
### Error Handling
291
292
Handle environment-related errors and validation.
293
294
```python { .api }
295
class InvalidPythonEnvironment(Exception):
296
"""Raised when Python environment is invalid or inaccessible."""
297
```
298
299
**Usage Example:**
300
```python
301
import jedi
302
from jedi.api.environment import create_environment, InvalidPythonEnvironment
303
304
# Attempt to create environments with error handling
305
test_paths = [
306
"/usr/bin/python3",
307
"/path/to/nonexistent/python",
308
"/bin/ls", # Not a Python executable
309
"/path/to/broken/venv/bin/python"
310
]
311
312
for path in test_paths:
313
try:
314
env = create_environment(path)
315
print(f"✓ Valid environment: {path}")
316
print(f" Python {env.version_info}")
317
except InvalidPythonEnvironment as e:
318
print(f"✗ Invalid environment: {path}")
319
print(f" Error: {e}")
320
except FileNotFoundError:
321
print(f"✗ Not found: {path}")
322
print()
323
324
# Safe environment creation
325
def safe_create_environment(path):
326
try:
327
return create_environment(path, safe=True)
328
except (InvalidPythonEnvironment, FileNotFoundError):
329
return None
330
331
env = safe_create_environment("/usr/bin/python3")
332
if env:
333
print(f"Successfully created environment: {env.executable}")
334
```
335
336
## Environment Types
337
338
### SameEnvironment
339
340
```python { .api }
341
class SameEnvironment(Environment):
342
"""Environment representing the current Python process."""
343
```
344
345
### InterpreterEnvironment
346
347
```python { .api }
348
class InterpreterEnvironment(SameEnvironment):
349
"""Environment optimized for interpreter usage."""
350
```
351
352
**Usage Example:**
353
```python
354
import jedi
355
from jedi.api.environment import InterpreterEnvironment
356
357
# Create interpreter-specific environment
358
env = InterpreterEnvironment()
359
360
# Use with Interpreter class
361
namespaces = [globals(), locals()]
362
interpreter = jedi.Interpreter('import os; os.', namespaces, environment=env)
363
completions = interpreter.complete()
364
365
print(f"Interpreter environment completions: {len(completions)}")
366
```