or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-framework.mdcore-management.mddependency-resolution.mdenvironment-management.mdindex.mdinstallation-sync.mdproject-management.md

environment-management.mddocs/

0

# Environment Management

1

2

Python environment abstraction supporting virtual environments, system Python, and containerized environments with comprehensive package management capabilities. PDM's environment system provides a unified interface for different Python execution contexts.

3

4

## Capabilities

5

6

### Base Environment Interface

7

8

Abstract base class defining the common interface for all environment types in PDM.

9

10

```python { .api }

11

from abc import ABC, abstractmethod

12

from pathlib import Path

13

14

class BaseEnvironment(ABC):

15

"""

16

Abstract base class for Python environments.

17

18

Provides unified interface for environment operations including

19

path resolution, Python executable access, and package management.

20

"""

21

22

@property

23

@abstractmethod

24

def python_executable(self) -> Path:

25

"""Path to Python executable for this environment"""

26

27

@abstractmethod

28

def get_paths(self) -> dict[str, str]:

29

"""

30

Get environment paths following PEP 427.

31

32

Returns:

33

Dictionary with standard path keys:

34

- platlib: Platform-specific library directory

35

- purelib: Pure Python library directory

36

- headers: Header files directory

37

- scripts: Executable scripts directory

38

- data: Data files directory

39

"""

40

41

@abstractmethod

42

def get_python_executable(self) -> Path:

43

"""

44

Get Python executable path.

45

46

Returns:

47

Path to Python interpreter for this environment

48

"""

49

50

def is_global(self) -> bool:

51

"""

52

Check if this is a global/system environment.

53

54

Returns:

55

True if global system environment

56

"""

57

58

def get_working_set(self) -> list[Distribution]:

59

"""

60

Get currently installed packages in environment.

61

62

Returns:

63

List of installed package distributions

64

"""

65

```

66

67

### Bare Environment

68

69

Minimal environment implementation without package management capabilities.

70

71

```python { .api }

72

class BareEnvironment(BaseEnvironment):

73

"""

74

Minimal environment implementation for basic Python execution.

75

76

Provides Python executable access and path resolution without

77

package installation capabilities. Useful for read-only environments.

78

"""

79

80

def __init__(self, python_executable: Path | str):

81

"""

82

Initialize bare environment.

83

84

Args:

85

python_executable: Path to Python interpreter

86

"""

87

88

@property

89

def python_executable(self) -> Path:

90

"""Python executable path"""

91

92

def get_paths(self) -> dict[str, str]:

93

"""Get environment paths from sysconfig"""

94

95

def get_python_executable(self) -> Path:

96

"""Get Python executable path"""

97

```

98

99

### Python Environment

100

101

Full-featured Python environment with complete package management capabilities.

102

103

```python { .api }

104

class PythonEnvironment(BaseEnvironment):

105

"""

106

Full Python environment with package management capabilities.

107

108

Supports package installation, uninstallation, and environment

109

manipulation using pip and other standard tools.

110

"""

111

112

def __init__(

113

self,

114

python_executable: Path | str,

115

prefix: Path | str | None = None

116

):

117

"""

118

Initialize Python environment.

119

120

Args:

121

python_executable: Path to Python interpreter

122

prefix: Optional environment prefix path

123

"""

124

125

def install(self, requirements: list[str]) -> None:

126

"""

127

Install packages in this environment.

128

129

Args:

130

requirements: List of requirement specifications to install

131

132

Raises:

133

InstallationError: Package installation failed

134

"""

135

136

def uninstall(self, packages: list[str]) -> None:

137

"""

138

Uninstall packages from this environment.

139

140

Args:

141

packages: List of package names to uninstall

142

143

Raises:

144

UninstallError: Package uninstallation failed

145

"""

146

147

def update_shebangs(self, packages: list[str]) -> None:

148

"""

149

Update script shebangs for specified packages.

150

151

Args:

152

packages: Package names to update shebangs for

153

"""

154

155

def get_python_version(self) -> tuple[int, int, int]:

156

"""

157

Get Python version tuple.

158

159

Returns:

160

Python version as (major, minor, micro) tuple

161

"""

162

163

def run_command(

164

self,

165

command: list[str],

166

cwd: Path | str | None = None,

167

env: dict[str, str] | None = None

168

) -> subprocess.CompletedProcess:

169

"""

170

Run command in this environment.

171

172

Args:

173

command: Command and arguments to execute

174

cwd: Working directory for command

175

env: Environment variables for command

176

177

Returns:

178

Completed process result

179

"""

180

```

