or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

architecture.mdbuild-selection.mdci-integration.mdcli.mdconfiguration.mdenvironment.mderrors.mdindex.mdplatforms.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Cibuildwheel provides various utility functions for string formatting, command preparation, version parsing, and other common operations.

3

4

## Capabilities

5

6

### String Formatting

7

8

Safe string formatting with path support.

9

10

```python { .api }

11

def format_safe(template: str, **kwargs: str | os.PathLike[str]) -> str:

12

"""

13

Safely format a template string with keyword arguments.

14

15

Args:

16

template: Template string with {key} placeholders

17

**kwargs: Keyword arguments for substitution

18

19

Returns:

20

Formatted string with substitutions applied

21

22

Raises:

23

KeyError: If template contains undefined placeholders

24

"""

25

```

26

27

### Command Preparation

28

29

Prepare shell commands with safe argument substitution.

30

31

```python { .api }

32

def prepare_command(command: str, **kwargs: PathOrStr) -> str:

33

"""

34

Prepare a shell command with safe argument substitution.

35

36

Args:

37

command: Command template with {key} placeholders

38

**kwargs: Arguments for substitution (strings or paths)

39

40

Returns:

41

Command string with arguments safely substituted

42

"""

43

```

44

45

### Boolean Conversion

46

47

Convert string values to boolean with flexible input support.

48

49

```python { .api }

50

def strtobool(val: str) -> bool:

51

"""

52

Convert string representation of truth to boolean.

53

54

Args:

55

val: String value to convert

56

57

Returns:

58

Boolean representation of the input

59

60

Raises:

61

ValueError: If string is not a recognized boolean value

62

63

Accepts: 'y', 'yes', 't', 'true', 'on', '1' (case-insensitive) for True

64

'n', 'no', 'f', 'false', 'off', '0' (case-insensitive) for False

65

"""

66

```

67

68

### Text Unwrapping

69

70

Utilities for unwrapping and reformatting text.

71

72

```python { .api }

73

def unwrap(text: str) -> str:

74

"""

75

Unwrap text by removing line breaks within paragraphs.

76

77

Args:

78

text: Input text with possible line breaks

79

80

Returns:

81

Text with line breaks removed within paragraphs

82

"""

83

84

def unwrap_preserving_paragraphs(text: str) -> str:

85

"""

86

Unwrap text while preserving paragraph breaks.

87

88

Args:

89

text: Input text with paragraphs separated by blank lines

90

91

Returns:

92

Text with line breaks removed within paragraphs but paragraph breaks preserved

93

"""

94

```

95

96

### Key-Value Parsing

97

98

Parse configuration strings containing key-value pairs.

99

100

```python { .api }

101

def parse_key_value_string(

102

key_value_string: str,

103

positional_arg_names: Sequence[str] | None = None,

104

kw_arg_names: Sequence[str] | None = None,

105

) -> dict[str, list[str]]:

106

"""

107

Parse a string containing key-value pairs and positional arguments.

108

109

Args:

110

key_value_string: String to parse (e.g., "pos1 pos2 key1=val1 key2=val2")

111

positional_arg_names: Names for positional arguments

112

kw_arg_names: Valid keyword argument names

113

114

Returns:

115

Dictionary mapping argument names to lists of values

116

117

Raises:

118

ValueError: If parsing fails or invalid arguments provided

119

"""

120

```

121

122

### Version Handling

123

124

Flexible version comparison and parsing.

125

126

```python { .api }

127

@dataclasses.dataclass(order=True)

128

class FlexibleVersion:

129

"""

130

Version class that handles various version formats flexibly.

131

132

Supports:

133

- Semantic versioning (1.2.3)

134

- Python version format (3.11.0)

135

- Pre-release versions (1.0.0a1, 1.0.0rc1)

136

- Development versions (1.0.0.dev0)

137

- Epoch versions (1!1.0.0)

138

"""

139

140

def __init__(self, version: str) -> None:

141

"""

142

Initialize from version string.

143

144

Args:

145

version: Version string to parse

146

"""

147

148

def __str__(self) -> str:

149

"""Return string representation of version."""

150

151

def __eq__(self, other: object) -> bool:

152

"""Check version equality."""

153

154

def __lt__(self, other: FlexibleVersion) -> bool:

155

"""Compare versions for ordering."""

156

```

