0
# Setuptools Integration
1
2
Import Tracker provides powerful setuptools integration that automatically generates `install_requires` and `extras_require` configurations by analyzing project dependencies. This eliminates manual dependency management and ensures setuptools configurations stay synchronized with actual code requirements.
3
4
## Capabilities
5
6
### Requirements Parsing and Analysis
7
8
Analyzes a library's dependency patterns to automatically determine which packages should be core requirements versus optional extras, generating proper setuptools configuration.
9
10
```python { .api }
11
def parse_requirements(
12
requirements: Union[List[str], str],
13
library_name: str,
14
extras_modules: Optional[List[str]] = None,
15
**kwargs,
16
) -> Tuple[List[str], Dict[str, List[str]]]:
17
"""
18
Generate install_requires and extras_require from requirements and library analysis.
19
20
Parameters:
21
- requirements: Union[List[str], str] - List of requirement entries or file path to requirements file
22
- library_name: str - Top-level name of the library package to analyze
23
- extras_modules: Optional[List[str]] - Module names that should generate extras_require sets
24
- **kwargs - Additional arguments passed through to track_module
25
26
Returns:
27
Tuple[List[str], Dict[str, List[str]]] - (install_requires list, extras_require dict)
28
"""
29
```
30
31
**Usage Example:**
32
33
```python
34
from import_tracker.setup_tools import parse_requirements
35
36
# Using requirements file
37
install_requires, extras_require = parse_requirements(
38
requirements="requirements.txt",
39
library_name="mylib",
40
extras_modules=[
41
"mylib.visualization",
42
"mylib.database",
43
"mylib.ml"
44
]
45
)
46
47
# Using requirements list
48
requirements_list = [
49
"numpy>=1.20.0",
50
"pandas>=1.3.0",
51
"matplotlib>=3.0.0",
52
"sqlalchemy>=1.4.0",
53
"scikit-learn>=1.0.0"
54
]
55
56
install_requires, extras_require = parse_requirements(
57
requirements=requirements_list,
58
library_name="mylib",
59
extras_modules=["mylib.visualization", "mylib.database"]
60
)
61
62
print("Install requires:", install_requires)
63
# ['numpy>=1.20.0', 'pandas>=1.3.0']
64
65
print("Extras require:", extras_require)
66
# {
67
# 'mylib.visualization': ['matplotlib>=3.0.0'],
68
# 'mylib.database': ['sqlalchemy>=1.4.0'],
69
# 'all': ['matplotlib>=3.0.0', 'sqlalchemy>=1.4.0']
70
# }
71
```
72
73
### Setup.py Integration
74
75
Complete setup.py integration example showing how to use import_tracker for automated dependency management:
76
77
```python
78
# setup.py
79
import os
80
from setuptools import setup, find_packages
81
from import_tracker.setup_tools import parse_requirements
82
83
# Path to requirements file
84
requirements_file = os.path.join(os.path.dirname(__file__), "requirements.txt")
85
86
# Define which modules should be treated as extras
87
extras_modules = [
88
"mylib.visualization", # Optional plotting capabilities
89
"mylib.database", # Database connectivity
90
"mylib.ml", # Machine learning features
91
"mylib.web" # Web scraping utilities
92
]
93
94
# Parse requirements automatically
95
install_requires, extras_require = parse_requirements(
96
requirements=requirements_file,
97
library_name="mylib",
98
extras_modules=extras_modules,
99
recursive=True, # Analyze all submodules
100
num_jobs=4 # Use parallel processing
101
)
102
103
setup(
104
name="mylib",
105
version="1.0.0",
106
packages=find_packages(),
107
install_requires=install_requires,
108
extras_require=extras_require,
109
# ... other setup parameters
110
)
111
```
112
113
### Advanced Configuration Options
114
115
The parse_requirements function accepts all track_module parameters for fine-tuned analysis:
116
117
```python
118
install_requires, extras_require = parse_requirements(
119
requirements="requirements.txt",
120
library_name="mylib",
121
extras_modules=["mylib.advanced"],
122
123
# track_module options
124
recursive=True,
125
num_jobs=4,
126
detect_transitive=True,
127
side_effect_modules=["matplotlib.pyplot"],
128
log_level="INFO"
129
)
130
```
131
132
## Requirements File Format
133
134
Import Tracker supports standard pip requirements file format:
135
136
```txt
137
# Core dependencies
138
numpy>=1.20.0
139
pandas>=1.3.0
140
141
# Optional dependencies
142
matplotlib>=3.0.0
143
seaborn>=0.11.0
144
sqlalchemy>=1.4.0
145
psycopg2-binary>=2.8.0
146
scikit-learn>=1.0.0
147
torch>=1.9.0
148
149
# Development dependencies (will be excluded from extras if not used)
150
pytest>=6.0.0
151
black>=21.0.0
152
```
153
154
## Dependency Classification Logic
155
156
Import Tracker uses sophisticated logic to classify dependencies:
157
158
### Core Dependencies (install_requires)
159
160
Dependencies are included in `install_requires` if they are:
161
162
1. **Common Intersection**: Used by ALL specified extras modules
163
2. **Non-Extra Dependencies**: Required by modules not in the extras list
164
3. **Direct Dependencies**: Directly imported by parent modules when `detect_transitive=True`
165
4. **Untracked Requirements**: Listed in requirements.txt but not found in any tracked module (assumed to be runtime dependencies)
166
167
### Extras Dependencies (extras_require)
168
169
Dependencies are placed in specific extras if they are:
170
171
1. **Module-Specific**: Only used by that particular extras module
172
2. **Transitive**: Required transitively by the extras module
173
3. **Not in Core**: Not already included in install_requires
174
175
### Special "all" Extra
176
177
Import Tracker automatically creates an "all" extra that includes all optional dependencies:
178
179
```python
180
extras_require = {
181
'visualization': ['matplotlib>=3.0.0', 'seaborn>=0.11.0'],
182
'database': ['sqlalchemy>=1.4.0', 'psycopg2-binary>=2.8.0'],
183
'ml': ['scikit-learn>=1.0.0', 'torch>=1.9.0'],
184
'all': ['matplotlib>=3.0.0', 'seaborn>=0.11.0', 'sqlalchemy>=1.4.0',
185
'psycopg2-binary>=2.8.0', 'scikit-learn>=1.0.0', 'torch>=1.9.0']
186
}
187
```
188
189
## Usage Patterns
190
191
### Automatic Extras Generation
192
193
If no `extras_modules` list is provided, Import Tracker will create extras for all discovered modules:
194
195
```python
196
install_requires, extras_require = parse_requirements(
197
requirements="requirements.txt",
198
library_name="mylib"
199
# extras_modules not specified - generates extras for all submodules
200
)
201
```
202
203
### Integration with Lazy Import Errors
204
205
Coordinate setuptools extras with lazy import error handling:
206
207
```python
208
# In your library's __init__.py
209
import import_tracker
210
211
def get_extras_modules():
212
"""Return the same modules used in setup.py extras_require."""
213
return {
214
"mylib.visualization",
215
"mylib.database",
216
"mylib.ml"
217
}
218
219
# Enable lazy imports with extras integration
220
import_tracker.lazy_import_errors(get_extras_modules=get_extras_modules)
221
222
# Now missing extras will show helpful install messages
223
```
224
225
### CI/CD Integration
226
227
Use in continuous integration to validate dependency declarations:
228
229
```python
230
# validate_deps.py
231
from import_tracker.setup_tools import parse_requirements
232
233
# Parse current requirements
234
install_requires, extras_require = parse_requirements(
235
requirements="requirements.txt",
236
library_name="mylib",
237
extras_modules=["mylib.viz", "mylib.db"]
238
)
239
240
# Compare with setup.py declarations
241
import setup
242
assert setup.install_requires == install_requires
243
assert setup.extras_require == extras_require
244
```
245
246
## Implementation Details
247
248
- **Module-to-Package Mapping**: Import Tracker uses pip installation records to map Python module names to package names
249
- **Requirement Standardization**: Package names are normalized (hyphens to underscores) for consistent matching
250
- **Transitive Analysis**: When enabled, distinguishes between direct and transitive dependencies for more accurate classification
251
- **Missing Requirements Handling**: Dependencies in requirements.txt but not found in any module are assumed to be runtime dependencies and added to install_requires