or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dependency-tracking.mdindex.mdlazy-import-errors.mdsetup-tools.md

setup-tools.mddocs/

0

# Setup Tools Integration

1

2

Automatic generation of setuptools configuration from dependency analysis, bridging import tracking with package management by computing install_requires and extras_require.

3

4

## Capabilities

5

6

### Requirements Parsing

7

8

Parses requirements files or lists and generates setuptools-compatible install_requires and extras_require dictionaries based on actual module dependencies.

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

full_depth: bool = True,

16

keep_optional: Union[bool, Dict[str, List[str]]] = False,

17

**kwargs,

18

) -> Tuple[List[str], Dict[str, List[str]]]:

19

"""

20

Parse requirements and generate install_requires and extras_require for setuptools.

21

22

Uses dependency tracking to map each module within the project to its specific

23

dependencies, then allocates requirements between install_requires (common/required)

24

and extras_require (module-specific/optional).

25

26

Args:

27

requirements: The list of requirements entries, or a file path pointing to a

28

requirements file

29

library_name: The top-level name of the library package

30

extras_modules: List of module names that should be used to generate

31

extras_require sets

32

full_depth: Include transitive dependencies of direct third-party dependencies

33

keep_optional: Indicate which optional dependencies should be kept when computing

34

extras sets. If True, all optional dependencies are kept.

35

If False, none are kept. If dict, maps modules to lists of

36

optional dependencies to keep.

37

**kwargs: Additional keyword arguments to pass through to track_module

38

39

Returns:

40

requirements: The list of requirements to pass to setup()

41

extras_require: The extras_require dict to pass to setup()

42

"""

43

```

44

45

### Basic Setup Integration

46

47

Simple integration for generating setuptools configuration:

48

49

```python

50

import setuptools

51

from import_tracker.setup_tools import parse_requirements

52

53

# Parse requirements from file

54

install_requires, extras_require = parse_requirements(

55

requirements='requirements.txt',

56

library_name='my_package'

57

)

58

59

# Use in setup.py

60

setuptools.setup(

61

name='my_package',

62

version='1.0.0',

63

install_requires=install_requires,

64

extras_require=extras_require,

65

packages=setuptools.find_packages(),

66

)

67

```

68

69

### Requirements File Parsing

70

71

Parse dependencies from requirements.txt files:

72

73

```python

74

# requirements.txt content:

75

# requests>=2.25.0

76

# numpy>=1.20.0

77

# matplotlib>=3.0.0 # Optional for plotting

78

# seaborn>=0.11.0 # Optional for advanced plotting

79

80

install_requires, extras_require = parse_requirements(

81

requirements='requirements.txt',

82

library_name='my_package',

83

extras_modules=['my_package.plotting']

84

)

85

86

print(install_requires)

87

# ['requests>=2.25.0', 'numpy>=1.20.0']

88

89

print(extras_require)

90

# {

91

# 'my_package.plotting': ['matplotlib>=3.0.0', 'seaborn>=0.11.0'],

92

# 'all': ['matplotlib>=3.0.0', 'seaborn>=0.11.0']

93

# }

94

```

95

96

### In-Memory Requirements

97

98

Pass requirements as a list instead of a file:

99

100

```python

101

requirements_list = [

102

'requests>=2.25.0',

103

'numpy>=1.20.0',

104

'pandas>=1.3.0',

105

'matplotlib>=3.0.0'

106

]

107

108

install_requires, extras_require = parse_requirements(

109

requirements=requirements_list,

110

library_name='my_package',

111

extras_modules=[

112

'my_package.data_processing',

113

'my_package.visualization'

114

]

115

)

116

```

117

118

### Multiple Extras Groups

119

120

Generate multiple extras_require sets for different feature groups:

121

122

```python

123

install_requires, extras_require = parse_requirements(

124

requirements='requirements.txt',

125

library_name='my_package',

126

extras_modules=[

127

'my_package.web', # Web scraping features

128

'my_package.ml', # Machine learning features

129

'my_package.viz' # Visualization features

130

]

131

)

132

133

print(extras_require)

134

# {

135

# 'my_package.web': ['requests', 'beautifulsoup4'],

136

# 'my_package.ml': ['scikit-learn', 'tensorflow'],

137

# 'my_package.viz': ['matplotlib', 'plotly'],

138

# 'all': ['requests', 'beautifulsoup4', 'scikit-learn', 'tensorflow', 'matplotlib', 'plotly']

139

# }

140

```

141

142

### Optional Dependency Handling

143

144

Control which optional dependencies are included in extras:

145

146

```python

147

# Keep all optional dependencies

148

install_requires, extras_require = parse_requirements(

149

requirements='requirements.txt',

150

library_name='my_package',

151

extras_modules=['my_package.optional_features'],

152

keep_optional=True

153

)

154

155

# Keep no optional dependencies (only required ones)

156

install_requires, extras_require = parse_requirements(

157

requirements='requirements.txt',

158

library_name='my_package',

159

extras_modules=['my_package.optional_features'],

160

keep_optional=False

161

)

162

163

# Keep specific optional dependencies per module

164

install_requires, extras_require = parse_requirements(

165

requirements='requirements.txt',

166

library_name='my_package',

167

extras_modules=['my_package.optional_features'],

168

keep_optional={

169

'my_package.optional_features': ['matplotlib', 'seaborn']

170

}

171

)

172

```

173

174

### Advanced Configuration

175

176

Fine-tune dependency analysis behavior:

177

178

```python

179