157

158

## Usage Examples

159

160

### String Formatting

161

162

```python

163

from cibuildwheel.util.helpers import format_safe

164

165

# Basic formatting

166

template = "Building {package} version {version}"

167

result = format_safe(template, package="my-package", version="1.0.0")

168

# Result: "Building my-package version 1.0.0"

169

170

# Path formatting

171

template = "Output to {output_dir}/wheels"

172

result = format_safe(template, output_dir=Path("/tmp/build"))

173

# Result: "Output to /tmp/build/wheels"

174

```

175

176

### Command Preparation

177

178

```python

179

from cibuildwheel.util.helpers import prepare_command

180

from pathlib import Path

181

182

# Prepare test command

183

command = "pytest {project}/tests --output={output}"

184

prepared = prepare_command(

185

command,

186

project=Path("/src/mypackage"),

187

output=Path("/tmp/test-results.xml")

188

)

189

# Result: "pytest /src/mypackage/tests --output=/tmp/test-results.xml"

190

191

# Command with shell escaping

192

command = "echo {message}"

193

prepared = prepare_command(command, message="Hello World with spaces")

194

# Result: "echo 'Hello World with spaces'"

195

```

196

197

### Boolean Conversion

198

199

```python

200

from cibuildwheel.util.helpers import strtobool

201

202

# Convert various string representations

203

strtobool("yes") # True

204

strtobool("true") # True

205

strtobool("1") # True

206

strtobool("on") # True

207

208

strtobool("no") # False

209

strtobool("false") # False

210

strtobool("0") # False

211

strtobool("off") # False

212

213

# Case insensitive

214

strtobool("TRUE") # True

215

strtobool("False") # False

216

217

# Error on invalid input

218

try:

219

strtobool("maybe") # ValueError

220

except ValueError:

221

pass

222

```

223

224

### Text Unwrapping

225

226

```python

227

from cibuildwheel.util.helpers import unwrap, unwrap_preserving_paragraphs

228

229

# Simple unwrapping

230

text = """This is a long line

231

that was wrapped

232

for display."""

233

234

unwrapped = unwrap(text)

235

# Result: "This is a long line that was wrapped for display."

236

237

# Preserving paragraphs

238

text = """First paragraph

239

with wrapped lines.

240

241

Second paragraph

242

also wrapped."""

243

244

unwrapped = unwrap_preserving_paragraphs(text)

245

# Result: "First paragraph with wrapped lines.\n\nSecond paragraph also wrapped."

246

```

247

248

### Key-Value Parsing

249

250

```python

251

from cibuildwheel.util.helpers import parse_key_value_string

252

253

# Parse mixed positional and keyword arguments

254

config = "arg1 arg2 key1=value1 key2=value2"

255

parsed = parse_key_value_string(

256

config,

257

positional_arg_names=["first", "second"],

258

kw_arg_names=["key1", "key2", "key3"]

259

)

260

# Result: {

261

# "first": ["arg1"],

262

# "second": ["arg2"],

263

# "key1": ["value1"],

264

# "key2": ["value2"]

265

# }

266

267

# Multiple values for same key

268

config = "key1=val1 key1=val2 key2=single"

269

parsed = parse_key_value_string(config)

270

# Result: {

271

# "key1": ["val1", "val2"],

272

# "key2": ["single"]

273

# }

274

```

275

276

### Version Comparison

277

278

