or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-backend.mdbuilders.mdconfiguration.mdconstraints.mdfactory-core.mdindex.mdjson-validation.mdpackages.mdutilities.mdvcs-support.mdversion-system.md

packages.mddocs/

0

# Package System

1

2

Poetry Core provides a comprehensive package system for managing package specifications, dependencies, and various dependency types. This system supports standard Python packages, VCS dependencies, local file/directory dependencies, and URL-based dependencies.

3

4

## Core Imports

5

6

```python

7

# Base package classes

8

from poetry.core.packages.specification import PackageSpecification

9

from poetry.core.packages.package import Package

10

from poetry.core.packages.project_package import ProjectPackage

11

12

# Dependency classes

13

from poetry.core.packages.dependency import Dependency

14

from poetry.core.packages.dependency_group import DependencyGroup, MAIN_GROUP

15

16

# Specialized dependency types

17

from poetry.core.packages.directory_dependency import DirectoryDependency

18

from poetry.core.packages.file_dependency import FileDependency

19

from poetry.core.packages.url_dependency import URLDependency

20

from poetry.core.packages.vcs_dependency import VCSDependency

21

22

# Utility functions

23

from poetry.core.packages.utils import dependency_from_pep_508

24

``` { .api }

25

26

## PackageSpecification

27

28

Base class for package specifications providing source information and feature management.

29

30

### PackageSpecification.__init__

31

32

```python

33

class PackageSpecification:

34

def __init__(

35

self,

36

name: str,

37

source_type: str | None = None,

38

source_url: str | None = None,

39

source_reference: str | None = None,

40

source_resolved_reference: str | None = None,

41

source_subdirectory: str | None = None,

42

features: Iterable[str] | None = None,

43

) -> None:

44

"""

45

Initialize package specification.

46

47

Args:

48

name: Package name (will be normalized)

49

source_type: Source type ("git", "file", "directory", "url", None)

50

source_url: Source URL or path

51

source_reference: Source reference (branch, tag, commit for VCS)

52

source_resolved_reference: Resolved reference (full commit hash)

53

source_subdirectory: Subdirectory within source

54

features: Package features/extras to enable

55

56

Example:

57

>>> spec = PackageSpecification("requests")

58

>>> spec = PackageSpecification(

59

... "mypackage",

60

... source_type="git",

61

... source_url="https://github.com/user/repo.git",

62

... source_reference="main"

63

... )

64

"""

65

``` { .api }

66

67

### Properties

68

69

#### Name Properties

70

71

```python

72

@property

73

def name(self) -> NormalizedName:

74

"""Normalized package name (PEP 503 compliant)."""

75

76

@property

77

def pretty_name(self) -> str:

78

"""Original case-preserved package name."""

79

80

@property

81

def complete_name(self) -> str:

82

"""

83

Name including features in normalized form.

84

85

Returns:

86

Package name with features like "requests[security,socks]"

87

88

Example:

89

>>> spec = PackageSpecification("requests", features=["security"])

90

>>> print(spec.complete_name)

91

requests[security]

92

"""

93

94

@property

95

def complete_pretty_name(self) -> str:

96

"""Name including features in pretty form."""

97

``` { .api }

98

99

#### Source Properties

100

101

```python

102

@property

103

def source_type(self) -> str | None:

104

"""

105

Source type identifier.

106

107

Returns:

108

One of: "git", "file", "directory", "url", or None for PyPI

109

"""

110

111

@property

112

def source_url(self) -> str | None:

113

"""Source URL or local path."""

114

115

@property

116

def source_reference(self) -> str | None:

117

"""Source reference (branch, tag, commit for VCS)."""

118

119

@property

120

def source_resolved_reference(self) -> str | None:

121

"""Resolved reference (full commit hash for VCS)."""

122

123

@property

124

def source_subdirectory(self) -> str | None:

125

"""Subdirectory within source."""

126

127

@property

128

def features(self) -> frozenset[NormalizedName]:

129

"""Package features/extras enabled."""

130

``` { .api }

131

132

### Methods

133

134

