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

factory-core.mddocs/

0

# Factory and Core Poetry Functionality

1

2

The factory and core Poetry modules provide central orchestration for creating and managing Poetry project instances. The Factory class serves as the main entry point for creating Poetry objects from project configurations.

3

4

## Core Imports

5

6

```python

7

from poetry.core.factory import Factory

8

from poetry.core.poetry import Poetry

9

from poetry.core.packages.project_package import ProjectPackage

10

from poetry.core.pyproject.toml import PyProjectTOML

11

``` { .api }

12

13

## Factory Class

14

15

The Factory class provides static and instance methods for creating Poetry projects and validating configurations.

16

17

### Factory.__init__

18

19

```python

20

class Factory:

21

"""Factory class to create various elements needed by Poetry."""

22

23

def __init__(self) -> None:

24

"""Initialize Factory instance."""

25

``` { .api }

26

27

### create_poetry

28

29

```python

30

def create_poetry(

31

self,

32

cwd: Path | None = None,

33

with_groups: bool = True

34

) -> Poetry:

35

"""

36

Create a Poetry instance from pyproject.toml configuration.

37

38

Args:

39

cwd: Working directory to search for pyproject.toml. If None, uses current directory.

40

with_groups: Whether to load dependency groups. Set False for build operations.

41

42

Returns:

43

Poetry instance representing the project

44

45

Raises:

46

RuntimeError: If Poetry configuration is invalid

47

PyProjectError: If pyproject.toml is missing or malformed

48

ValidationError: If project schema validation fails

49

50

Example:

51

>>> factory = Factory()

52

>>> poetry = factory.create_poetry()

53

>>> print(f"Project: {poetry.package.name}")

54

Project: my-package

55

56

>>> # Create from specific directory

57

>>> poetry = factory.create_poetry(Path("/path/to/project"))

58

59

>>> # Skip dependency groups for faster loading

60

>>> poetry = factory.create_poetry(with_groups=False)

61

"""

62

``` { .api }

63

64

### get_package (Class Method)

65

66

```python

67

@classmethod

68

def get_package(cls, name: str, version: str) -> ProjectPackage:

69

"""

70

Create a ProjectPackage instance with given name and version.

71

72

Args:

73

name: Package name

74

version: Package version string

75

76

Returns:

77

ProjectPackage instance

78

79

Example:

80

>>> package = Factory.get_package("my-package", "1.0.0")

81

>>> print(f"{package.name} v{package.version}")

82

my-package v1.0.0

83

"""

84

``` { .api }

85

86

### configure_package (Class Method)

87

88

```python

89

@classmethod

90

def configure_package(

91

cls,

92

package: ProjectPackage,

93

pyproject: PyProjectTOML,

94

root: Path,

95

with_groups: bool = True

96

) -> None:

97

"""

98

Configure package metadata, dependencies, and Poetry-specific settings.

99

100

Args:

101

package: ProjectPackage instance to configure

102

pyproject: PyProject TOML configuration

103

root: Project root directory path

104

with_groups: Whether to configure dependency groups

105

106

Raises:

107

ValidationError: If configuration is invalid

108

109

Note:

110

This method modifies the package in-place, setting:

111

- Basic metadata (description, authors, etc.)

112

- Dependencies and dependency groups

113

- Build configuration

114

- Entry points and scripts

115

- Package includes/excludes

116

"""

117

``` { .api }

118

119

### create_dependency (Class Method)

120

121

