poetry
Definitive guidelines for using Poetry for Python dependency management, packaging, and project structure, emphasizing modern best practices as of 2025.
Le skill
# poetry Best Practices
Poetry is the de-facto standard for modern Python project management. This guide outlines our team's definitive best practices for leveraging Poetry's full power, ensuring reproducible builds, streamlined development, and robust packaging.
## 1. Project Initialization & Structure
Always start new projects with `poetry new` to establish a correct `pyproject.toml` and project structure.
### ✅ GOOD: Use `src` layout by default
Poetry 2.1+ defaults to the `src` layout, which prevents common import issues and improves package isolation.
```bash
# Initialize a new project with the recommended src layout
poetry new my-project
```
This creates:
```
my-project/
├── pyproject.toml
├── README.md
├── my_project/ # Your package source code lives here
│ └── __init__.py
└── tests/
└── __init__.py
└── test_my_project.py
```
## 2. `pyproject.toml` Configuration
`pyproject.toml` is your project's single source of truth.
### ✅ GOOD: Prioritize PEP 621 `[project]` section
Poetry 2.0+ fully supports PEP 621. Use the `[project]` section for standard metadata (name, version, description, authors, etc.). Only use `[tool.poetry]` for Poetry-specific features not covered by PEP 621.
**❌ BAD: Using deprecated `tool.poetry` fields**
```toml
# pyproject.toml
[tool.poetry]
name = "my-project" # Deprecated in favor of [project].name
version = "0.1.0" # Deprecated in favor of [project].version
description = "A bad example"
authors = ["Bad Developer <bad@example.com>"]
```
**✅ GOOD: Using `[project]` for standard metadata**
```toml
# pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
description = "A good example using PEP 621"
authors = [{name = "Good Developer", email = "good@example.com"}]
readme = "README.md"
requires-python = ">=3.9,<4.0" # Always specify Python version
license = { text = "MIT" } # Or { file = "LICENSE" }
keywords = ["python", "poetry", "best-practices"]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
[tool.poetry]
# Only Poetry-specific configurations here, e.g., packages, scripts
packages = [{ include = "my_project" }] # Required for src layout
```
### ✅ GOOD: Explicitly declare `[build-system]`
Always define your build backend explicitly, even if using `poetry-core`. This ensures consistent builds and prepares for alternative backends.
```toml
# pyproject.toml
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
```
### ✅ GOOD: Use alternative build backends when appropriate
For projects with Rust extensions (`maturin`) or other specific needs, declare the alternative build backend.
```toml
# pyproject.toml
[build-system]
requires = ["maturin>=0.8.1,<0.9"]
build-backend = "maturin"
```
## 3. Dependency Management
### ✅ GOOD: Add dependencies with explicit constraints
Always use `poetry add` and specify PEP 440-compliant version constraints. Avoid unconstrained dependencies (`*`) to prevent unexpected breakage.
**❌ BAD: Unconstrained or overly broad dependencies**
```bash
poetry add requests # Adds requests with ^ constraint, but better to be explicit
poetry add my-lib@* # Never do this
```
**✅ GOOD: Explicit, well-defined dependency constraints**
```bash
poetry add requests@^2.30.0 # Caret (compatible with 2.30.0 but not 3.0.0)
poetry add rich@~13.0 # Tilde (compatible with 13.0.x but not 13.1.0)
poetry add pandas@">=2.0.0,<2.1.0" # Specific range
```
### ✅ GOOD: Group development dependencies
Isolate development tools (linters, formatters, test runners) into a `dev` group. This keeps production environments lean.
```bash
poetry add --group dev pytest black isort flake8 mypy
```
```toml
# pyproject.toml
[project]
# ...
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
black = "^23.0"
isort = "^5.0"
flake8 = "^6.0"
mypy = "^1.0"
```
### ✅ GOOD: Commit `poetry.lock`
Always commit `poetry.lock` to ensure reproducible environments across all development, CI/CD, and production systems.
```bash
git add pyproject.toml poetry.lock
git commit -m "feat: Add initial project setup"
```
**❌ BAD: Manually editing `poetry.lock`**
Never manually edit `poetry.lock`. It's generated by Poetry and should only be updated via `poetry add`, `poetry remove`, or `poetry update`.
## 4. Virtual Environments & Execution
### ✅ GOOD: Use `pipx` for Poetry installation
Install Poetry itself in an isolated environment using `pipx` to avoid conflicts with project dependencies.
```bash
pipx install poetry
pipx upgrade poetry # To update Poetry
```
### ✅ GOOD: Activate environments with `poetry env activate`
Use `poetry env activate` to get the shell command for activating the virtual environment. This is more robust than the deprecated `poetry shell`.
```bash
# In your shell, to activate for the current session:
eval $(poetry env activate)
# Or, if you need to specify a Python version:
poetry python install 3.11 # (Experimental)
poetry env use 3.11
eval $(poetry env activate)
```
### ✅ GOOD: Execute commands with `poetry run`
For one-off commands or scripts, use `poetry run` to execute them within the project's virtual environment without explicit activation.
```bash
poetry run pytest
poetry run black .
```
## 5. Code Quality & Automation
### ✅ GOOD: Integrate pre-commit hooks
Enforce code quality standards (formatting, linting, typing) on every commit using `pre-commit` hooks.
1. **Install `pre-commit`**:
```bash
poetry add --group dev pre-commit
poetry run pre-commit install
```
2. **Configure `.pre-commit-config.yaml`**:
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 23.12.1
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
args: [--ignore-missing-imports]
```
## 6. Packaging & Publishing
### ✅ GOOD: Build packages with `poetry build`
Use `poetry build` to create `sdist` and `wheel` distributions. Ensure your `pyproject.toml`'s `[build-system]` is correctly configured.
```bash
poetry build
```
### ✅ GOOD: Publish to PyPI or private repositories
Use `poetry publish` to distribute your package. Configure credentials securely.
```bash
# Publish to PyPI (default)
poetry publish --build # Build and publish in one step
# Publish to a private repository
poetry publish -r my-private-repo --build
```
## 7. Performance & Troubleshooting
### ✅ GOOD: Update dependencies regularly
Run `poetry update` to refresh dependencies, but always review changelogs and run tests before committing.
```bash
poetry update
```
### ✅ GOOD: Clear cache for resolution issues
If dependency resolution is slow or problematic, clear Poetry's cache.
```bash
poetry cache clear --all pypi
```
Comment l’installer
1. Open the tool and start a new conversation, project or template. 2. Paste the text below wherever the tool keeps standing instructions — usually called system prompt, instructions, or persona. 3. Save it so it applies to every run rather than a single message.