```python

135

def is_direct_origin(self) -> bool:

136

"""

137

Check if package comes from direct source (not PyPI).

138

139

Returns:

140

True if source_type is not None (VCS, file, directory, URL)

141

"""

142

143

def provides(self, other: PackageSpecification) -> bool:

144

"""

145

Check if this specification provides another specification.

146

147

Args:

148

other: Another package specification

149

150

Returns:

151

True if this spec can satisfy the other spec

152

"""

153

154

def is_same_source_as(self, other: PackageSpecification) -> bool:

155

"""Check if two specs have the same source."""

156

157

def is_same_package_as(self, other: PackageSpecification) -> bool:

158

"""Check if two specs represent the same package."""

159

160

def clone(self: T) -> T:

161

"""Create a shallow copy of this specification."""

162

163

def with_features(self: T, features: Iterable[str]) -> T:

164

"""

165

Create copy with additional features.

166

167

Args:

168

features: Features/extras to add

169

170

Returns:

171

New specification with combined features

172

"""

173

174

def without_features(self: T) -> T:

175

"""Create copy without any features."""

176

``` { .api }

177

178

## Dependency

179

180

Represents a package dependency with version constraints and metadata.

181

182

### Dependency.__init__

183

184

```python

185

class Dependency(PackageSpecification):

186

def __init__(

187

self,

188

name: str,

189

constraint: str | VersionConstraint,

190

optional: bool = False,

191

groups: Iterable[str] | None = None,

192

allows_prereleases: bool | None = None,

193

extras: Iterable[str] | None = None,

194

source_type: str | None = None,

195

source_url: str | None = None,

196

source_reference: str | None = None,

197

source_resolved_reference: str | None = None,

198

source_subdirectory: str | None = None,

199

) -> None:

200

"""

201

Create a package dependency.

202

203

Args:

204

name: Package name

205

constraint: Version constraint (string or VersionConstraint object)

206

optional: Whether dependency is optional

207

groups: Dependency groups (defaults to ["main"])

208

allows_prereleases: Whether to allow prerelease versions

209

extras: Package extras/features to enable

210

source_type: Source type for non-PyPI dependencies

211

source_url: Source URL for non-PyPI dependencies

212

source_reference: VCS reference (branch, tag, commit)

213

source_resolved_reference: Resolved VCS reference

214

source_subdirectory: Subdirectory within source

215

216

Example:

217

>>> dep = Dependency("requests", "^2.25.0")

218

>>> dep = Dependency("pytest", ">=6.0.0", groups=["dev"])

219

>>> dep = Dependency("mypackage", "*", optional=True, extras=["extra1"])

220

"""

221

``` { .api }

222

223

### Properties

224

225

#### Core Dependency Properties

226

227

```python

228

@property

229

def constraint(self) -> VersionConstraint:

230

"""Version constraint for this dependency."""

231

232

@constraint.setter

233

def constraint(self, constraint: str | VersionConstraint) -> None:

234

"""Set version constraint from string or VersionConstraint object."""

235

236

@property

237

def pretty_constraint(self) -> str:

238

"""Human-readable constraint string."""

239

240

@property

241

def optional(self) -> bool:

242

"""Whether dependency is optional."""

243

244

@property

245

def groups(self) -> frozenset[str]:

246

"""

247

Dependency groups.

248

249

Returns:

250

Set of group names like {"main", "dev", "test"}

251

"""

252

``` { .api }

253

254

#### Python and Marker Properties

255

256

```python

257

@property

258

def python_versions(self) -> str:

259

"""

260

Required Python versions.

261

262

Returns:

263

Python version constraint string (e.g., ">=3.8,<4.0")

264

"""

265

266

@python_versions.setter

267

def python_versions(self, value: str) -> None:

268

"""Set Python version requirements."""

269

270

@property

271

def marker(self) -> BaseMarker:

272

"""

273

PEP 508 environment marker.

274

275

Returns:

276

Environment marker for conditional installation

277

"""

278

279

@marker.setter

280

def marker(self, marker: str | BaseMarker) -> None:

281

"""Set environment marker from string or BaseMarker."""

282

283

@property

284

def allows_prereleases(self) -> bool | None:

285

"""Whether to allow prerelease versions."""

286

``` { .api }

287

288

### Static Methods

289

290

#### create_from_pep_508

291

292

