0
# Project Configuration
1
2
Project-level configuration and management including sys.path customization, extension loading, and multi-file analysis scope. Enables project-aware analysis and search with proper dependency resolution and workspace understanding.
3
4
## Capabilities
5
6
### Project Creation and Configuration
7
8
Create and configure projects for comprehensive code analysis with custom settings.
9
10
```python { .api }
11
class Project:
12
def __init__(self, path, *, environment_path=None, load_unsafe_extensions=False,
13
sys_path=None, added_sys_path=(), smart_sys_path=True):
14
"""
15
Create a project configuration.
16
17
Parameters:
18
- path (str or Path): Base project path.
19
- environment_path (str, optional): Python environment path.
20
- load_unsafe_extensions (bool): Load unsafe extensions. Default False.
21
- sys_path (list, optional): Custom sys.path override.
22
- added_sys_path (tuple): Additional sys.path entries. Default ().
23
- smart_sys_path (bool): Calculate intelligent sys.path. Default True.
24
"""
25
```
26
27
**Usage Example:**
28
```python
29
import jedi
30
from jedi import Project
31
from pathlib import Path
32
33
# Basic project setup
34
project_path = Path("/path/to/my/project")
35
project = Project(project_path)
36
37
# Project with custom sys.path
38
custom_paths = ["/path/to/dependencies", "/opt/custom/libs"]
39
project = Project(
40
project_path,
41
added_sys_path=tuple(custom_paths),
42
smart_sys_path=True
43
)
44
45
# Project with specific environment
46
project = Project(
47
project_path,
48
environment_path="/path/to/venv/bin/python"
49
)
50
51
# Use project with Script
52
code = '''
53
import my_local_module
54
from utils import helper_function
55
'''
56
57
script = jedi.Script(code=code, path=project_path / "main.py", project=project)
58
completions = script.complete(line=2, column=20)
59
```
60
61
### Project Properties and Settings
62
63
Access and configure project properties for analysis behavior.
64
65
```python { .api }
66
class Project:
67
path: Path # Base project path
68
sys_path: list # Custom sys.path
69
smart_sys_path: bool # Whether to calculate smart sys.path
70
load_unsafe_extensions: bool # Load unsafe extensions
71
added_sys_path: tuple # Additional sys.path entries
72
73
def get_environment(self):
74
"""Get project environment."""
75
76
def save(self):
77
"""Save project configuration to .jedi/project.json"""
78
```
79
80
**Usage Example:**
81
```python
82
import jedi
83
from jedi import Project
84
85
project = Project("/path/to/project")
86
87
# Check project settings
88
print(f"Project path: {project.path}")
89
print(f"Custom sys.path: {project.sys_path}")
90
print(f"Added paths: {project.added_sys_path}")
91
print(f"Smart sys.path: {project.smart_sys_path}")
92
print(f"Load unsafe extensions: {project.load_unsafe_extensions}")
93
94
# Get project environment
95
env = project.get_environment()
96
print(f"Project Python: {env.executable}")
97
print(f"Project Python version: {env.version_info}")
98
99
# Save configuration
100
project.save() # Creates .jedi/project.json
101
```
102
103
### Project Loading and Persistence
104
105
Load and save project configurations for consistent analysis settings.
106
107
```python { .api }
108
@classmethod
109
def load(cls, path):
110
"""
111
Load project configuration from path.
112
113
Parameters:
114
- path (str or Path): Project path containing .jedi/project.json.
115
116
Returns:
117
Project object with loaded configuration.
118
"""
119
```
120
121
**Usage Example:**
122
```python
123
import jedi
124
from jedi import Project
125
from pathlib import Path
126
127
# Create and configure project
128
project_path = Path("/path/to/project")
129
project = Project(
130
project_path,
131
added_sys_path=("/opt/custom/libs",),
132
load_unsafe_extensions=True
133
)
134
135
# Save configuration
136
project.save()
137
138
# Later, load the same configuration
139
loaded_project = Project.load(project_path)
140
print(f"Loaded project: {loaded_project.path}")
141
print(f"Loaded settings: {loaded_project.added_sys_path}")
142
143
# Use loaded project
144
script = jedi.Script(
145
path=project_path / "main.py",
146
project=loaded_project
147
)
148
```
149
150
### Default Project Management
151
152
Get default project configurations based on file locations and context.
153
154
```python { .api }
155
def get_default_project(path=None):
156
"""
157
Get default project configuration for a path.
158
159
Parameters:
160
- path (str or Path, optional): File or directory path.
161
162
Returns:
163
Project object with intelligent defaults.
164
"""
165
```
166
167
**Usage Example:**
168
```python
169
import jedi
170
from jedi import get_default_project
171
172
# Get default project for current directory
173
default_project = get_default_project()
174
print(f"Default project path: {default_project.path}")
175
176
# Get project for specific file
177
file_path = "/path/to/project/src/main.py"
178
file_project = get_default_project(file_path)
179
print(f"File project path: {file_project.path}")
180
181
# Use with Script
182
script = jedi.Script(
183
code="import local_module",
184
path=file_path,
185
project=file_project
186
)
187
188
# The project helps resolve local imports
189
completions = script.complete(line=1, column=18)
190
```
191
192
### Project-Wide Search
193
194
Search for symbols across the entire project with scope control.
195
196
```python { .api }
197
def search(self, string, *, all_scopes=False):
198
"""
199
Search for names across the entire project.
200
201
Parameters:
202
- string (str): Search string pattern.
203
- all_scopes (bool): Search in all scopes. Default False.
204
205
Returns:
206
Generator of Name objects from across the project.
207
"""
208
209
def complete_search(self, string, **kwargs):
210
"""
211
Search with completion-style matching across project.
212
213
Parameters:
214
- string (str): Search string pattern.
215
- **kwargs: Additional search options.
216
217
Returns:
218
Generator of Completion objects from across the project.
219
"""
220
```
221
222
**Usage Example:**
223
```python
224
import jedi
225
from jedi import Project
226
227
# Set up project
228
project = Project("/path/to/large/project")
229
230
# Search for class definitions across the project
231
class_results = list(project.search("class:MyClass"))
232
for result in class_results:
233
print(f"Found class: {result.name}")
234
print(f" File: {result.module_path}")
235
print(f" Line: {result.line}")
236
237
# Search for function definitions
238
function_results = list(project.search("function:process_data"))
239
for result in function_results:
240
print(f"Found function: {result.name}")
241
print(f" Module: {result.module_name}")
242
print(f" Full name: {result.full_name}")
243
244
# Fuzzy search across project
245
fuzzy_results = list(project.complete_search("proc", fuzzy=True))
246
for result in fuzzy_results:
247
print(f"Fuzzy match: {result.name} in {result.module_name}")
248
249
# Search in all scopes (including local variables)
250
all_scope_results = list(project.search("temp_var", all_scopes=True))
251
```
252
253
### Multi-File Analysis Context
254
255
Enable cross-file analysis and import resolution within project scope.
256
257
**Usage Example:**
258
```python
259
import jedi
260
from jedi import Project
261
262
# Project structure:
263
# /project/
264
# ├── main.py
265
# ├── utils/
266
# │ ├── __init__.py
267
# │ └── helpers.py
268
# └── models/
269
# ├── __init__.py
270
# └── user.py
271
272
project = Project("/project")
273
274
# File: models/user.py
275
user_model_code = '''
276
class User:
277
def __init__(self, name, email):
278
self.name = name
279
self.email = email
280
281
def get_display_name(self):
282
return f"{self.name} <{self.email}>"
283
'''
284
285
# File: utils/helpers.py
286
helpers_code = '''
287
from models.user import User
288
289
def create_admin_user():
290
return User("Admin", "admin@example.com")
291
292
def format_user_list(users):
293
return [user.get_display_name() for user in users]
294
'''
295
296
# File: main.py
297
main_code = '''
298
from utils.helpers import create_admin_user, format_user_list
299
from models.user import User
300
301
# Create users
302
admin = create_admin_user()
303
regular_user = User("John", "john@example.com")
304
305
# Format for display
306
users = [admin, regular_user]
307
formatted = format_user_list(users)
308
'''
309
310
# Analyze main.py with project context
311
script = jedi.Script(
312
code=main_code,
313
path="/project/main.py",
314
project=project
315
)
316
317
# Get completions for imported functions
318
completions = script.complete(line=5, column=15) # At 'create_admin_user'
319
print("Available completions:")
320
for comp in completions:
321
print(f" {comp.name}: {comp.type}")
322
323
# Navigate to definition across files
324
definitions = script.goto(line=5, column=8, follow_imports=True) # At 'create_admin_user'
325
for defn in definitions:
326
print(f"Definition: {defn.name}")
327
print(f" File: {defn.module_path}")
328
print(f" Line: {defn.line}")
329
330
# Find references across the project
331
references = script.get_references(line=6, column=15) # At 'User'
332
print("References across project:")
333
for ref in references:
334
print(f" {ref.module_path}:{ref.line} - {ref.get_line_code().strip()}")
335
```
336
337
### Sys.path Customization
338
339
Customize Python module search paths for dependency resolution.
340
341
**Usage Example:**
342
```python
343
import jedi
344
from jedi import Project
345
346
# Project with custom dependencies
347
project = Project(
348
"/path/to/project",
349
added_sys_path=(
350
"/opt/custom/libraries",
351
"/home/user/dev/shared-utils",
352
"/path/to/vendor/packages"
353
),
354
smart_sys_path=True # Also include intelligent paths
355
)
356
357
# Code that imports from custom paths
358
code = '''
359
import custom_library
360
from shared_utils import common_functions
361
from vendor_package import specialized_tool
362
363
custom_library.'''
364
365
script = jedi.Script(code=code, project=project)
366
367
# Get completions from custom library
368
completions = script.complete(line=4, column=15)
369
print("Custom library completions:")
370
for comp in completions:
371
print(f" {comp.name}: {comp.type}")
372
373
# Override sys.path completely
374
project_override = Project(
375
"/path/to/project",
376
sys_path=[
377
"/custom/path/1",
378
"/custom/path/2",
379
"/usr/lib/python3.9/site-packages" # Keep standard library
380
],
381
smart_sys_path=False # Don't add intelligent paths
382
)
383
```
384
385
### Extension and Plugin Support
386
387
Configure loading of Jedi extensions and plugins for enhanced functionality.
388
389
**Usage Example:**
390
```python
391
import jedi
392
from jedi import Project
393
394
# Project with unsafe extensions enabled
395
project = Project(
396
"/path/to/project",
397
load_unsafe_extensions=True
398
)
399
400
# This enables additional analysis capabilities that might be unsafe
401
# in some environments but provide enhanced completions
402
script = jedi.Script(
403
code="import numpy as np; np.array([1,2,3]).",
404
project=project
405
)
406
407
# Extensions might provide better NumPy completions
408
completions = script.complete()
409
numpy_methods = [c for c in completions if 'array' in c.name.lower()]
410
print("Enhanced NumPy completions:")
411
for method in numpy_methods:
412
print(f" {method.name}: {method.description}")
413
```
414
415
### Project Configuration File
416
417
Manage project settings through configuration files.
418
419
**Configuration File Format (`.jedi/project.json`):**
420
```json
421
{
422
"added_sys_path": [
423
"/opt/custom/libs",
424
"/path/to/dependencies"
425
],
426
"load_unsafe_extensions": false,
427
"smart_sys_path": true,
428
"environment_path": "/path/to/venv/bin/python"
429
}
430
```
431
432
**Usage Example:**
433
```python
434
import jedi
435
from jedi import Project
436
import json
437
438
# Manually create configuration
439
config = {
440
"added_sys_path": ["/opt/custom/libs"],
441
"load_unsafe_extensions": False,
442
"smart_sys_path": True
443
}
444
445
# Save configuration manually
446
project_path = "/path/to/project"
447
config_dir = f"{project_path}/.jedi"
448
import os
449
os.makedirs(config_dir, exist_ok=True)
450
451
with open(f"{config_dir}/project.json", "w") as f:
452
json.dump(config, f, indent=2)
453
454
# Load project with configuration
455
project = Project.load(project_path)
456
print(f"Loaded config: {project.added_sys_path}")
457
```