or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mdenvironment.mdexceptions.mdindex.mdproject.mdroutines.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Utility functions for dependency parsing, shell operations, file handling, and system integration. These modules provide helper functions, constants, and lower-level operations that support pipenv's core functionality.

3

4

## Capabilities

5

6

### Dependency Utilities

7

8

Parse and manipulate package dependencies and version specifications.

9

10

```python { .api }

11

# From pipenv.utils.dependencies

12

def get_version(pipfile_entry):

13

"""

14

Extract version specification from Pipfile entry.

15

16

Parameters:

17

pipfile_entry: Pipfile package entry (str or dict)

18

19

Returns:

20

str: Version specification

21

"""

22

23

def python_version(path_to_python):

24

"""

25

Get Python version from executable path.

26

27

Parameters:

28

path_to_python (str): Path to Python executable

29

30

Returns:

31

str: Python version string

32

"""

33

34

def clean_pkg_version(version):

35

"""

36

Clean and normalize package version string.

37

38

Parameters:

39

version (str): Raw version string

40

41

Returns:

42

str: Cleaned version string

43

"""

44

45

def expansive_install_req_from_line(line, extras_to_install=None):

46

"""

47

Parse pip install line into InstallRequirement.

48

49

Parameters:

50

line (str): Pip install line

51

extras_to_install (list, optional): Extra requirements

52

53

Returns:

54

InstallRequirement: Parsed requirement

55

"""

56

57

def determine_package_name(package):

58

"""

59

Determine canonical package name.

60

61

Parameters:

62

package: Package specification

63

64

Returns:

65

str: Package name

66

"""

67

68

def get_canonical_names(packages):

69

"""

70

Get canonical names for packages.

71

72

Parameters:

73

packages (list): List of package specifications

74

75

Returns:

76

list: Canonical package names

77

"""

78

```

79

80

Usage examples:

81

```python

82

from pipenv.utils.dependencies import (

83

get_version, python_version, clean_pkg_version,

84

determine_package_name, get_canonical_names

85

)

86

87

# Extract version from Pipfile entries

88

version1 = get_version("requests>=2.25.0") # ">=2.25.0"

89

version2 = get_version({"version": "==1.0.0"}) # "==1.0.0"

90

version3 = get_version("*") # "*"

91

92

# Get Python version

93

py_version = python_version("/usr/bin/python3.9")

94

print(f"Python version: {py_version}") # "3.9.7"

95

96

# Clean version strings

97

clean_version = clean_pkg_version("==2.25.1 ") # "==2.25.1"

98

99

# Parse install requirements

100

from pipenv.utils.dependencies import expansive_install_req_from_line

101

req = expansive_install_req_from_line("requests>=2.25.0")

102

print(f"Package: {req.name}, Version: {req.specifier}")

103

104

# Determine package names

105

name1 = determine_package_name("requests>=2.25.0") # "requests"

106

name2 = determine_package_name("git+https://...") # Extracted from URL

107

108

# Get canonical names

109

packages = ["Django", "REQUESTS", "click"]

110

canonical = get_canonical_names(packages)

111

print(f"Canonical names: {canonical}") # ["django", "requests", "click"]

112

```

113

114

### Shell Utilities

115

116

Handle shell operations, path manipulation, and directory management.

117

118

```python { .api }

119

# From pipenv.utils.shell

120

def make_posix(path):

121

"""

122

Convert path to POSIX format.

123

124

Parameters:

125

path (str): File system path

126

127

Returns:

128

str: POSIX-formatted path

129

"""

130

131

def chdir(path):

132

"""

133

Context manager for changing directory.

134

135

Parameters:

136

path (str): Directory path to change to

137

138

Returns:

139

ContextManager: Directory change context

140

"""

141

142

def looks_like_dir(path):

143

"""

144

Check if path looks like a directory.

145

146

Parameters:

147

path (str): Path to check

148

149

Returns:

150

bool: True if path looks like directory

151

"""

152

153

def load_path(python):

154

"""

155

Load Python sys.path for given executable.

156

157

Parameters:

158

python (str): Python executable path

159

160

Returns:

161

list: Python sys.path entries

162

"""

163

```

164

165

Usage examples:

166

