or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-backend.mdcommands.mdcore-classes.mdcore-setup.mdexceptions.mdindex.mdpkg-resources.mdutilities.md

core-classes.mddocs/

0

# Core Classes

1

2

Essential setuptools classes that provide the foundation for package building, extension compilation, and command execution. These classes extend distutils functionality with enhanced capabilities for modern Python packaging.

3

4

## Capabilities

5

6

### Distribution Class

7

8

The Distribution class is the enhanced version of distutils.Distribution that handles setuptools-specific metadata and configuration.

9

10

```python { .api }

11

class Distribution:

12

"""

13

Enhanced distribution class that extends distutils.Distribution.

14

15

This class handles package metadata, command execution, and configuration

16

parsing with setuptools-specific enhancements.

17

18

Key Attributes:

19

- metadata: Package metadata

20

- packages: List of packages to include

21

- py_modules: List of Python modules

22

- ext_modules: List of C/C++ extensions

23

- scripts: List of script files

24

- data_files: List of data files

25

- cmdclass: Dictionary of command classes

26

27

Key Methods:

28

"""

29

30

def __init__(self, attrs=None):

31

"""

32

Initialize Distribution with package attributes.

33

34

Parameters:

35

- attrs (dict): Package attributes and metadata

36

"""

37

38

def parse_config_files(self, filenames=None):

39

"""

40

Parse setup.cfg and other configuration files.

41

42

Parameters:

43

- filenames (list): Configuration files to parse

44

45

Returns:

46

None

47

"""

48

49

def get_command_class(self, command):

50

"""

51

Get command class by name.

52

53

Parameters:

54

- command (str): Command name (e.g., 'build', 'install')

55

56

Returns:

57

type: Command class

58

"""

59

60

def get_command_obj(self, command, create=1):

61

"""

62

Get command instance, creating if necessary.

63

64

Parameters:

65

- command (str): Command name

66

- create (int): Whether to create if not exists (default: 1)

67

68

Returns:

69

Command: Command instance

70

"""

71

72

def run_command(self, command):

73

"""

74

Execute a command by name.

75

76

Parameters:

77

- command (str): Command name to run

78

79

Returns:

80

None

81

"""

82

83

def run_commands(self):

84

"""Run all commands in command line order."""

85

86

def get_command_list(self):

87

"""Get list of available commands."""

88

89

def finalize_options(self):

90

"""Finalize and validate all options."""

91

```

92

93

### Command Base Class

94

95

The Command class is the abstract base class for all setuptools commands, providing the interface and common functionality.

96

97

```python { .api }

98

class Command:

99

"""

100

Abstract base class for all setuptools commands.

101

102

All setuptools commands must inherit from this class and implement

103

the three required methods: initialize_options, finalize_options, and run.

104

105

Attributes:

106

- distribution: Reference to Distribution instance

107

- _dry_run: Whether to perform actual operations

108

- verbose: Verbosity level

109

- force: Whether to force operations

110

"""

111

112

def __init__(self, dist):

113

"""

114

Initialize command with distribution reference.

115

116

Parameters:

117

- dist (Distribution): Distribution instance

118

"""

119

120

def initialize_options(self):

121

"""

122

Set default values for all command options.

123

124

This method must be implemented by subclasses to set default

125

values for all options that the command supports.

126

"""

127

128

def finalize_options(self):

129

"""

130

Validate and process command options.

131

132

This method must be implemented by subclasses to validate

133

option values and perform any necessary processing.

134

"""

135

136

def run(self):

137

"""

138

Execute the command.

139

140

This method must be implemented by subclasses to perform

141

the actual command operation.

142

"""

143

144

def announce(self, msg, level=1):

145

"""

146

Announce a message at given verbosity level.

147

148

Parameters:

149

- msg (str): Message to announce

150

- level (int): Verbosity level (default: 1)

151

"""

152

153

def debug_print(self, msg):

154

"""Print debug message if in debug mode."""

155

156

def ensure_dirname(self, option):

157

"""Ensure an option value is a directory name."""

158

159

def ensure_filename(self, option):

160

"""Ensure an option value is a filename."""

161

162

def ensure_string(self, option, default=None):

163

"""Ensure an option value is a string."""

164

165

def ensure_string_list(self, option):

166

"""Ensure an option value is a list of strings."""

167

168

def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1):

169

"""Copy a file with optional preservation of metadata."""

170

171

def copy_tree(self, indir, outdir, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1):

172

"""Copy an entire directory tree."""

173

174

def make_file(self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1):

175

"""Make a file by calling a function if inputs are newer than output."""

176

177

def spawn(self, cmd, search_path=1, level=1):

178

"""Spawn a subprocess command."""

179

180

def mkpath(self, name, mode=0o777):

181

"""Create a directory path."""

182

183

def execute(self, func, args, msg=None, level=1):

184

"""Execute a function with optional message."""

185

```

