or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcore-api.mdindex.mdintegration.mdversion-schemes.md

integration.mddocs/

0

# Build System Integration

1

2

setuptools-scm provides seamless integration with setuptools, modern build systems, and packaging tools through entry points, hooks, and configuration. This enables automatic version inference and SCM-managed file inclusion in Python packages.

3

4

```python

5

from pathlib import Path

6

from typing import Any, Sequence

7

from os import PathLike

8

9

# Type Aliases (from setuptools_scm)

10

PathT = PathLike[str] | str

11

```

12

13

## Capabilities

14

15

### File Discovery

16

17

Functions for finding and listing SCM-managed files for inclusion in source distributions.

18

19

```python { .api }

20

def find_files(path: PathT = "") -> list[str]:

21

"""

22

Find SCM-managed files for setuptools integration.

23

24

Parameters:

25

- path: Root path to search for files (default: current directory)

26

27

Returns:

28

List of file paths managed by SCM

29

"""

30

```

31

32

### Version File Generation

33

34

Functions for writing version information to files during build or development.

35

36

```python { .api }

37

def dump_version(

38

root: PathT,

39

version: str,

40

write_to: PathT,

41

template: str | None = None,

42

scm_version: ScmVersion | None = None

43

) -> None:

44

"""

45

Write version information to a file (soft deprecated).

46

47

Parameters:

48

- root: Repository root directory

49

- version: Version string to write

50

- write_to: Path to write version file to

51

- template: Template for version file content (uses default if None)

52

- scm_version: ScmVersion object for additional metadata

53

"""

54

55

def write_version_to_path(

56

target: Path,

57

template: str | None = None,

58

version: str,

59

scm_version: ScmVersion | None = None

60

) -> None:

61

"""

62

Write version to specific path with template.

63

64

Parameters:

65

- target: Target file path

66

- template: Template for file content

67

- version: Version string

68

- scm_version: ScmVersion object for metadata

69

"""

70

```

71

72

### SCM File Finders

73

74

Specialized file finders for different SCM systems, accessible via entry points.

75

76

```python { .api }

77

# Git file finders

78

def git_find_files(path: str) -> list[str]:

79

"""Find files managed by Git"""

80

81

def git_archive_find_files(path: str) -> list[str]:

82

"""Find files from Git archive metadata"""

83

84

# Mercurial file finders

85

def hg_find_files(path: str) -> list[str]:

86

"""Find files managed by Mercurial"""

87

88

def hg_archive_find_files(path: str) -> list[str]:

89

"""Find files from Mercurial archive metadata"""

90

```

91

92

### Setuptools Hooks

93

94

Integration points for setuptools to automatically infer versions and find files.

95

96

```python { .api }

97

def version_keyword(dist, keyword, value):

98

"""Handle use_scm_version keyword in setup.py (legacy)"""

99

100

def infer_version(dist):

101

"""Automatically infer version for setuptools during build"""

102

```

103

104

### Utility Functions

105

106

Helper functions for parsing and processing integration data.

107

108

```python { .api }

109

def data_from_mime(path: str, content: str | None = None) -> dict[str, str]:

110

"""

111

Return mapping from MIME/pseudo-MIME content.

112

113

Parameters:

114

- path: File path

115

- content: File content (reads from path if None)

116

117

Returns:

118

Dictionary mapping parsed from MIME-like content

119

"""

120

```

121

122

## Entry Point System

123

124

setuptools-scm uses Python's entry point system to provide extensible plugin architecture:

125

126

### SCM Parsers

127

128

```python

129

# Entry point group: "setuptools_scm.parse_scm"

130

".git" = "setuptools_scm.git:parse"

131

".hg" = "setuptools_scm.hg:parse"

132

133

# Entry point group: "setuptools_scm.parse_scm_fallback"

134

".git_archival.txt" = "setuptools_scm.git:parse_archival"

135

".hg_archival.txt" = "setuptools_scm.hg:parse_archival"

136

"PKG-INFO" = "setuptools_scm.fallbacks:parse_pkginfo"

137

"pyproject.toml" = "setuptools_scm.fallbacks:fallback_version"

138

"setup.py" = "setuptools_scm.fallbacks:fallback_version"

139

```