```python

167

from pipenv.utils.shell import make_posix, chdir, looks_like_dir, load_path

168

import os

169

170

# Convert to POSIX paths

171

posix_path = make_posix("C:\\Users\\Name\\Project") # "/c/Users/Name/Project"

172

posix_path2 = make_posix("/already/posix/path") # "/already/posix/path"

173

174

# Change directory context

175

current_dir = os.getcwd()

176

with chdir("/tmp"):

177

print(f"Inside context: {os.getcwd()}") # "/tmp"

178

# Do work in /tmp

179

print(f"Outside context: {os.getcwd()}") # Back to original

180

181

# Check if path looks like directory

182

is_dir1 = looks_like_dir("/path/to/directory/") # True

183

is_dir2 = looks_like_dir("/path/to/file.py") # False

184

is_dir3 = looks_like_dir("relative_dir") # True

185

186

# Load Python path

187

python_paths = load_path("/usr/bin/python3.9")

188

print(f"Python sys.path: {python_paths}")

189

```

190

191

### Pipfile Utilities

192

193

Handle Pipfile discovery, creation, and manipulation.

194

195

```python { .api }

196

# From pipenv.utils.pipfile

197

def find_pipfile(max_depth=3):

198

"""

199

Find Pipfile in directory tree.

200

201

Parameters:

202

max_depth (int): Maximum directories to search up

203

204

Returns:

205

str|None: Path to Pipfile or None if not found

206

"""

207

208

def ensure_pipfile():

209

"""

210

Ensure Pipfile exists in current directory.

211

212

Returns:

213

str: Path to Pipfile

214

"""

215

216

class Pipfile:

217

"""

218

Pipfile manipulation class.

219

220

Methods:

221

load(): Load Pipfile content

222

write(): Write Pipfile content

223

add_package(): Add package to Pipfile

224

remove_package(): Remove package from Pipfile

225

"""

226

```

227

228

Usage examples:

229

```python

230

from pipenv.utils.pipfile import find_pipfile, ensure_pipfile, Pipfile

231

import os

232

233

# Find Pipfile in current or parent directories

234

pipfile_path = find_pipfile(max_depth=5)

235

if pipfile_path:

236

print(f"Found Pipfile at: {pipfile_path}")

237

else:

238

print("No Pipfile found")

239

240

# Ensure Pipfile exists

241

pipfile_path = ensure_pipfile()

242

print(f"Pipfile location: {pipfile_path}")

243

244

# Work with Pipfile class

245

pipfile = Pipfile()

246

pipfile_data = pipfile.load()

247

print(f"Pipfile packages: {pipfile_data.get('packages', {}).keys()}")

248

249

# Modify Pipfile

250

pipfile.add_package("requests", ">=2.25.0")

251

pipfile.remove_package("unused-package")

252

pipfile.write()

253

```

254

255

### Locking Utilities

256

257

Handle lock file operations and atomic writes.

258

259

```python { .api }

260

# From pipenv.utils.locking

261

def prepare_lockfile(lockfile_data):

262

"""

263

Prepare lockfile data for writing.

264

265

Parameters:

266

lockfile_data (dict): Raw lockfile data

267

268

Returns:

269

dict: Prepared lockfile data

270

"""

271

272

def atomic_open_for_write(filename):

273

"""

274

Atomic file writing context manager.

275

276

Parameters:

277

filename (str): File to write atomically

278

279

Returns:

280

ContextManager: Atomic write context

281

"""

282

283

class Lockfile:

284

"""

285

Lockfile operations class.

286

287

Methods:

288

load(): Load lockfile content

289

write(): Write lockfile content

290

verify(): Verify lockfile integrity

291

"""

292

```

293

294

Usage examples:

295

```python

296

from pipenv.utils.locking import prepare_lockfile, atomic_open_for_write, Lockfile

297

import json

298

299

# Prepare lockfile data

300

raw_lockfile = {

301

"default": {"requests": {"version": "==2.25.1"}},

302

"develop": {"pytest": {"version": "==6.2.2"}}

303

}

304

prepared = prepare_lockfile(raw_lockfile)

305

306

# Atomic file writing

307

with atomic_open_for_write("Pipfile.lock") as f:

308

json.dump(prepared, f, indent=4)

309

310

# Work with Lockfile class

311

lockfile = Lockfile()

312

lockfile_data = lockfile.load()

313

print(f"Lockfile hash: {lockfile_data.get('_meta', {}).get('hash')}")

314

315

# Verify lockfile

316

is_valid = lockfile.verify()

317

print(f"Lockfile valid: {is_valid}")

318

```