186

187

### Extension Class

188

189

The Extension class describes C/C++ extension modules to be built.

190

191

```python { .api }

192

class Extension:

193

"""

194

Enhanced C/C++ extension module descriptor.

195

196

Extends distutils.Extension with additional features like Cython support,

197

limited API support, and enhanced configuration options.

198

199

Attributes:

200

- name: Extension module name

201

- sources: List of source files

202

- include_dirs: Include directories

203

- define_macros: Preprocessor macros

204

- undef_macros: Macros to undefine

205

- library_dirs: Library search directories

206

- libraries: Libraries to link against

207

- runtime_library_dirs: Runtime library directories

208

- extra_objects: Additional object files

209

- extra_compile_args: Extra compiler arguments

210

- extra_link_args: Extra linker arguments

211

- export_symbols: Symbols to export (Windows)

212

- swig_opts: SWIG options

213

- depends: Dependency files

214

- language: Programming language ('c' or 'c++')

215

- optional: Whether extension is optional

216

- py_limited_api: Whether to use stable ABI

217

"""

218

219

def __init__(self, name, sources, include_dirs=None, define_macros=None,

220

undef_macros=None, library_dirs=None, libraries=None,

221

runtime_library_dirs=None, extra_objects=None,

222

extra_compile_args=None, extra_link_args=None,

223

export_symbols=None, swig_opts=None, depends=None,

224

language=None, optional=None, py_limited_api=False, **kw):

225

"""

226

Initialize Extension with configuration.

227

228

Parameters:

229

- name (str): Fully qualified extension name (e.g., 'package.module')

230

- sources (list): List of source file paths

231

- include_dirs (list): Directories to search for header files

232

- define_macros (list): Macros to define (list of tuples)

233

- undef_macros (list): Macros to undefine

234

- library_dirs (list): Directories to search for libraries

235

- libraries (list): Libraries to link against

236

- runtime_library_dirs (list): Runtime library search directories

237

- extra_objects (list): Additional object files to link

238

- extra_compile_args (list): Additional compiler arguments

239

- extra_link_args (list): Additional linker arguments

240

- export_symbols (list): Symbols to export on Windows

241

- swig_opts (list): Options for SWIG

242

- depends (list): Files that extension depends on

243

- language (str): Programming language ('c' or 'c++')

244

- optional (bool): Whether extension is optional

245

- py_limited_api (bool): Whether to use Python stable ABI

246

"""

247

```

248

249

### Library Class

250

251

The Library class describes C/C++ libraries to be built (similar to Extension but for libraries).

252

253

```python { .api }

254

class Library:

255

"""

256

C/C++ library descriptor.

257

258

Like Extension but for building libraries instead of extension modules.

259

Libraries are built and can be used by extension modules.

260

261

Attributes: Same as Extension

262

"""

263

264

def __init__(self, name, sources, **kw):

265

"""

266

Initialize Library with configuration.

267

268

Parameters: Same as Extension.__init__

269

"""

270

```

271

272

### Package Discovery Classes

273

274

Classes that provide automatic discovery of Python packages and modules within a project directory structure.

275

276

```python { .api }

277

class PackageFinder:

278

"""

279

Standard package discovery for traditional package layouts.

280

281

Finds regular Python packages (directories with __init__.py files).

282

"""

283

284

@classmethod

285

def find(cls, where='.', exclude=(), include=('*',)):

286

"""

287

Find all packages in the given directory.

288

289

Parameters:

290

- where (str): Root directory to search (default: '.')

291

- exclude (tuple): Glob patterns for packages to exclude

292

- include (tuple): Glob patterns for packages to include (default: ('*',))

293

294

Returns:

295

list[str]: List of discovered package names

296

"""

297

298

class PEP420PackageFinder(PackageFinder):

299

"""

300

Discovery for PEP 420 implicit namespace packages.

301

302

Finds both regular packages and namespace packages (directories without __init__.py).

303

"""

304

305

@classmethod

306

def find(cls, where='.', exclude=(), include=('*',)):

307

"""

308

Find all packages including PEP 420 namespace packages.

309

310

Parameters:

311

- where (str): Root directory to search (default: '.')

312

- exclude (tuple): Glob patterns for packages to exclude

313

- include (tuple): Glob patterns for packages to include (default: ('*',))

314

315

Returns:

316

list[str]: List of discovered package names (including namespace packages)

317

"""

318

319

class ModuleFinder:

320

"""

321

Discovery for standalone Python modules.

322

323

Finds individual .py files that should be included as modules.

324

"""

325

326

@classmethod

327

def find(cls, where='.', exclude=(), include=('*',)):

328

"""

329

Find all Python modules in the given directory.

330

331

Parameters:

332

- where (str): Root directory to search (default: '.')

333

- exclude (tuple): Glob patterns for modules to exclude

334

- include (tuple): Glob patterns for modules to include (default: ('*',))

335

336

Returns:

337

list[str]: List of discovered module names

338

"""

339

340

class FlatLayoutPackageFinder(PEP420PackageFinder):

341

"""

342

Package discovery for flat-layout projects.

343

344

Specialized finder for projects that don't use src-layout but have packages

345

directly under the project root.

346

"""

347

348

class FlatLayoutModuleFinder(ModuleFinder):

349

"""

350

Module discovery for flat-layout projects.

351

352

Specialized finder for discovering standalone modules in flat-layout projects.

353

"""

354

355

class ConfigDiscovery:

356

"""

357

Automatic configuration discovery for setuptools.

358

359

Provides automatic discovery of package configuration including packages,

360

modules, entry points, and other metadata from project structure.

361

"""

362

363

def __init__(self, distribution=None):

364

"""

365

Initialize configuration discovery.

366

367

Parameters:

368

- distribution (Distribution, optional): Distribution instance

369

"""

370

371

def __call__(self, dist=None):

372

"""

373

Perform automatic discovery and apply to distribution.

374

375

Parameters:

376

- dist (Distribution, optional): Distribution to configure

377

378

Returns:

379

dict: Discovered configuration

380

"""

381

```