140

141

### File Finders

142

143

```python

144

# Entry point group: "setuptools_scm.files_command"

145

".git" = "setuptools_scm._file_finders.git:git_find_files"

146

".hg" = "setuptools_scm._file_finders.hg:hg_find_files"

147

148

# Entry point group: "setuptools_scm.files_command_fallback"

149

".git_archival.txt" = "setuptools_scm._file_finders.git:git_archive_find_files"

150

".hg_archival.txt" = "setuptools_scm._file_finders.hg:hg_archive_find_files"

151

```

152

153

### Setuptools Integration

154

155

```python

156

# Entry point group: "distutils.setup_keywords"

157

"use_scm_version" = "setuptools_scm._integration.setuptools:version_keyword"

158

159

# Entry point group: "setuptools.file_finders"

160

"setuptools_scm" = "setuptools_scm._file_finders:find_files"

161

162

# Entry point group: "setuptools.finalize_distribution_options"

163

"setuptools_scm" = "setuptools_scm._integration.setuptools:infer_version"

164

```

165

166

## Usage Examples

167

168

### pyproject.toml Configuration

169

170

Modern Python packaging with PEP 518/621 support:

171

172

```toml

173

[build-system]

174

requires = ["setuptools>=64", "setuptools-scm>=8"]

175

build-backend = "setuptools.build_meta"

176

177

[project]

178

name = "mypackage"

179

dynamic = ["version"]

180

dependencies = ["requests", "click"]

181

182

[tool.setuptools_scm]

183

version_file = "src/mypackage/_version.py"

184

version_file_template = '''

185

# File generated by setuptools-scm

186

__version__ = "{version}"

187

__version_tuple__ = {version_tuple}

188

'''

189

```

190

191

### Version File Generation

192

193

```python

194

# Configuration with version file

195

from setuptools_scm import get_version

196

197

version = get_version(

198

write_to="src/mypackage/_version.py",

199

write_to_template='''

200

__version__ = "{version}"

201

__version_tuple__ = {version_tuple}

202

'''

203

)

204

205

# The generated file will contain:

206

# __version__ = "1.2.3.dev4+g1234567.d20231201"

207

# __version_tuple__ = ('1', '2', '3', 'dev4', 'g1234567', 'd20231201')

208

```

209

210

### Legacy setup.py Integration

211

212

```python

213

# setup.py (legacy approach)

214

from setuptools import setup

215

216

setup(

217

name="mypackage",

218

use_scm_version=True,

219

setup_requires=["setuptools-scm"],

220

# ... other setup parameters

221

)

222

223

# With custom configuration

224

setup(

225

name="mypackage",

226

use_scm_version={

227

"version_scheme": "python-simplified-semver",

228

"local_scheme": "no-local-version",

229

"write_to": "mypackage/_version.py"

230

},

231

setup_requires=["setuptools-scm"],

232

)

233

```

234

235

### Build Tool Integration

236

237

```bash

238

# Using build (PEP 517)

239

python -m build

240

241

# Using pip

242

pip install -e .

243

244

# Using setuptools directly

245

python setup.py sdist bdist_wheel

246

```

247

248

All these tools automatically pick up setuptools-scm configuration and use it for version determination.

249

250

### File Finder Usage

251

252

```python

253

from setuptools_scm._file_finders import find_files

254

255

# Find all SCM-managed files

256

files = find_files(".")

257

print("SCM-managed files:", files)

258

259

# This is used internally by setuptools to include files in sdist

260

```

261

262

### Custom Entry Points

263

264

You can extend setuptools-scm with custom entry points:

265

266