319

320

### Constants and Definitions

321

322

Important constants and type definitions used throughout pipenv.

323

324

```python { .api }

325

# From pipenv.utils.constants

326

VCS_LIST: tuple # ("git", "svn", "hg", "bzr")

327

SCHEME_LIST: tuple # ("http://", "https://", "ftp://", ...)

328

FALSE_VALUES: tuple # ("0", "false", "no", "off")

329

TRUE_VALUES: tuple # ("1", "true", "yes", "on")

330

REMOTE_SCHEMES: tuple # Remote URL schemes

331

RELEVANT_PROJECT_FILES: tuple # Project configuration files

332

INSTALLABLE_EXTENSIONS: tuple # Package file extensions

333

334

# Additional constants

335

DEFAULT_NEWLINES: str # Default line endings

336

PIPFILE_SPEC: dict # Pipfile specification

337

LOCKFILE_VERSION: str # Lock file format version

338

```

339

340

Usage examples:

341

```python

342

from pipenv.utils.constants import (

343

VCS_LIST, SCHEME_LIST, FALSE_VALUES, TRUE_VALUES,

344

RELEVANT_PROJECT_FILES, INSTALLABLE_EXTENSIONS

345

)

346

347

# Check VCS systems

348

if "git" in VCS_LIST:

349

print("Git is supported")

350

351

# Validate URL schemes

352

def is_remote_url(url):

353

return any(url.startswith(scheme) for scheme in SCHEME_LIST)

354

355

# Parse boolean values

356

def parse_bool(value):

357

if str(value).lower() in TRUE_VALUES:

358

return True

359

elif str(value).lower() in FALSE_VALUES:

360

return False

361

else:

362

raise ValueError(f"Invalid boolean value: {value}")

363

364

# Check for project files

365

import os

366

def find_project_files():

367

found_files = []

368

for filename in RELEVANT_PROJECT_FILES:

369

if os.path.exists(filename):

370

found_files.append(filename)

371

return found_files

372

373

# Check installable files

374

def is_installable_file(filename):

375

return any(filename.endswith(ext) for ext in INSTALLABLE_EXTENSIONS)

376

377

print(f"VCS systems: {VCS_LIST}")

378

print(f"URL schemes: {SCHEME_LIST}")

379

print(f"Project files: {find_project_files()}")

380

```

381

382

### Script Parsing

383

384

Parse and execute Pipfile scripts with support for call-based script definitions.

385

386

```python { .api }

387

class Script:

388

"""

389

Parse a script line from Pipfile's [scripts] section.

390

Always works in POSIX mode, even on Windows.

391

"""

392

393

script_types: list # ["call"]

394

395

def __init__(self, command, args=None):

396

"""

397

Initialize Script with command and arguments.

398

399

Parameters:

400

command (str): The command to execute

401

args (list, optional): Additional arguments

402

"""

403

404

@classmethod

405

def parse(cls, value):

406

"""

407

Parse script value from Pipfile.

408

409

Parameters:

410

value: Script definition (str, list, or inline table)

411

412

Returns:

413

Script: Parsed script instance

414

"""

415

416

def cmdify(self):

417

"""

418

Convert script to executable command format.

419

420

Returns:

421

str: Executable command string

422

"""

423

424

class ScriptEmptyError(ValueError):

425

"""Raised when script definition is empty."""

426

427

class ScriptParseError(ValueError):

428

"""Raised when script definition cannot be parsed."""

429

```

430

431

Usage examples:

432

```python

433

from pipenv.cmdparse import Script, ScriptParseError

434

435

# Parse simple string script

436

script = Script.parse("python setup.py test")

437

command = script.cmdify()

438

print(f"Command: {command}")

439

440

# Parse call-based script

441

call_script = Script.parse({"call": "mypackage.module:function('arg')"})

442

call_command = call_script.cmdify()

443

print(f"Call command: {call_command}")

444

445

# Handle script parsing errors

446

try:

447

invalid_script = Script.parse({"invalid": "not supported"})

448

except ScriptParseError as e:

449

print(f"Script parse error: {e}")

450

451

# Create script programmatically

452

custom_script = Script("pytest", ["-v", "--cov=mypackage"])

453

test_command = custom_script.cmdify()

454

print(f"Test command: {test_command}")

455

```

456

457

### File and Path Utilities

458

459

Additional file and path manipulation utilities.

460

461