```python

122

@classmethod

123

def create_dependency(

124

cls,

125

name: str,

126

constraint: DependencyConstraint,

127

groups: list[str] | None = None,

128

root_dir: Path | None = None

129

) -> Dependency:

130

"""

131

Create various types of dependencies from constraint specifications.

132

133

Args:

134

name: Dependency name

135

constraint: Version constraint or dependency specification

136

groups: Dependency groups (e.g., ["dev", "test"])

137

root_dir: Root directory for resolving relative paths

138

139

Returns:

140

Appropriate Dependency subclass instance:

141

- Dependency: Regular version-based dependency

142

- VCSDependency: Git/VCS dependency

143

- FileDependency: Local file dependency

144

- DirectoryDependency: Local directory dependency

145

- URLDependency: URL-based dependency

146

147

Example:

148

>>> # Version constraint

149

>>> dep = Factory.create_dependency("requests", "^2.25.0")

150

151

>>> # Git dependency

152

>>> dep = Factory.create_dependency("mypackage", {

153

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

154

... "branch": "main"

155

... })

156

157

>>> # Local path dependency

158

>>> dep = Factory.create_dependency("local-pkg", {"path": "./libs/local"})

159

"""

160

``` { .api }

161

162

### validate (Class Method)

163

164

```python

165

@classmethod

166

def validate(

167

cls,

168

toml_data: dict[str, Any],

169

strict: bool = False

170

) -> dict[str, list[str]]:

171

"""

172

Validate Poetry configuration against JSON schemas.

173

174

Args:

175

toml_data: Raw TOML data from pyproject.toml

176

strict: Whether to treat warnings as errors

177

178

Returns:

179

Dictionary containing validation results:

180

{

181

"errors": ["List of error messages"],

182

"warnings": ["List of warning messages"]

183

}

184

185

Example:

186

>>> from poetry.core.pyproject.toml import PyProjectTOML

187

>>> pyproject = PyProjectTOML(Path("pyproject.toml"))

188

>>> result = Factory.validate(pyproject.data)

189

>>> if result["errors"]:

190

... print("Configuration errors:", result["errors"])

191

>>> if result["warnings"]:

192

... print("Configuration warnings:", result["warnings"])

193

"""

194

``` { .api }

195

196

### locate (Class Method)

197

198

```python

199

@classmethod

200

def locate(cls, cwd: Path | None = None) -> Path:

201

"""

202

Locate pyproject.toml file in current or parent directories.

203

204

Args:

205

cwd: Directory to start search from. If None, uses current directory.

206

207

Returns:

208

Path to the pyproject.toml file

209

210

Raises:

211

RuntimeError: If pyproject.toml cannot be found

212

213

Example:

214

>>> pyproject_path = Factory.locate()

215

>>> print(f"Found: {pyproject_path}")

216

Found: /path/to/project/pyproject.toml

217

218

>>> # Search from specific directory

219

>>> pyproject_path = Factory.locate(Path("/some/subdirectory"))

220

"""

221

``` { .api }

222

223

## Poetry Class

224

225

The Poetry class represents a complete Poetry project context with configuration, package information, and build dependencies.

226

227

### Poetry.__init__

228

229

```python

230

class Poetry:

231

def __init__(

232

self,

233

file: Path,

234

local_config: dict[str, Any],

235

package: ProjectPackage,

236

pyproject_type: type[PyProjectTOML] = PyProjectTOML,

237

) -> None:

238

"""

239

Initialize Poetry instance.

240

241

Args:

242

file: Path to pyproject.toml file

243

local_config: Poetry configuration from [tool.poetry] section

244

package: ProjectPackage instance

245

pyproject_type: PyProjectTOML class (for testing/customization)

246

"""

247

``` { .api }

248

249

### Properties

250

251

#### pyproject

252

253

```python

254

@property

255

def pyproject(self) -> PyProjectTOML:

256

"""

257

PyProject TOML configuration object.

258

259

Returns:

260

PyProjectTOML instance with full project configuration

261

262

Example:

263

>>> poetry = Factory().create_poetry()

264

>>> config = poetry.pyproject

265

>>> print(f"Build system: {config.build_system.build_backend}")

266

"""

267

``` { .api }

268

269

#### pyproject_path

270

271

```python

272

@property

273

def pyproject_path(self) -> Path:

274

"""

275

Path to the pyproject.toml file.

276

277

Returns:

278

Absolute path to pyproject.toml

279

280

Example:

281

>>> poetry = Factory().create_poetry()

282

>>> print(f"Config file: {poetry.pyproject_path}")

283

Config file: /path/to/project/pyproject.toml

284

"""

285

``` { .api }