181

182

### Local Python Environment

183

184

Specialized environment for local/system Python installations with enhanced integration.

185

186

```python { .api }

187

class PythonLocalEnvironment(PythonEnvironment):

188

"""

189

Local Python environment for system installations.

190

191

Provides enhanced integration with system Python installations

192

and local development workflows.

193

"""

194

195

def __init__(self, python_executable: Path | str):

196

"""

197

Initialize local Python environment.

198

199

Args:

200

python_executable: Path to system Python interpreter

201

"""

202

203

def get_site_packages(self) -> list[Path]:

204

"""

205

Get site-packages directories.

206

207

Returns:

208

List of site-packages directory paths

209

"""

210

211

def is_venv(self) -> bool:

212

"""

213

Check if environment is a virtual environment.

214

215

Returns:

216

True if virtual environment

217

"""

218

219

def get_venv_root(self) -> Path | None:

220

"""

221

Get virtual environment root directory.

222

223

Returns:

224

Path to venv root, or None if not a venv

225

"""

226

```

227

228

### Environment Detection and Creation

229

230

Utilities for environment detection, creation, and management.

231

232

```python { .api }

233

def get_environment(python_executable: Path | str) -> BaseEnvironment:

234

"""

235

Get appropriate environment instance for Python executable.

236

237

Args:

238

python_executable: Path to Python interpreter

239

240

Returns:

241

Environment instance (PythonEnvironment or PythonLocalEnvironment)

242

"""

243

244

def find_python_executable(version_spec: str | None = None) -> Path:

245

"""

246

Find Python executable matching version specification.

247

248

Args:

249

version_spec: Python version specification (e.g., "3.9", ">=3.8")

250

251

Returns:

252

Path to matching Python executable

253

254

Raises:

255

NoPythonVersion: No matching Python found

256

"""

257

258

def create_venv(

259

location: Path | str,

260

python_executable: Path | str | None = None,

261

prompt: str | None = None

262

) -> PythonEnvironment:

263

"""

264

Create new virtual environment.

265

266

Args:

267

location: Directory for new virtual environment

268

python_executable: Python executable to use as base

269

prompt: Custom prompt for virtual environment

270

271

Returns:

272

New PythonEnvironment instance for created venv

273

"""

274

```

275

276

### Environment Information

277

278

Classes for gathering and representing Python environment information.

279

280

```python { .api }

281

@dataclass

282

class PythonInfo:

283

"""

284

Python interpreter information and capabilities.

285

286

Contains comprehensive information about a Python installation

287

including version, paths, and feature support.

288

"""

289

290

executable: Path

291

version: tuple[int, int, int]

292

implementation: str

293

architecture: str

294

abi_tag: str

295

296

@property

297

def version_string(self) -> str:

298

"""Formatted version string (e.g., '3.9.7')"""

299

300

@property

301

def interpreter_tag(self) -> str:

302

"""PEP 425 interpreter tag (e.g., 'cp39')"""

303

304

def supports_feature(self, feature: str) -> bool:

305

"""

306

Check if Python supports specific feature.

307

308

Args:

309

feature: Feature name to check

310

311

Returns:

312

True if feature is supported

313

"""

314

315

def get_python_info(executable: Path | str) -> PythonInfo:

316

"""

317

Get comprehensive Python interpreter information.

318

319

Args:

320

executable: Path to Python interpreter

321

322

Returns:

323

PythonInfo instance with interpreter details

324

"""

325

```