```python { .api }

462

# File operations

463

def normalize_path(path):

464

"""Normalize file system path."""

465

466

def is_file_url(url):

467

"""Check if URL is a file:// URL."""

468

469

def is_vcs_url(url):

470

"""Check if URL is a VCS URL."""

471

472

def temp_environ():

473

"""Context manager for temporary environment variables."""

474

475

def safe_expandvars(value):

476

"""Safely expand environment variables in string."""

477

```

478

479

Usage examples:

480

```python

481

from pipenv.utils import normalize_path, is_file_url, is_vcs_url, temp_environ

482

import os

483

484

# Normalize paths

485

normalized = normalize_path("./relative/../path/to/file")

486

print(f"Normalized: {normalized}")

487

488

# Check URL types

489

file_url = is_file_url("file:///path/to/file") # True

490

vcs_url = is_vcs_url("git+https://github.com/user/repo") # True

491

492

# Temporary environment

493

with temp_environ():

494

os.environ["TEMP_VAR"] = "temporary_value"

495

print(f"Temp var: {os.environ.get('TEMP_VAR')}")

496

# Variable is removed after context

497

```

498

499

## Integration Examples

500

501

Complete examples showing utility integration.

502

503

### Dependency Analysis

504

505

```python

506

from pipenv.utils.dependencies import (

507

get_version, determine_package_name, get_canonical_names

508

)

509

from pipenv.utils.pipfile import Pipfile

510

511

def analyze_dependencies():

512

"""Analyze project dependencies."""

513

pipfile = Pipfile()

514

pipfile_data = pipfile.load()

515

516

packages = pipfile_data.get("packages", {})

517

dev_packages = pipfile_data.get("dev-packages", {})

518

519

print("Production Dependencies:")

520

for pkg, spec in packages.items():

521

version = get_version(spec)

522

canonical = determine_package_name(pkg)

523

print(f" {canonical}: {version}")

524

525

print("\nDevelopment Dependencies:")

526

for pkg, spec in dev_packages.items():

527

version = get_version(spec)

528

canonical = determine_package_name(pkg)

529

print(f" {canonical}: {version}")

530

531

# analyze_dependencies()

532

```

533

534

### Environment Setup

535

536

```python

537

from pipenv.utils.shell import chdir, load_path

538

from pipenv.utils.pipfile import find_pipfile, ensure_pipfile

539

import os

540

541

def setup_project_environment(project_path):

542

"""Set up pipenv project environment."""

543

with chdir(project_path):

544

# Find or create Pipfile

545

pipfile_path = find_pipfile()

546

if not pipfile_path:

547

pipfile_path = ensure_pipfile()

548

print(f"Created new Pipfile at: {pipfile_path}")

549

else:

550

print(f"Using existing Pipfile: {pipfile_path}")

551

552

# Load Python path information

553

python_exe = "/usr/bin/python3"

554

if os.path.exists(python_exe):

555

sys_path = load_path(python_exe)

556

print(f"Python sys.path has {len(sys_path)} entries")

557

558

# setup_project_environment("/path/to/project")

559

```

560

561

### Lock File Management

562

563

```python

564

from pipenv.utils.locking import prepare_lockfile, atomic_open_for_write, Lockfile

565

import json

566

import hashlib

567

568

def update_lockfile(packages_data):

569

"""Update lock file with new package data."""

570

# Prepare lockfile data

571

lockfile_data = {

572

"_meta": {

573

"hash": {"sha256": hashlib.sha256(json.dumps(packages_data, sort_keys=True).encode()).hexdigest()},

574

"pipfile-spec": 6,

575

"requires": {"python_version": "3.9"},

576

"sources": [{"name": "pypi", "url": "https://pypi.org/simple", "verify_ssl": True}]

577

},

578

"default": packages_data.get("packages", {}),

579

"develop": packages_data.get("dev-packages", {})

580

}

581

582

prepared = prepare_lockfile(lockfile_data)

583

584

# Write atomically

585

with atomic_open_for_write("Pipfile.lock") as f:

586

json.dump(prepared, f, indent=4, sort_keys=True)

587

588

print("Lockfile updated successfully")

589

590

# Example usage

591

# packages = {

592

# "packages": {"requests": {"version": "==2.25.1"}},

593

# "dev-packages": {"pytest": {"version": "==6.2.2"}}

594

# }

595

# update_lockfile(packages)

596

```