382

383

## Usage Examples

384

385

### Custom Command Class

386

387

```python

388

from setuptools import setup, Command

389

import subprocess

390

391

class CustomCommand(Command):

392

"""Custom command example."""

393

394

description = 'Run custom command'

395

user_options = [

396

('option=', 'o', 'Custom option'),

397

]

398

399

def initialize_options(self):

400

"""Set default option values."""

401

self.option = None

402

403

def finalize_options(self):

404

"""Validate and process options."""

405

if self.option is None:

406

self.option = 'default_value'

407

408

def run(self):

409

"""Execute the custom command."""

410

self.announce(f'Running custom command with option: {self.option}')

411

# Custom command logic here

412

subprocess.run(['echo', f'Custom option: {self.option}'])

413

414

setup(

415

name='my-package',

416

cmdclass={

417

'custom': CustomCommand,

418

},

419

)

420

```

421

422

### C Extension with Cython

423

424

```python

425

from setuptools import setup, Extension

426

from Cython.Build import cythonize

427

428

extensions = [

429

Extension(

430

'my_package.fast_module',

431

sources=['src/fast_module.pyx'], # Cython source

432

include_dirs=['src/include'],

433

libraries=['m'],

434

extra_compile_args=['-O3'],

435

language='c++',

436

py_limited_api=True, # Use stable ABI

437

)

438

]

439

440

setup(

441

name='my-package',

442

ext_modules=cythonize(extensions),

443

)

444

```

445

446

### Complex Extension Configuration

447

448

```python

449

from setuptools import setup, Extension

450

import numpy

451

452

ext_modules = [

453

Extension(

454

'my_package.numerical',

455

sources=[

456

'src/numerical.c',

457

'src/utils.c',

458

],

459

include_dirs=[

460

'src/include',

461

numpy.get_include(), # NumPy headers

462

],

463

library_dirs=['/usr/local/lib'],

464

libraries=['blas', 'lapack'],

465

define_macros=[

466

('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'),

467

('VERSION', '"1.0.0"'),

468

],

469

extra_compile_args=['-O3', '-fopenmp'],

470

extra_link_args=['-fopenmp'],

471

depends=['src/numerical.h', 'src/utils.h'],

472

optional=False, # Required extension

473

)

474

]

475

476

setup(

477

name='numerical-package',

478

ext_modules=ext_modules,

479

zip_safe=False,

480

)

481

```

482

483

### Distribution Subclass

484

485

```python

486

from setuptools import setup

487

from setuptools.dist import Distribution

488

489

class CustomDistribution(Distribution):

490

"""Custom distribution class."""

491

492

def __init__(self, attrs=None):

493

# Custom initialization

494

super().__init__(attrs)

495

# Add custom behavior

496

497

def run_commands(self):

498

"""Override command execution."""

499

self.announce('Running custom distribution')

500

super().run_commands()

501

502

setup(

503

name='my-package',

504

distclass=CustomDistribution,

505

)

506

```

507

508

### Library Building

509

510

```python

511

from setuptools import setup

512

from setuptools.extension import Library, Extension

513

514

libraries = [

515

Library(

516

'myutils',

517

sources=['src/utils.c', 'src/helpers.c'],

518

include_dirs=['src/include'],

519

)

520

]

521

522

extensions = [

523

Extension(

524

'my_package.core',

525

sources=['src/core.c'],

526

libraries=['myutils'], # Link against our library

527

library_dirs=['.'],

528

)

529

]

530

531

setup(

532

name='my-package',

533

libraries=libraries,

534

ext_modules=extensions,

535

)

536

```