326

327

### Usage Examples

328

329

#### Basic Environment Operations

330

331

```python

332

from pdm.environments import get_environment, PythonEnvironment

333

from pathlib import Path

334

335

# Get environment for system Python

336

python_path = Path("/usr/bin/python3.9")

337

env = get_environment(python_path)

338

339

# Check environment type

340

print(f"Environment type: {type(env).__name__}")

341

print(f"Python executable: {env.python_executable}")

342

print(f"Is global: {env.is_global()}")

343

344

# Get environment paths

345

paths = env.get_paths()

346

for key, path in paths.items():

347

print(f"{key}: {path}")

348

349

# Get installed packages

350

working_set = env.get_working_set()

351

for dist in working_set:

352

print(f"{dist.name} {dist.version}")

353

```

354

355

#### Package Management in Environment

356

357

```python

358

from pdm.environments import PythonEnvironment

359

360

# Create environment instance

361

env = PythonEnvironment("/usr/bin/python3.9")

362

363

# Install packages

364

env.install([

365

"requests>=2.25.0",

366

"click>=8.0.0",

367

"rich"

368

])

369

370

# Check what's installed

371

working_set = env.get_working_set()

372

installed = {dist.name: dist.version for dist in working_set}

373

print("Installed packages:", installed)

374

375

# Uninstall packages

376

env.uninstall(["rich"])

377

378

# Update shebangs after installation

379

env.update_shebangs(["requests", "click"])

380

```

381

382

#### Virtual Environment Creation

383

384

```python

385

from pdm.environments import create_venv, find_python_executable

386

from pathlib import Path

387

388

# Find appropriate Python version

389

python_exe = find_python_executable(">=3.8")

390

print(f"Using Python: {python_exe}")

391

392

# Create virtual environment

393

venv_path = Path("./my-venv")

394

env = create_venv(

395

location=venv_path,

396

python_executable=python_exe,

397

prompt="my-project"

398

)

399

400

# Verify virtual environment

401

local_env = env

402

if hasattr(local_env, 'is_venv') and local_env.is_venv():

403

venv_root = local_env.get_venv_root()

404

print(f"Created virtual environment at: {venv_root}")

405

```

406

407

#### Environment Detection and Information

408

409

```python

410

from pdm.environments import get_environment, get_python_info

411

from pathlib import Path

412

413

# Detect environment type

414

env = get_environment("/usr/bin/python3")

415

print(f"Environment: {type(env).__name__}")

416

417

# Get detailed Python information

418

python_info = get_python_info(env.python_executable)

419

print(f"Python {python_info.version_string}")

420

print(f"Implementation: {python_info.implementation}")

421

print(f"Architecture: {python_info.architecture}")

422

print(f"Interpreter tag: {python_info.interpreter_tag}")

423

424

# Check feature support

425

if python_info.supports_feature("f-strings"):

426

print("F-strings are supported")

427

```

428

429

#### Running Commands in Environment

430

431

```python

432

from pdm.environments import PythonEnvironment

433

from pathlib import Path

434

import subprocess

435

436

env = PythonEnvironment("/usr/bin/python3.9")

437

438

# Run Python script in environment

439

result = env.run_command([

440

"python", "-c", "import sys; print(sys.version)"

441

])

442

print("Python version:", result.stdout.decode())

443

444

# Run with custom environment variables

445

result = env.run_command(

446

["python", "-c", "import os; print(os.environ.get('CUSTOM_VAR'))"],

447

env={"CUSTOM_VAR": "test_value"}

448

)

449

print("Custom variable:", result.stdout.decode())

450

451

# Run from specific working directory

452

result = env.run_command(

453

["python", "-m", "pip", "list"],

454

cwd=Path("/tmp")

455

)

456

```