```python

293

@classmethod

294

def create_from_pep_508(

295

cls,

296

requirement_string: str,

297

relative_to: Path | None = None

298

) -> Dependency:

299

"""

300

Create dependency from PEP 508 requirement string.

301

302

Args:

303

requirement_string: PEP 508 requirement specification

304

relative_to: Base path for resolving relative file/directory paths

305

306

Returns:

307

Appropriate Dependency subclass instance

308

309

Raises:

310

InvalidRequirementError: If requirement string is malformed

311

312

Examples:

313

>>> dep = Dependency.create_from_pep_508("requests>=2.25.0")

314

>>> dep = Dependency.create_from_pep_508("pytest>=6.0; python_version>='3.8'")

315

>>> dep = Dependency.create_from_pep_508("mypackage[extra1,extra2]>=1.0")

316

>>> dep = Dependency.create_from_pep_508("./local-package", Path("/base/dir"))

317

"""

318

``` { .api }

319

320

## Package

321

322

Represents an installed or installable package with metadata.

323

324

### Package.__init__

325

326

```python

327

class Package(PackageSpecification):

328

def __init__(

329

self,

330

name: str,

331

version: str | Version,

332

description: str = "",

333

category: str = "main",

334

optional: bool = False,

335

develop: bool = False,

336

source_type: str | None = None,

337

source_url: str | None = None,

338

source_reference: str | None = None,

339

source_resolved_reference: str | None = None,

340

source_subdirectory: str | None = None,

341

features: Iterable[str] | None = None,

342

) -> None:

343

"""

344

Create package instance.

345

346

Args:

347

name: Package name

348

version: Package version (string or Version object)

349

description: Package description

350

category: Package category ("main", "dev", etc.)

351

optional: Whether package is optional

352

develop: Whether this is a development package

353

source_type: Source type for non-PyPI packages

354

source_url: Source URL for non-PyPI packages

355

source_reference: VCS reference

356

source_resolved_reference: Resolved VCS reference

357

source_subdirectory: Subdirectory within source

358

features: Enabled package features

359

"""

360

``` { .api }

361

362

### Properties

363

364

```python

365

@property

366

def version(self) -> Version:

367

"""Package version object."""

368

369

@property

370

def description(self) -> str:

371

"""Package description."""

372

373

@property

374

def category(self) -> str:

375

"""Package category (main, dev, etc.)."""

376

377

@property

378

def optional(self) -> bool:

379

"""Whether package is optional."""

380

381

@property

382

def files(self) -> list[dict[str, Any]]:

383

"""

384

Package files information.

385

386

Returns:

387

List of file info dictionaries with hashes and paths

388

"""

389

390

@files.setter

391

def files(self, files: list[dict[str, Any]]) -> None:

392

"""Set package files information."""

393

``` { .api }

394

395

## ProjectPackage

396

397

Represents the project package being built with additional Poetry-specific metadata.

398

399

### ProjectPackage Properties

400

401

```python

402

class ProjectPackage(Package):

403

# Additional metadata properties

404

405

@property

406

def authors(self) -> list[str]:

407

"""Package authors list."""

408

409

@property

410

def maintainers(self) -> list[str]:

411

"""Package maintainers list."""

412

413

@property

414

def homepage(self) -> str | None:

415

"""Homepage URL."""

416

417

@property

418

def repository_url(self) -> str | None:

419

"""Repository URL."""

420

421

@property

422

def documentation_url(self) -> str | None:

423

"""Documentation URL."""

424

425

@property

426

def keywords(self) -> list[str]:

427

"""Package keywords."""

428

429

@property

430

def classifiers(self) -> list[str]:

431

"""Trove classifiers."""

432

433

@property

434

def license(self) -> License | None:

435

"""Package license object."""

436

437

@property

438

def readmes(self) -> tuple[Path, ...]:

439

"""README files."""

440

441

@property

442

def packages(self) -> list[dict[str, Any]]:

443

"""Package includes configuration."""

444

445

@property

446

def include(self) -> list[dict[str, Any]]:

447

"""File includes configuration."""

448

449

@property

450

def exclude(self) -> list[str]:

451

"""File excludes patterns."""

452

453

@property

454

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

455

"""Custom project URLs."""

456

457

@property

458

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

459

"""Entry points configuration."""

460

461

@property

462

def extras(self) -> dict[NormalizedName, list[Dependency]]:

463

"""Optional extras and their dependencies."""

464

465

@property

466

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

467

"""Build configuration settings."""

468

``` { .api }

469

470

### Dependency Management

471

472

```python

473

def add_dependency(self, dependency: Dependency) -> None:

474

"""

475

Add dependency to project.

476

477

Args:

478

dependency: Dependency to add

479

480

Note:

481

Dependencies are organized by groups. Main dependencies

482

go to the "main" group, dev dependencies to "dev", etc.

483

"""

484

485

def remove_dependency(self, name: str, group: str = MAIN_GROUP) -> None:

486

"""Remove dependency from specified group."""

487

488

@property

489

def requires(self) -> list[Dependency]:

490

"""All main dependencies."""

491

492

@property

493

def dev_requires(self) -> list[Dependency]:

494

"""Development dependencies."""

495

496

def dependency_group(self, name: str) -> DependencyGroup:

497

"""Get dependency group by name."""

498

499

def has_dependency_group(self, name: str) -> bool:

500

"""Check if dependency group exists."""

501

``` { .api }

502

503

## Specialized Dependency Types

504

505

### DirectoryDependency

506

507

```python

508

class DirectoryDependency(Dependency):

509

"""Dependency on local directory containing a Python package."""

510

511

def __init__(

512

self,

513

name: str,

514

path: Path,

515

groups: Iterable[str] | None = None,

516

optional: bool = False,

517

develop: bool = False,

518

extras: Iterable[str] | None = None,

519

) -> None:

520

"""

521

Create directory dependency.

522

523

Args:

524

name: Package name

525

path: Path to directory containing package

526

groups: Dependency groups

527

optional: Whether dependency is optional

528

develop: Whether to install in development mode

529

extras: Package extras to enable

530

"""

531

532

@property

533

def path(self) -> Path:

534

"""Path to directory."""

535

536

@property

537

def develop(self) -> bool:

538

"""Whether to install in development mode."""

539

``` { .api }

540

541

### FileDependency

542

543

```python

544

class FileDependency(Dependency):

545

"""Dependency on local file (wheel or sdist)."""

546

547

def __init__(

548

self,

549

name: str,

550

path: Path,

551

groups: Iterable[str] | None = None,

552

optional: bool = False,

553

extras: Iterable[str] | None = None,

554

) -> None:

555

"""

556

Create file dependency.

557

558

Args:

559

name: Package name

560

path: Path to wheel or sdist file

561

groups: Dependency groups

562

optional: Whether dependency is optional

563

extras: Package extras to enable

564

"""

565

566

@property

567

def path(self) -> Path:

568

"""Path to file."""

569

``` { .api }

570

571

### URLDependency

572

573

```python

574

class URLDependency(Dependency):

575

"""Dependency on package downloadable from URL."""

576

577

def __init__(

578

self,

579

name: str,

580

url: str,

581

groups: Iterable[str] | None = None,

582

optional: bool = False,

583

extras: Iterable[str] | None = None,

584

) -> None:

585

"""

586

Create URL dependency.

587

588

Args:

589

name: Package name

590

url: URL to package archive

591

groups: Dependency groups

592

optional: Whether dependency is optional

593

extras: Package extras to enable

594

"""

595

596

@property

597

def url(self) -> str:

598

"""Package URL."""

599

``` { .api }

600

601

### VCSDependency

602

603

```python

604

class VCSDependency(Dependency):

605

"""Dependency on Version Control System repository."""

606

607

def __init__(

608

self,

609

name: str,

610

vcs: str,

611

source: str,

612

branch: str | None = None,

613

tag: str | None = None,

614

rev: str | None = None,

615

resolved_rev: str | None = None,

616

directory: str | None = None,

617

groups: Iterable[str] | None = None,

618

optional: bool = False,

619

develop: bool = False,

620

extras: Iterable[str] | None = None,

621

) -> None:

622

"""

623

Create VCS dependency.

624

625

Args:

626

name: Package name

627

vcs: Version control system ("git", "hg", "svn", "bzr")

628

source: Repository URL

629

branch: Branch name

630

tag: Tag name

631

rev: Specific revision/commit

632

resolved_rev: Resolved full revision hash

633

directory: Subdirectory within repository

634

groups: Dependency groups

635

optional: Whether dependency is optional

636

develop: Whether to install in development mode

637

extras: Package extras to enable

638

"""

639

640

@property

641

def vcs(self) -> str:

642

"""Version control system type."""

643

644

@property

645

def branch(self) -> str | None:

646

"""Branch name."""

647

648

@property

649

def tag(self) -> str | None:

650

"""Tag name."""

651

652

@property

653

def rev(self) -> str | None:

654

"""Revision/commit."""

655

656

@property

657

def develop(self) -> bool:

658

"""Whether to install in development mode."""

659

``` { .api }