286

287

#### package

288

289

```python

290

@property

291

def package(self) -> ProjectPackage:

292

"""

293

Project package instance containing metadata and dependencies.

294

295

Returns:

296

ProjectPackage with all package information

297

298

Example:

299

>>> poetry = Factory().create_poetry()

300

>>> pkg = poetry.package

301

>>> print(f"{pkg.name} v{pkg.version}")

302

>>> print(f"Dependencies: {len(pkg.requires)}")

303

"""

304

``` { .api }

305

306

#### is_package_mode

307

308

```python

309

@property

310

def is_package_mode(self) -> bool:

311

"""

312

Whether the project is in package mode.

313

314

Returns:

315

True if in package mode (builds installable package),

316

False if in application mode (no package building)

317

318

Example:

319

>>> poetry = Factory().create_poetry()

320

>>> if poetry.is_package_mode:

321

... print("This project builds a package")

322

... else:

323

... print("This is an application project")

324

"""

325

``` { .api }

326

327

#### local_config

328

329

```python

330

@property

331

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

332

"""

333

Local Poetry configuration dictionary.

334

335

Returns:

336

Dictionary containing [tool.poetry] section configuration

337

338

Example:

339

>>> poetry = Factory().create_poetry()

340

>>> config = poetry.local_config

341

>>> print(f"Name: {config.get('name')}")

342

>>> print(f"Version: {config.get('version')}")

343

"""

344

``` { .api }

345

346

#### build_system_dependencies

347

348

```python

349

@property

350

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

351

"""

352

Build system dependencies from [build-system] section.

353

354

Returns:

355

List of Dependency objects required for building

356

357

Example:

358

>>> poetry = Factory().create_poetry()

359

>>> build_deps = poetry.build_system_dependencies

360

>>> for dep in build_deps:

361

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

362

"""

363

``` { .api }

364

365

### Methods

366

367

#### get_project_config

368

369

```python

370

def get_project_config(self, config: str, default: Any = None) -> Any:

371

"""

372

Get project-specific configuration value.

373

374

Args:

375

config: Configuration key to retrieve

376

default: Default value if key not found

377

378

Returns:

379

Configuration value or default

380

381

Example:

382

>>> poetry = Factory().create_poetry()

383

>>> cache_dir = poetry.get_project_config("cache-dir", "~/.cache")

384

>>> print(f"Cache directory: {cache_dir}")

385

"""

386

``` { .api }

387

388

## Type Definitions

389

390

```python

391

from typing import Any, Mapping, Union

392

from pathlib import Path

393

from poetry.core.packages.dependency import Dependency

394

395

# Dependency constraint types

396

DependencyConstraint = Union[str, Mapping[str, Any]]

397

DependencyConfig = Mapping[

398

str, Union[list[DependencyConstraint], DependencyConstraint]

399

]

400

401

# Configuration types

402

LocalConfig = dict[str, Any]

403

ValidationResult = dict[str, list[str]]

404

``` { .api }

405

406

## Complete Usage Examples

407

408

### Creating and Inspecting a Poetry Project

409

410

```python

411

from pathlib import Path

412

from poetry.core.factory import Factory

413

414

def analyze_project(project_path: Path) -> None:

415

"""Analyze a Poetry project and print key information."""

416

417

factory = Factory()

418

419

try:

420

# Create Poetry instance

421

poetry = factory.create_poetry(project_path)

422

423

# Project information

424

pkg = poetry.package

425

print(f"Project: {pkg.name}")

426

print(f"Version: {pkg.version}")

427

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

428

print(f"Package mode: {poetry.is_package_mode}")

429

430

# Dependencies

431

print(f"\nDependencies ({len(pkg.requires)}):")

432

for dep in pkg.requires:

433

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

434

435

# Development dependencies

436

if pkg.has_dependency_group("dev"):

437

dev_deps = pkg.dependency_group("dev").dependencies

438

print(f"\nDev Dependencies ({len(dev_deps)}):")

439

for dep in dev_deps:

440

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

441

442

# Build system

443

build_deps = poetry.build_system_dependencies

444

print(f"\nBuild Dependencies ({len(build_deps)}):")

445

for dep in build_deps:

446

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

447

448

except Exception as e:

449

print(f"Error analyzing project: {e}")

450

451

# Usage

452

analyze_project(Path("./my-poetry-project"))

453

``` { .api }

