poetry — Cursor rule: what it does, how to install
Cursor rule for Python projects using modern Poetry standards. It enforces PEP 621 configuration, dependency groups, and the src package layout.
.cursor/rules/poetry.mdcWhat poetry does
This rule guides Cursor when generating or editing Python packages managed by Poetry. It enforces standards introduced in Poetry 2.0 and 2.1. The AI defaults to a src layout for package sources to isolate imports cleanly. Standard project metadata must live inside the PEP 621 [project] table, while [tool.poetry] stays reserved for build-specific keys.
Dependencies must include strict PEP 440 constraints rather than open wildcards. Tools like test runners or linters belong exclusively in the dev dependency group. Environment activation relies on eval $(poetry env activate) because poetry shell is deprecated. Single scripts run via poetry run.
Any legacy Poetry configurations will be flagged for refactoring. The rule also mandates an explicit [build-system] definition and standard pre-commit hook configurations.
What it helps with
- migrate pyproject.toml metadata to the PEP 621 standard
- set up package directory structure using the src layout
- isolate test and linting utilities into a dev group
- enforce strict PEP 440 dependency version constraints
Example prompts for the agent
- Create a new Python package using Poetry and the
srclayout. - Update
pyproject.tomlto move package metadata into PEP 621[project]. - Add
pytestandmypyto the development dependency group.
How to install poetry
Manually: put the files in place
.cursor/rules/poetry.mdcFrontmatter: description, globs, alwaysApply
Manually: put the files in place
.claude/rules/poetry.mdThe paths frontmatter field limits the files: move globs from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.github/instructions/poetry.instructions.mdThe applyTo field sets which files it applies to: move globs from the source into applyTo
Manually: put the files in place
.devin/rules/poetry.mdManually: put the files in place
.clinerules/poetry.mdStep by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules
Questions about poetry
How to install the poetry rule in Cursor?
Create the file .cursor/rules/poetry.mdc in your project root and paste the rule content there. Cursor will apply it automatically to all files matching **/*.py.
What does this rule enforce?
It enforces modern Poetry conventions, including PEP 621 metadata tables, src directory layout, explicit build systems, and dependency groups.
How does it activate the virtual environment?
The rule avoids the deprecated poetry shell command. Instead, it directs you to run eval $(poetry env activate) or execute commands directly with poetry run.
Source text
poetry.mdc · CC0-1.0
---
description: Definitive guidelines for using Poetry for Python dependency management, packaging, and project structure, emphasizing modern best practices as of 2025.
globs: **/*.py
---
# 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 <[email protected]>"]
```
**✅ 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 = "[email protected]"}]
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
```
© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc