or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-pyproject-hooks

A low-level library for calling build-backends in pyproject.toml-based project

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/pyproject-hooks@1.2.x

To install, run

npx @tessl/cli install tessl/pypi-pyproject-hooks@1.2.0

0

# pyproject-hooks

1

2

A low-level library for calling build-backends in pyproject.toml-based Python projects. This library provides the basic functionality to help write tooling that generates distribution files from Python projects, serving as the underlying piece for build frontends like pip, build, and other tools.

3

4

## Package Information

5

6

- **Package Name**: pyproject-hooks

7

- **Language**: Python

8

- **Installation**: `pip install pyproject-hooks`

9

- **Python Version**: >=3.7

10

11

## Core Imports

12

13

```python

14

from pyproject_hooks import BuildBackendHookCaller

15

```

16

17

For exception handling:

18

19

```python

20

from pyproject_hooks import (

21

BackendUnavailable,

22

HookMissing,

23

UnsupportedOperation

24

)

25

```

26

27

For subprocess runners:

28

29

```python

30

from pyproject_hooks import (

31

default_subprocess_runner,

32

quiet_subprocess_runner

33

)

34

```

35

36

## Basic Usage

37

38

```python

39

from pyproject_hooks import BuildBackendHookCaller

40

import tempfile

41

42

# Initialize the hook caller for a project

43

hook_caller = BuildBackendHookCaller(

44

source_dir="/path/to/project",

45

build_backend="setuptools.build_meta"

46

)

47

48

# Get wheel build dependencies

49

wheel_deps = hook_caller.get_requires_for_build_wheel()

50

print(f"Wheel dependencies: {wheel_deps}")

51

52

# Build a wheel

53

with tempfile.TemporaryDirectory() as temp_dir:

54

wheel_filename = hook_caller.build_wheel(temp_dir)

55

print(f"Built wheel: {wheel_filename}")

56

```

57

58

## Architecture

59

60

The library provides a subprocess-based isolation mechanism for calling build backends:

61

62

- **BuildBackendHookCaller**: Main class that manages backend communication

63

- **Subprocess Execution**: Isolates backend calls in subprocess to avoid import conflicts

64

- **Hook Protocol**: Implements PEP 517/518 build backend interface

65

- **Exception Handling**: Comprehensive error handling for backend failures

66

67

## Capabilities

68

69

### Build Backend Hook Caller

70

71

Main class for interfacing with build backends. Manages source directory, backend specification, and subprocess execution.

72

73

```python { .api }

74

class BuildBackendHookCaller:

75

def __init__(

76

self,

77

source_dir: str,

78

build_backend: str,

79

backend_path: Optional[Sequence[str]] = None,

80

runner: Optional[SubprocessRunner] = None,

81

python_executable: Optional[str] = None,

82

) -> None:

83

"""

84

Initialize the hook caller.

85

86

Parameters:

87

- source_dir: The source directory to invoke the build backend for

88

- build_backend: The build backend spec (e.g., "setuptools.build_meta")

89

- backend_path: Additional path entries for the build backend spec

90

- runner: The subprocess runner to use (defaults to default_subprocess_runner)

91

- python_executable: The Python executable used to invoke the build backend

92

"""

93

```

94

95

### Subprocess Runner Context Manager

96

97

Temporarily override the default subprocess runner for specific operations.

98

99

```python { .api }

100

def subprocess_runner(self, runner: SubprocessRunner) -> Iterator[None]:

101

"""

102

Context manager for temporarily overriding subprocess runner.

103

104

Parameters:

105

- runner: The new subprocess runner to use within the context

106

"""

107

```

108

109

### Wheel Build Operations

110

111

Operations for building wheels and managing wheel metadata.

112

113

```python { .api }

114

def get_requires_for_build_wheel(

115

self,

116

config_settings: Optional[Mapping[str, Any]] = None,

117

) -> Sequence[str]:

118

"""

119

Get additional dependencies required for building a wheel.

120

121

Parameters:

122

- config_settings: The configuration settings for the build backend

123

124

Returns:

125

A list of PEP 508 dependency specifiers.

126

127

Note: Returns empty list if backend doesn't define this hook.

128

"""

129

130

def prepare_metadata_for_build_wheel(

131

self,

132

metadata_directory: str,

133

config_settings: Optional[Mapping[str, Any]] = None,

134

_allow_fallback: bool = True,

135

) -> str:

136

"""

137

Prepare a *.dist-info folder with metadata for this project.

138

139

Parameters:

140

- metadata_directory: The directory to write the metadata to

141

- config_settings: The configuration settings for the build backend

142

- _allow_fallback: Whether to allow fallback to building wheel and extracting metadata

143

144

Returns:

145

Name of the newly created subfolder within metadata_directory containing the metadata.

146

147

Note: May fall back to building wheel and extracting metadata if hook not defined.

148

"""

149

150

def build_wheel(

151

self,

152

wheel_directory: str,

153

config_settings: Optional[Mapping[str, Any]] = None,

154

metadata_directory: Optional[str] = None,

155

) -> str:

156

"""

157

Build a wheel from this project.

158

159

Parameters:

160

- wheel_directory: The directory to write the wheel to

161

- config_settings: The configuration settings for the build backend

162

- metadata_directory: The directory to reuse existing metadata from

163

164

Returns:

165

The name of the newly created wheel within wheel_directory.

166

"""

167

```

168

169

### Editable Wheel Operations

170

171

Operations for building editable wheels, supporting PEP 660 editable installs.

172

173