660

661

## Dependency Groups

662

663

### DependencyGroup

664

665

```python

666

class DependencyGroup:

667

"""Container for related dependencies."""

668

669

def __init__(

670

self,

671

name: str,

672

dependencies: list[Dependency] | None = None,

673

optional: bool = False

674

) -> None:

675

"""

676

Create dependency group.

677

678

Args:

679

name: Group name (e.g., "main", "dev", "test")

680

dependencies: Initial dependencies

681

optional: Whether entire group is optional

682

"""

683

684

@property

685

def name(self) -> str:

686

"""Group name."""

687

688

@property

689

def dependencies(self) -> list[Dependency]:

690

"""Dependencies in this group."""

691

692

@property

693

def optional(self) -> bool:

694

"""Whether group is optional."""

695

696

def add_dependency(self, dependency: Dependency) -> None:

697

"""Add dependency to group."""

698

699

def remove_dependency(self, name: str) -> None:

700

"""Remove dependency by name."""

701

``` { .api }

702

703

### Group Constants

704

705

```python

706

MAIN_GROUP = "main" # Main dependency group identifier

707

``` { .api }

708

709

## Usage Examples

710

711

### Creating Various Dependency Types

712

713

```python

714

from pathlib import Path

715

from poetry.core.packages.dependency import Dependency

716

from poetry.core.constraints.version import parse_constraint

717

718

def create_dependencies():

719

"""Demonstrate creating different dependency types."""

720

721

# Regular PyPI dependency

722

requests_dep = Dependency("requests", "^2.25.0")

723

print(f"Regular: {requests_dep.name} {requests_dep.constraint}")

724

725

# Development dependency

726

pytest_dep = Dependency(

727

"pytest",

728

">=6.0.0",

729

groups=["dev"],

730

allows_prereleases=True

731

)

732

print(f"Dev: {pytest_dep.name} in {pytest_dep.groups}")

733

734

# Optional dependency with extras

735

optional_dep = Dependency(

736

"requests",

737

"^2.25.0",

738

optional=True,

739

extras=["security", "socks"]

740

)

741

print(f"Optional: {optional_dep.complete_name}")

742

743

# Dependency with environment marker

744

marker_dep = Dependency("pywin32", "*")

745

marker_dep.marker = "sys_platform == 'win32'"

746

print(f"Conditional: {marker_dep.name} when {marker_dep.marker}")

747

748

create_dependencies()

749

``` { .api }

750

751

### Creating from PEP 508 Strings

752

753

```python

754

from poetry.core.packages.dependency import Dependency

755

756

def pep508_examples():

757

"""Create dependencies from PEP 508 requirement strings."""

758

759

examples = [

760

"requests>=2.25.0",

761

"pytest>=6.0; python_version>='3.8'",

762

"sphinx[docs]>=3.0",

763

"mypackage[extra1,extra2]>=1.0,<2.0",

764

"pywin32>=200; sys_platform=='win32'",

765

]

766

767

for requirement in examples:

768

try:

769

dep = Dependency.create_from_pep_508(requirement)

770

print(f"✓ {requirement}")

771

print(f" -> {dep.name} {dep.constraint}")

772

if not dep.marker.is_any():

773

print(f" -> Marker: {dep.marker}")

774

if dep.features:

775

print(f" -> Features: {sorted(dep.features)}")

776

777

except Exception as e:

778

print(f"✗ {requirement}: {e}")

779

780

pep508_examples()

781

``` { .api }

782

783

### Working with Project Packages

784

785