install_requires, extras_require = parse_requirements(

180

requirements='requirements.txt',

181

library_name='my_package',

182

extras_modules=['my_package.advanced'],

183

full_depth=True, # Include transitive third-party deps

184

keep_optional=True, # Keep optional dependencies

185

# Pass additional track_module arguments

186

detect_transitive=True, # Distinguish direct vs transitive

187

show_optional=True # Track optional dependency status

188

)

189

```

190

191

## Complete Setup.py Example

192

193

Comprehensive setup.py using import_tracker for dependency management:

194

195

```python

196

"""A setuptools setup module for my_package"""

197

198

import os

199

import setuptools

200

from import_tracker.setup_tools import parse_requirements

201

202

# Read the README to provide the long description

203

base_dir = os.path.abspath(os.path.dirname(__file__))

204

with open(os.path.join(base_dir, "README.md"), "r") as handle:

205

long_description = handle.read()

206

207

# Determine requirements file path

208

requirements_file = os.path.join(base_dir, "requirements.txt")

209

210

# Parse requirement sets using import_tracker

211

install_requires, extras_require = parse_requirements(

212

requirements_file=requirements_file,

213

library_name="my_package",

214

extras_modules=[

215

"my_package.web_scraping",

216

"my_package.data_analysis",

217

"my_package.machine_learning",

218

"my_package.visualization"

219

],

220

full_depth=True,

221

keep_optional=True

222

)

223

224

# Perform the standard setup call

225

setuptools.setup(

226

name="my_package",

227

version="1.0.0",

228

author="Your Name",

229

author_email="your.email@example.com",

230

description="A package with managed dependencies",

231

long_description=long_description,

232

long_description_content_type="text/markdown",

233

url="https://github.com/yourusername/my_package",

234

license="MIT",

235

classifiers=[

236

"Development Status :: 4 - Beta",

237

"Intended Audience :: Developers",

238

"License :: OSI Approved :: MIT License",

239

"Programming Language :: Python :: 3",

240

"Programming Language :: Python :: 3.7",

241

"Programming Language :: Python :: 3.8",

242

"Programming Language :: Python :: 3.9",

243

"Programming Language :: Python :: 3.10",

244

"Programming Language :: Python :: 3.11",

245

],

246

keywords=["dependencies", "packaging", "imports"],

247

packages=setuptools.find_packages(),

248

python_requires=">=3.7",

249

install_requires=install_requires,

250

extras_require=extras_require,

251

entry_points={

252

"console_scripts": [

253

"my-package=my_package.cli:main",

254

],

255

},

256

)

257

```

258

259

## Integration with Lazy Import Errors

260

261

Combine setup tools integration with lazy import error handling:

262

263

```python

264

# In your package's __init__.py

265

from import_tracker import lazy_import_errors

266

from import_tracker.setup_tools import parse_requirements

267

268

# Function to get extras modules for error messages

269

def get_extras_modules():

270

"""Return the set of modules managed as extras"""

271

return {

272

'my_package.web_scraping',

273

'my_package.data_analysis',

274

'my_package.visualization'

275

}

276

277

# Enable lazy errors with extras integration

278

lazy_import_errors(get_extras_modules=get_extras_modules)

279

280

# Import all submodules - won't crash if dependencies missing

281

from . import web_scraping

282

from . import data_analysis

283

from . import visualization

284

```

285

286

When a user tries to use a feature with missing dependencies:

287

288

```python

289

import my_package

290

291

# This will show helpful installation message

292

my_package.visualization.plot_data()

293

# ModuleNotFoundError: No module named 'matplotlib'.

294

# To install the missing dependencies, run `pip install my_package[my_package.visualization]`

295

```

296

297

## Dependency Mapping

298

299

The system automatically maps Python import names to package names:

300

301

```python

302

# Import name -> Package name mapping examples

303

{

304

'requests': 'requests',

305

'numpy': 'numpy',

306

'pandas': 'pandas',

307

'matplotlib': 'matplotlib',

308

'PIL': 'pillow', # Special case mapping

309

'cv2': 'opencv-python', # Special case mapping

310

'sklearn': 'scikit-learn' # Special case mapping

311

}

312

```

313

314

## Return Values

315

316

### install_requires Format

317

318

List of requirement strings compatible with setuptools:

319

320

```python

321

[

322

'requests>=2.25.0',

323

'numpy>=1.20.0',

324

'click>=8.0.0'

325

]

326

```

327

328

### extras_require Format

329

330

Dictionary mapping extras names to requirement lists:

331

332

```python

333

{

334

'my_package.web': ['beautifulsoup4>=4.9.0', 'lxml>=4.6.0'],

335

'my_package.data': ['pandas>=1.3.0', 'openpyxl>=3.0.0'],

336

'my_package.viz': ['matplotlib>=3.4.0', 'seaborn>=0.11.0'],

337

'all': ['beautifulsoup4>=4.9.0', 'lxml>=4.6.0', 'pandas>=1.3.0',

338

'openpyxl>=3.0.0', 'matplotlib>=3.4.0', 'seaborn>=0.11.0']

339

}

340

```

341

342

## Types

343

344

```python { .api }

345

from typing import Dict, List, Optional, Tuple, Union

346

347

# Function parameter types

348

RequirementsInput = Union[List[str], str]

349

LibraryName = str

350

ExtrasModules = Optional[List[str]]

351

KeepOptional = Union[bool, Dict[str, List[str]]]

352

353

# Return types

354

InstallRequires = List[str]

355

ExtrasRequire = Dict[str, List[str]]

356

ParseRequirementsReturn = Tuple[InstallRequires, ExtrasRequire]

357

358

# Requirements mapping types

359

RequirementSpec = str # e.g., 'requests>=2.25.0'

360

PackageName = str # e.g., 'requests'

361

ModuleName = str # e.g., 'my_package.web'

362

```