0
# Configuration System
1
2
Comprehensive configuration management system supporting pyproject.toml files, command-line overrides, and environment markers for flexible project setup. The system provides type-safe configuration with validation and help generation.
3
4
## Capabilities
5
6
### Configuration Options
7
8
The Option class defines individual configuration parameters with type safety and validation.
9
10
```python { .api }
11
class Option:
12
"""Defines configuration options for Configurable objects."""
13
14
def __init__(self, name, option_type=str, default=None, choices=None, help=None, metavar=None, tools=None):
15
"""
16
Create a configuration option.
17
18
Args:
19
name (str): Option name (used for command-line and config file)
20
option_type (type, optional): Option type (str, int, bool, list, float). Defaults to str.
21
default: Default value for the option
22
choices (list, optional): Valid choices for the option (for validation)
23
help (str, optional): Help text displayed in --help
24
metavar (str, optional): Metavar for help display (overrides default)
25
tools (list, optional): List of tools this option applies to
26
"""
27
pass
28
29
def validate(self, value):
30
"""
31
Validate option value against type and choices.
32
33
Args:
34
value: Value to validate
35
36
Returns:
37
Converted value of correct type
38
39
Raises:
40
UserException: If validation fails
41
"""
42
pass
43
```
44
45
### Configurable Base Class
46
47
The Configurable class provides the foundation for all configurable SIP components.
48
49
```python { .api }
50
class Configurable:
51
"""Base class for configurable objects with command-line option support."""
52
53
def add_options(self, parser):
54
"""
55
Add options to argument parser.
56
57
Args:
58
parser: ArgumentParser instance to add options to
59
"""
60
pass
61
62
def apply_options(self, options):
63
"""
64
Apply parsed options to configuration.
65
66
Args:
67
options: Parsed options namespace
68
"""
69
pass
70
71
def get_options(self):
72
"""
73
Get all available options.
74
75
Returns:
76
list: List of Option objects
77
"""
78
pass
79
```
80
81
### PyProject Configuration
82
83
The PyProject class handles pyproject.toml file parsing and management.
84
85
```python { .api }
86
class PyProject:
87
"""Parses and manages pyproject.toml configuration."""
88
89
def __init__(self, project_file='pyproject.toml'):
90
"""
91
Initialize PyProject configuration.
92
93
Args:
94
project_file (str): Path to pyproject.toml file
95
"""
96
pass
97
98
def get_bindings_configuration(self, name):
99
"""
100
Get bindings configuration by name.
101
102
Args:
103
name (str): Bindings name
104
105
Returns:
106
dict: Bindings configuration
107
"""
108
pass
109
110
def get_dunder_init(self):
111
"""
112
Get __init__.py configuration.
113
114
Returns:
115
dict: __init__.py configuration
116
"""
117
pass
118
```
119
120
### Project Configuration Options
121
122
The Project class supports 37+ configuration options covering all aspects of build configuration.
123
124
#### Build Configuration
125
126
```python { .api }
127
# Build directories and paths
128
build_dir: str # Build directory path (default: 'build')
129
build_settings: dict # Platform-specific build settings
130
target_dir: str # Installation target directory
131
132
# Build behavior
133
distinfo: bool # Create .dist-info directories
134
verbose: bool # Enable verbose output
135
quiet: bool # Suppress output messages
136
build_tag: str # Build tag for wheel names
137
```
138
139
#### Python Environment Configuration
140
141
```python { .api }
142
# Python version targeting
143
py_debug: bool # Build for debug Python
144
py_include_dir: str # Python header files directory
145
py_platform: str # Target Python platform
146
py_major_version: int # Target Python major version
147
py_minor_version: int # Target Python minor version
148
minimum_glibc_version: str # Minimum GLIBC version for wheels
149
minimum_macos_version: str # Minimum macOS version for wheels
150
```
151
152
#### SIP Module Configuration
153
154
```python { .api }
155
# SIP module settings
156
abi_version: str # SIP ABI version (e.g., '12.8')
157
sip_module: str # Fully qualified SIP module name
158
sip_files_dir: str # Directory containing .sip files
159
sip_include_dirs: list # Additional .sip file search paths
160
```
161
162
#### Factory Pattern Configuration
163
164
```python { .api }
165
# Custom factories
166
bindings_factory: str # Custom bindings factory callable
167
builder_factory: str # Custom builder factory callable
168
project_factory: str # Custom project factory callable
169
```
170
171
#### Entry Points and Scripts
172
173
```python { .api }
174
# Script generation
175
console_scripts: list # Console script entry points
176
gui_scripts: list # GUI script entry points
177
dunder_init: bool # Install __init__.py files
178
```
179
180
#### Distribution Configuration
181
182
```python { .api }
183
# Source distributions
184
sdist_excludes: list # Files to exclude from sdist
185
186
# Wheel distributions
187
wheel_includes: list # Files to include in wheels
188
manylinux: bool # Use manylinux platform tags
189
190
# API files
191
api_dir: str # Generate QScintilla .api files
192
```
193
194
#### Additional Options
195
196
```python { .api }
197
# Metadata and documentation
198
metadata: dict # PEP 566 metadata overrides
199
documentation_dir: str # Documentation directory
200
license_dir: str # License files directory
201
202
# Advanced settings
203
jobs: int # Number of parallel build jobs
204
link_full_dll: bool # Link full DLL on Windows
205
no_docstrings: bool # Disable docstring generation
206
protected_is_public: bool # Treat protected as public
207
pyi_extract_dir: str # Type stub extraction directory
208
```
209
210
### Bindings Configuration Options
211
212
The Bindings class supports 18+ configuration options for code generation.
213
214
#### Core Configuration
215
216
```python { .api }
217
# Primary bindings settings
218
sip_file: str # Main .sip specification file
219
sip_files: list # Alternative: list of .sip files
220
internal: bool # Mark bindings as internal only
221
static: bool # Build as static library
222
```
223
224
#### Code Generation Options
225
226
```python { .api }
227
# Code generation behavior
228
exceptions: bool # Enable C++ exception support
229
docstrings: bool # Generate Python docstrings
230
release_gil: bool # Always release Python GIL
231
generate_extracts: bool # Generate extract files for .sip
232
source_suffix: str # Generated source file suffix (.cpp/.c)
233
```
234
235
#### Compilation Configuration
236
237
```python { .api }
238
# Compilation settings
239
include_dirs: list # C/C++ include directories
240
define_macros: list # Preprocessor macro definitions
241
extra_compile_args: list # Additional compiler arguments
242
extra_link_args: list # Additional linker arguments
243
extra_objects: list # Additional object files to link
244
```
245
246
#### Library Configuration
247
248
```python { .api }
249
# Library linking
250
libraries: list # Libraries to link against
251
library_dirs: list # Library search directories
252
```
253
254
#### Source Files
255
256
```python { .api }
257
# Additional sources
258
headers: list # Additional header files
259
sources: list # Additional C/C++ source files
260
```
261
262
#### Feature Control
263
264
```python { .api }
265
# Feature tags and settings
266
tags: list # Feature tags to enable
267
disabled_features: list # Feature tags to disable explicitly
268
```
269
270
#### Builder Integration
271
272
```python { .api }
273
# Builder-specific settings
274
builder_settings: dict # Platform/builder-specific configuration
275
```
276
277
## Usage Examples
278
279
### Basic Configuration
280
281
```python
282
from sipbuild import Project, Option
283
284
# Create project with default configuration
285
project = Project()
286
287
# Configure through code
288
project.build_dir = './build'
289
project.verbose = True
290
291
# Build with configuration
292
project.build()
293
```
294
295
### Custom Options
296
297
```python
298
from sipbuild import Configurable, Option
299
300
class CustomConfigurable(Configurable):
301
def __init__(self):
302
super().__init__()
303
304
# Add custom options
305
self.custom_option = Option(
306
'custom-flag',
307
bool,
308
default=False,
309
help='Enable custom functionality'
310
)
311
312
self.output_format = Option(
313
'output-format',
314
str,
315
default='default',
316
choices=['default', 'compact', 'verbose'],
317
help='Output format selection'
318
)
319
```
320
321
### PyProject Integration
322
323
**Complete pyproject.toml example:**
324
```toml
325
[build-system]
326
requires = ["sip"]
327
build-backend = "sipbuild.api"
328
329
[project]
330
name = "mypackage"
331
version = "1.0.0"
332
description = "Python bindings for MyLib"
333
334
[tool.sip.project]
335
# Build configuration
336
build-dir = "build"
337
verbose = true
338
abi-version = "12.8"
339
340
# Python targeting
341
minimum-macos-version = "10.14"
342
minimum-glibc-version = "2.17"
343
344
# Distribution
345
wheel-includes = ["LICENSE", "README.md"]
346
api-dir = "api"
347
348
# Custom factories (optional)
349
project-factory = "mypackage.build:CustomProject"
350
builder-factory = "mypackage.build:CustomBuilder"
351
352
[tool.sip.bindings.mymodule]
353
sip-file = "mymodule.sip"
354
include-dirs = ["/usr/include/mylib"]
355
libraries = ["mylib"]
356
library-dirs = ["/usr/lib"]
357
exceptions = true
358
docstrings = true
359
release-gil = true
360
define-macros = [["MY_FEATURE", "1"]]
361
tags = ["FEATURE_X", "FEATURE_Y"]
362
```
363
364
**Python usage:**
365
```python
366
from sipbuild import PyProject, Project
367
368
# Load configuration from pyproject.toml
369
pyproject = PyProject()
370
project = Project()
371
372
# Apply configuration
373
bindings_config = pyproject.get_bindings_configuration('mymodule')
374
project.apply_bindings_configuration(bindings_config)
375
```
376
377
### Factory Pattern Usage
378
379
**Custom project factory:**
380
```python
381
# mypackage/build.py
382
from sipbuild import Project, AbstractBuilder
383
384
class CustomProject(Project):
385
def setup(self):
386
super().setup()
387
print("Setting up custom project configuration")
388
389
# Custom initialization logic
390
self.custom_setting = True
391
392
def build(self):
393
print("Building with custom logic")
394
super().build()
395
396
class CustomBuilder(AbstractBuilder):
397
def build(self):
398
print("Using custom build process")
399
# Custom build logic here
400
super().build()
401
```
402
403
### Command-Line Integration
404
405
```python
406
import argparse
407
from sipbuild import Project
408
409
# Create argument parser
410
parser = argparse.ArgumentParser()
411
412
# Add project options
413
project = Project()
414
project.add_options(parser)
415
416
# Parse arguments
417
args = parser.parse_args()
418
419
# Apply to project
420
project.apply_options(args)
421
422
# Build with applied configuration
423
project.build()
424
```
425
426
## Configuration Validation
427
428
### Type Validation
429
430
All configuration options are validated against their declared types:
431
432
```python
433
from sipbuild import Option, UserException
434
435
try:
436
option = Option('count', int, default=0)
437
option.validate('invalid') # Raises UserException
438
except UserException as e:
439
print(f"Validation error: {e}")
440
```
441
442
### Choice Validation
443
444
Options with restricted choices are validated:
445
446
```python
447
format_option = Option(
448
'format',
449
str,
450
choices=['json', 'xml', 'yaml'],
451
default='json'
452
)
453
454
# This would raise UserException
455
# format_option.validate('invalid_format')
456
```
457
458
### Environment Markers
459
460
Configuration options support environment markers for conditional application:
461
462
```python
463
# Only apply on Windows
464
windows_option = Option(
465
'windows-specific',
466
bool,
467
environment_marker='sys_platform == "win32"'
468
)
469
```
470
471
## Error Handling
472
473
Configuration errors are handled through specific exceptions:
474
475
```python { .api }
476
class PyProjectOptionException(Exception):
477
"""Configuration option errors."""
478
pass
479
480
class PyProjectUndefinedOptionException(Exception):
481
"""Missing required options."""
482
pass
483
```
484
485
These exceptions provide detailed error messages including:
486
- Option name and expected type
487
- Valid choices (if applicable)
488
- Location in configuration file
489
- Suggestions for correction