```toml

267

# In your package's pyproject.toml

268

[project.entry-points."setuptools_scm.version_scheme"]

269

"my-custom-scheme" = "mypackage.scm:my_version_scheme"

270

271

[project.entry-points."setuptools_scm.local_scheme"]

272

"my-local-scheme" = "mypackage.scm:my_local_scheme"

273

274

[project.entry-points."setuptools_scm.parse_scm"]

275

".myvcm" = "mypackage.scm:parse_my_vcm"

276

```

277

278

```python

279

# mypackage/scm.py

280

def my_version_scheme(version):

281

"""Custom version scheme"""

282

return f"custom-{version.tag}"

283

284

def my_local_scheme(version):

285

"""Custom local scheme"""

286

return f"+build{version.distance}" if version.distance else ""

287

288

def parse_my_vcm(root, config):

289

"""Custom VCS parser"""

290

# Implementation for custom version control system

291

pass

292

```

293

294

### CI/CD Integration Examples

295

296

#### GitHub Actions

297

298

```yaml

299

name: Build and Release

300

on: [push, pull_request]

301

302

jobs:

303

build:

304

runs-on: ubuntu-latest

305

steps:

306

- uses: actions/checkout@v3

307

with:

308

fetch-depth: 0 # Required for setuptools-scm

309

310

- name: Set up Python

311

uses: actions/setup-python@v4

312

with:

313

python-version: "3.11"

314

315

- name: Install dependencies

316

run: |

317

pip install build setuptools-scm

318

319

- name: Get version

320

run: |

321

VERSION=$(python -m setuptools_scm)

322

echo "VERSION=$VERSION" >> $GITHUB_ENV

323

echo "Building version: $VERSION"

324

325

- name: Build package

326

run: python -m build

327

```

328

329

#### GitLab CI

330

331

```yaml

332

build:

333

stage: build

334

script:

335

- pip install build setuptools-scm

336

- VERSION=$(python -m setuptools_scm --strip-dev)

337

- echo "Building version $VERSION"

338

- python -m build

339

artifacts:

340

paths:

341

- dist/

342

```

343

344

### Docker Integration

345

346

```dockerfile

347

FROM python:3.11-slim

348

349

# Install git for setuptools-scm

350

RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*

351

352

COPY . /app

353

WORKDIR /app

354

355

# setuptools-scm will automatically determine version

356

RUN pip install -e .

357

358

# Version information available at runtime

359

RUN python -c "import mypackage; print(mypackage.__version__)"

360

```

361

362

### Runtime Version Access

363

364

```python

365

# In your package's __init__.py

366

from importlib.metadata import version, PackageNotFoundError

367

368

try:

369

__version__ = version("mypackage")

370

except PackageNotFoundError:

371

# Development installation

372

from setuptools_scm import get_version

373

__version__ = get_version(root="..")

374

```

375

376

Or with generated version file:

377

378

```python

379

# In your package's __init__.py

380

try:

381

from ._version import __version__

382

except ImportError:

383

# Fallback for development

384

from setuptools_scm import get_version

385

__version__ = get_version(root="..")

386

```

387

388

## Template Formats

389

390

### Python Version File Template

391

392

```python

393

# Default template for .py files

394

TEMPLATE_PY = '''

395

# file generated by setuptools-scm

396

# don't change, don't track in version control

397

398

__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]

399

400

__version__ = version = {version!r}

401

__version_tuple__ = version_tuple = {version_tuple!r}

402

'''

403

```

404

405

### Text File Template

406

407

```python

408

# Default template for .txt files

409

TEMPLATE_TXT = "{version}"

410

```

411

412

### Custom Templates

413

414

```python

415

# Custom template example

416

custom_template = '''

417

"""Version information for {dist_name}"""

418

VERSION = "{version}"

419

BUILD_DATE = "{build_date}"

420

COMMIT = "{node}"

421

DIRTY = {dirty}

422

'''

423

424

version = get_version(

425

write_to="mypackage/_version.py",

426

write_to_template=custom_template

427

)

428

```