454

455

### Configuration Validation

456

457

```python

458

from pathlib import Path

459

from poetry.core.factory import Factory

460

from poetry.core.pyproject.toml import PyProjectTOML

461

462

def validate_project_config(project_path: Path, strict: bool = False) -> bool:

463

"""Validate Poetry project configuration."""

464

465

try:

466

# Load pyproject.toml

467

pyproject_path = Factory.locate(project_path)

468

pyproject = PyProjectTOML(pyproject_path)

469

470

# Validate configuration

471

result = Factory.validate(pyproject.data, strict=strict)

472

473

# Report results

474

if result["errors"]:

475

print("Configuration Errors:")

476

for error in result["errors"]:

477

print(f" ❌ {error}")

478

479

if result["warnings"]:

480

print("Configuration Warnings:")

481

for warning in result["warnings"]:

482

print(f" ⚠️ {warning}")

483

484

# Return validation status

485

is_valid = not result["errors"]

486

if strict:

487

is_valid = is_valid and not result["warnings"]

488

489

print(f"\nConfiguration is {'valid' if is_valid else 'invalid'}")

490

return is_valid

491

492

except Exception as e:

493

print(f"Validation failed: {e}")

494

return False

495

496

# Usage

497

is_valid = validate_project_config(Path("./my-project"), strict=True)

498

``` { .api }

499

500

### Creating Dependencies Programmatically

501

502

```python

503

from poetry.core.factory import Factory

504

from pathlib import Path

505

506

def create_various_dependencies():

507

"""Demonstrate creating different types of dependencies."""

508

509

# Regular version dependencies

510

requests_dep = Factory.create_dependency("requests", "^2.25.0")

511

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

512

513

# Git dependency

514

git_dep = Factory.create_dependency("mypackage", {

515

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

516

"branch": "main",

517

"extras": ["dev"]

518

})

519

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

520

521

# Local path dependency

522

path_dep = Factory.create_dependency("local-lib", {

523

"path": "../shared-lib",

524

"develop": True

525

})

526

print(f"Path: {path_dep.name} from {path_dep.source_url}")

527

528

# URL dependency

529

url_dep = Factory.create_dependency("archive-pkg", {

530

"url": "https://example.com/package-1.0.0.tar.gz"

531

})

532

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

533

534

# Development dependency

535

dev_dep = Factory.create_dependency(

536

"pytest",

537

"^6.0.0",

538

groups=["dev", "test"]

539

)

540

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

541

542

create_various_dependencies()

543

``` { .api }

544

545

### Custom Project Creation

546

547

```python

548

from pathlib import Path

549

from poetry.core.factory import Factory

550

from poetry.core.packages.project_package import ProjectPackage

551

552

def create_custom_project() -> None:

553

"""Create a custom Poetry project programmatically."""

554

555

factory = Factory()

556

557

# Create base package

558

package = factory.get_package("my-custom-app", "0.1.0")

559

560

# Set metadata

561

package.description = "A custom application"

562

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

563

package.homepage = "https://github.com/user/my-custom-app"

564

565

# Add dependencies

566

requests_dep = factory.create_dependency("requests", "^2.25.0")

567

click_dep = factory.create_dependency("click", ">=7.0")

568

569

package.add_dependency(requests_dep)

570

package.add_dependency(click_dep)

571

572

# Add development dependencies

573

pytest_dep = factory.create_dependency("pytest", "^6.0.0", groups=["dev"])

574

package.add_dependency(pytest_dep)

575

576

print(f"Created project: {package.name}")

577

print(f"Dependencies: {[d.name for d in package.requires]}")

578

print(f"Dev dependencies: {[d.name for d in package.dev_requires]}")

579

580

create_custom_project()

581

``` { .api }