```python

279

from cibuildwheel.util.helpers import FlexibleVersion

280

281

# Create version objects

282

v1 = FlexibleVersion("1.2.3")

283

v2 = FlexibleVersion("1.2.4")

284

v3 = FlexibleVersion("1.2.3a1")

285

v4 = FlexibleVersion("2.0.0")

286

287

# Comparison operations

288

print(v1 < v2) # True

289

print(v1 > v3) # True (release > prerelease)

290

print(v2 < v4) # True

291

292

# Sorting versions

293

versions = [v4, v1, v3, v2]

294

sorted_versions = sorted(versions)

295

# Result: [v3, v1, v2, v4] (1.2.3a1, 1.2.3, 1.2.4, 2.0.0)

296

297

# String representation

298

print(str(v1)) # "1.2.3"

299

print(str(v3)) # "1.2.3a1"

300

```

301

302

## Advanced Usage

303

304

### Template Systems

305

306

```python

307

from cibuildwheel.util.helpers import format_safe

308

309

# Build complex command templates

310

template = """

311

cd {project_dir} && \

312

python -m pip install {build_deps} && \

313

python -m build --outdir {wheel_dir}

314

"""

315

316

command = format_safe(

317

template,

318

project_dir="/src/mypackage",

319

build_deps="wheel setuptools",

320

wheel_dir="/tmp/wheels"

321

).strip()

322

```

323

324

### Configuration Parsing

325

326

```python

327

from cibuildwheel.util.helpers import parse_key_value_string

328

329

# Parse build frontend configuration

330

frontend_config = "build --installer uv --outdir {wheel_dir}"

331

parsed = parse_key_value_string(

332

frontend_config,

333

positional_arg_names=["tool"],

334

kw_arg_names=["installer", "outdir"]

335

)

336

337

tool = parsed["tool"][0] # "build"

338

installer = parsed.get("installer", ["pip"])[0] # "uv"

339

outdir = parsed.get("outdir", ["{wheel_dir}"])[0] # "{wheel_dir}"

340

```

341

342

### Version Range Checking

343

344

```python

345

from cibuildwheel.util.helpers import FlexibleVersion

346

347

def check_python_compatibility(python_version: str, min_version: str = "3.8"):

348

"""Check if Python version meets minimum requirement."""

349

current = FlexibleVersion(python_version)

350

minimum = FlexibleVersion(min_version)

351

return current >= minimum

352

353

# Usage

354

check_python_compatibility("3.11.0", "3.8") # True

355

check_python_compatibility("3.7.0", "3.8") # False

356

```

357

358

### Environment Variable Processing

359

360

```python

361

from cibuildwheel.util.helpers import strtobool

362

import os

363

364

def get_bool_env(var_name: str, default: bool = False) -> bool:

365

"""Get boolean environment variable with default."""

366

value = os.environ.get(var_name)

367

if value is None:

368

return default

369

return strtobool(value)

370

371

# Usage

372

debug_enabled = get_bool_env("CIBW_DEBUG", False)

373

skip_tests = get_bool_env("CIBW_SKIP_TESTS", False)

374

```

375

376

### Text Processing Pipelines

377

378

```python

379

from cibuildwheel.util.helpers import unwrap_preserving_paragraphs

380

381

def process_multiline_config(config_text: str) -> str:

382

"""Process multiline configuration text."""

383

# Remove extra whitespace and unwrap lines

384

processed = unwrap_preserving_paragraphs(config_text.strip())

385

386

# Additional processing

387

lines = processed.split('\n')

388

cleaned_lines = [line.strip() for line in lines if line.strip()]

389

390

return '\n'.join(cleaned_lines)

391

392

# Usage with configuration files

393

config = """

394

build = cp39-* cp310-*

395

cp311-*

396

397

skip = *-win32

398

*-linux_i686

399

"""

400

401

processed = process_multiline_config(config)

402

# Result: "build = cp39-* cp310-* cp311-*\n\nskip = *-win32 *-linux_i686"

403

```

404

405

## Integration with Cibuildwheel

406

407

These utilities are used throughout cibuildwheel for:

408

409

- **Configuration processing**: Parsing TOML and environment variables

410

- **Command generation**: Creating shell commands for builds and tests

411

- **Version handling**: Comparing Python versions and package versions

412

- **Text formatting**: Processing help text and error messages

413

- **Path handling**: Working with file paths across platforms

414

415

The utilities provide a consistent interface for common operations while handling edge cases and platform differences internally.