```python

786

from poetry.core.packages.project_package import ProjectPackage

787

from poetry.core.packages.dependency import Dependency

788

789

def create_project():

790

"""Create and configure a project package."""

791

792

# Create project package

793

project = ProjectPackage("my-awesome-app", "1.0.0")

794

795

# Set metadata

796

project.description = "An awesome Python application"

797

project.authors = ["Developer <dev@example.com>"]

798

project.homepage = "https://github.com/user/my-awesome-app"

799

project.keywords = ["cli", "tool", "automation"]

800

801

# Add main dependencies

802

requests_dep = Dependency("requests", "^2.25.0")

803

click_dep = Dependency("click", ">=7.0")

804

project.add_dependency(requests_dep)

805

project.add_dependency(click_dep)

806

807

# Add development dependencies

808

pytest_dep = Dependency("pytest", "^6.0.0", groups=["dev"])

809

black_dep = Dependency("black", "^21.0.0", groups=["dev"])

810

project.add_dependency(pytest_dep)

811

project.add_dependency(black_dep)

812

813

# Print summary

814

print(f"Project: {project.name} v{project.version}")

815

print(f"Description: {project.description}")

816

print(f"Main dependencies: {len(project.requires)}")

817

print(f"Dev dependencies: {len(project.dev_requires)}")

818

819

# List dependencies

820

print("\nMain Dependencies:")

821

for dep in project.requires:

822

print(f" {dep.name}: {dep.constraint}")

823

824

print("\nDev Dependencies:")

825

for dep in project.dev_requires:

826

print(f" {dep.name}: {dep.constraint}")

827

828

create_project()

829

``` { .api }

830

831

### Specialized Dependencies

832

833

```python

834

from pathlib import Path

835

from poetry.core.packages.directory_dependency import DirectoryDependency

836

from poetry.core.packages.file_dependency import FileDependency

837

from poetry.core.packages.url_dependency import URLDependency

838

from poetry.core.packages.vcs_dependency import VCSDependency

839

840

def create_specialized_dependencies():

841

"""Create various specialized dependency types."""

842

843

# Local directory dependency

844

dir_dep = DirectoryDependency(

845

"local-lib",

846

Path("./libs/local-lib"),

847

develop=True

848

)

849

print(f"Directory: {dir_dep.name} from {dir_dep.path}")

850

851

# Local file dependency

852

file_dep = FileDependency(

853

"custom-wheel",

854

Path("./wheels/custom-1.0.0-py3-none-any.whl")

855

)

856

print(f"File: {file_dep.name} from {file_dep.path}")

857

858

# URL dependency

859

url_dep = URLDependency(

860

"archive-package",

861

"https://example.com/packages/archive-1.0.0.tar.gz"

862

)

863

print(f"URL: {url_dep.name} from {url_dep.url}")

864

865

# Git dependency

866

git_dep = VCSDependency(

867

"git-package",

868

"git",

869

"https://github.com/user/repo.git",

870

branch="develop",

871

directory="subpackage"

872

)

873

print(f"Git: {git_dep.name} from {git_dep.source_url}@{git_dep.branch}")

874

875

create_specialized_dependencies()

876

``` { .api }

877

878

### Dependency Analysis

879

880

```python

881

from poetry.core.packages.project_package import ProjectPackage

882

883

def analyze_dependencies(project: ProjectPackage):

884

"""Analyze project dependencies."""

885

886

print(f"Dependency Analysis for {project.name}")

887

print("=" * 50)

888

889

# Group analysis

890

all_groups = set()

891

for dep in project.all_requires:

892

all_groups.update(dep.groups)

893

894

print(f"Dependency groups: {sorted(all_groups)}")

895

896

# Count by group

897

for group in sorted(all_groups):

898

group_deps = [dep for dep in project.all_requires if group in dep.groups]

899

print(f" {group}: {len(group_deps)} dependencies")

900

901

# Source type analysis

902

source_types = {}

903

for dep in project.all_requires:

904

source_type = dep.source_type or "pypi"

905

source_types[source_type] = source_types.get(source_type, 0) + 1

906

907

print(f"\nBy source type:")

908

for source_type, count in source_types.items():

909

print(f" {source_type}: {count} dependencies")

910

911

# Optional dependencies

912

optional_deps = [dep for dep in project.all_requires if dep.optional]

913

print(f"\nOptional dependencies: {len(optional_deps)}")

914

915

# Dependencies with markers

916

marker_deps = [dep for dep in project.all_requires if not dep.marker.is_any()]

917

print(f"Conditional dependencies: {len(marker_deps)}")

918

919

# Dependencies with extras

920

extra_deps = [dep for dep in project.all_requires if dep.features]

921

print(f"Dependencies with extras: {len(extra_deps)}")

922

923

# Usage with a project

924

# analyze_dependencies(my_project)

925

``` { .api }