```python { .api }

174

def get_requires_for_build_editable(

175

self,

176

config_settings: Optional[Mapping[str, Any]] = None,

177

) -> Sequence[str]:

178

"""

179

Get additional dependencies required for building an editable wheel.

180

181

Parameters:

182

- config_settings: The configuration settings for the build backend

183

184

Returns:

185

A list of PEP 508 dependency specifiers.

186

187

Note: Returns empty list if backend doesn't define this hook.

188

"""

189

190

def prepare_metadata_for_build_editable(

191

self,

192

metadata_directory: str,

193

config_settings: Optional[Mapping[str, Any]] = None,

194

_allow_fallback: bool = True,

195

) -> Optional[str]:

196

"""

197

Prepare a *.dist-info folder with metadata for editable installation.

198

199

Parameters:

200

- metadata_directory: The directory to write the metadata to

201

- config_settings: The configuration settings for the build backend

202

- _allow_fallback: Whether to allow fallback to building editable wheel and extracting metadata

203

204

Returns:

205

Name of the newly created subfolder within metadata_directory containing the metadata.

206

207

Note: May fall back to building editable wheel and extracting metadata if hook not defined.

208

"""

209

210

def build_editable(

211

self,

212

wheel_directory: str,

213

config_settings: Optional[Mapping[str, Any]] = None,

214

metadata_directory: Optional[str] = None,

215

) -> str:

216

"""

217

Build an editable wheel from this project.

218

219

Parameters:

220

- wheel_directory: The directory to write the wheel to

221

- config_settings: The configuration settings for the build backend

222

- metadata_directory: The directory to reuse existing metadata from

223

224

Returns:

225

The name of the newly created wheel within wheel_directory.

226

"""

227

```

228

229

### Source Distribution Operations

230

231

Operations for building source distributions (sdists).

232

233

```python { .api }

234

def get_requires_for_build_sdist(

235

self,

236

config_settings: Optional[Mapping[str, Any]] = None,

237

) -> Sequence[str]:

238

"""

239

Get additional dependencies required for building an sdist.

240

241

Parameters:

242

- config_settings: The configuration settings for the build backend

243

244

Returns:

245

A list of PEP 508 dependency specifiers.

246

"""

247

248

def build_sdist(

249

self,

250

sdist_directory: str,

251

config_settings: Optional[Mapping[str, Any]] = None,

252

) -> str:

253

"""

254

Build an sdist from this project.

255

256

Parameters:

257

- sdist_directory: The directory to write the sdist to

258

- config_settings: The configuration settings for the build backend

259

260

Returns:

261

The name of the newly created sdist within sdist_directory.

262

"""

263

```

264

265

### Exception Classes

266

267

Exception classes for handling various error conditions during build backend operations.

268

269

```python { .api }

270

class BackendUnavailable(Exception):

271

"""

272

Raised when the backend cannot be imported in the hook process.

273

274

Attributes:

275

- backend_name: The name of the backend that failed to import

276

- backend_path: The backend path that was used

277

- traceback: The traceback from the import failure

278

"""

279

def __init__(

280

self,

281

traceback: str,

282

message: Optional[str] = None,

283

backend_name: Optional[str] = None,

284

backend_path: Optional[Sequence[str]] = None,

285

) -> None: ...

286

287

class HookMissing(Exception):

288

"""

289

Raised on missing hooks when a fallback cannot be used.

290

291

Attributes:

292

- hook_name: The name of the missing hook

293

"""

294

def __init__(self, hook_name: str) -> None: ...

295

296

class UnsupportedOperation(Exception):

297

"""

298

Raised by build_sdist if the backend indicates that it cannot perform the operation.

299

300

Attributes:

301

- traceback: The traceback from the backend failure

302

"""

303

def __init__(self, traceback: str) -> None: ...

304

```

305

306

### Subprocess Runners

307

308

Functions for executing subprocess commands with different behaviors.

309

310

```python { .api }

311

def default_subprocess_runner(

312

cmd: Sequence[str],

313

cwd: Optional[str] = None,

314

extra_environ: Optional[Mapping[str, str]] = None,

315

) -> None:

316

"""

317

The default method of calling the wrapper subprocess.

318

319

Uses subprocess.check_call under the hood.

320

321

Parameters:

322

- cmd: The command to execute as a sequence of strings

323

- cwd: The working directory for the command

324

- extra_environ: Additional environment variables

325

"""

326

327

def quiet_subprocess_runner(

328

cmd: Sequence[str],

329

cwd: Optional[str] = None,

330

extra_environ: Optional[Mapping[str, str]] = None,

331

) -> None:

332

"""

333

Call the subprocess while suppressing output.

334

335

Uses subprocess.check_output under the hood.

336

337

Parameters:

338

- cmd: The command to execute as a sequence of strings

339

- cwd: The working directory for the command

340

- extra_environ: Additional environment variables

341

"""

342

```

343

344

## Types

345

346

```python { .api }

347

from typing import Protocol, Sequence, Optional, Mapping, Any

348

349

class SubprocessRunner(Protocol):

350

"""

351

Protocol for subprocess runner functions.

352

"""

353

def __call__(

354

self,

355

cmd: Sequence[str],

356

cwd: Optional[str] = None,

357

extra_environ: Optional[Mapping[str, str]] = None,

358

) -> None: ...

359

```

360

361

## Deprecated APIs

362

363

```python { .api }

364

# Deprecated alias for BackendUnavailable

365

BackendInvalid = BackendUnavailable

366

```

367

368

Note: `BackendInvalid` is a deprecated alias for `BackendUnavailable`. Use `BackendUnavailable` instead.