Open-source project
python-poetry/poetry avatar
python-poetry/poetry

Poetry: one pyproject.toml, a core pinned to ==2.5.0, and three dependencies with no upper bound

Python packaging and dependency management made easy

34,305 stars2,523 forksPythonMIT

At a glance

What is it?
Poetry is the MIT-licensed Python packaging and dependency manager that replaces setup.py, requirements.txt, setup.cfg, MANIFEST.in and Pipfile with a single pyproject.toml. The repository itself is the best source of constraints: version 2.5.1 pins poetry-core to an exact patch, requires Python 3.10, and leaves three calendar-versioned dependencies unclamped.
Who is it for?
Poetry fits a team that wants one declarative file for metadata and dependencies, a committed lock file, and a build backend other tools already understand through PEP 517. It does not fit a team whose downstream consumers only know how to run pip install -r requirements.txt, since the lock format is not a requirements file and the conversion needs poetry-plugin-export.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Five files collapse into one pyproject.toml, with a PEP 517 backend named in it

The claim in the README is specific: Poetry replaces setup.py, requirements.txt, setup.cfg, MANIFEST.in and Pipfile with a pyproject.toml based project format. The sample project shows what that file carries, and the first lines are the ones that decide whether anything else on your machine can build your package:

toml
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

[project]
name = "my-package"
version = "0.1.0"
description = "The description of the package"
readme = "README.md"

license = "MIT"
license-files = ["LICENSE"]

A build backend named in a standard table is the part with the longest reach. pip can install the project, any PEP 517 front end can build it, and none of them need Poetry installed. The [project] table itself is the standard metadata table, and the sample even notes that keywords become tags on the package index, which is the mapping a reader has to know about before wondering why their keyword list is not showing up.

The sample project allows Python 3.9 while Poetry 2.5.1 will not run below 3.10

Two requires-python lines exist in this repository and they do not agree, and the difference is not an error. The example project declares requires-python = ">=3.9" with a comment explaining that there is no upper bound for package metadata, so that one line is about who is allowed to install your package, not about what builds it. Poetry's own pyproject.toml declares requires-python = ">=3.10,<4.0", which is about the machine running the tool. The gap between them is the design: a package built by Poetry 2.5.1 can still target 3.9 users, and 3.9 users install it with plain pip and never touch Poetry. The upper bound on Poetry itself is also a real constraint, since a project that wants to support 3.9 and newer has to run its build tooling on a machine that is not 3.9. Nothing in the README explains the split, so a reader who copies the example and reads only the project table will assume Poetry runs on whatever the package supports.

A 2.5.1 release pins its own build backend to ==2.5.0

Poetry's dependency list opens with poetry-core (==2.5.0), an exact equality, while every other entry uses a range. Version 2.5.1 of the frontend therefore ships against patch 2.5.0 of the library that actually does the building and metadata work. The reason is visible two entries later in the same list: cachecontrol, cleo, dulwich, installer, keyring, platformdirs, virtualenv and the rest are all ranged, so the exact pin on one dependency is a deliberate choice about a component the project controls. Two consequences. A contributor cannot bump poetry-core in a development checkout without breaking the install, so testing a new core means a branch. And a downstream project reading the sample gets a different rule: poetry-core>=2.0.0,<3.0.0, which lets a package build against any 2.x core. The frontend is strict about its own core and deliberately loose about yours.

Three dependencies are unclamped because they version by calendar date

Three lines in the dependency list carry the same comment. packaging (>=24.2) is annotated that PEP 639 support was added in 24.2, and packaging uses calver so the version is unclamped. trove-classifiers (>=2022.5.19) repeats the calver note. pbs-installer[download,install] (>=2025.6.10) says the same thing a third time. An unclamped upper bound on a calendar-versioned package is a standing upgrade risk rather than a style choice: those projects release on a date, not on a compatibility promise, so a new pbs-installer can land in a developer's environment on a Tuesday and change behaviour without Poetry cutting a release. The comment tells you the constraint exists. It does not tell you what breaks, and the README does not document a policy for pinning these in a development environment. Anyone maintaining the project has to discover the answer by watching that install fail.

Platform markers split the dev install, so two machines are never quite equal

Two entries in Poetry's own dependency list carry environment markers. xattr (>=1.0.0,<2.0.0) is gated on sys_platform == 'darwin', so a macOS contributor gets a filesystem extended-attribute library that nobody on Linux installs. tomli (>=2.0.1,<3.0.0) is gated on python_version < '3.11', because the standard library grew a TOML parser and the backport is only needed below that. Both are ordinary packaging practice and both have a practical edge for a project team. A bug that only reproduces on macOS, or only on Python 3.10, will not show up on a Linux CI runner above 3.11, and the contributor who has the unusual combination is the only one who can find it. The rest of the stack is similarly opinionated: dulwich is a pure-Python Git implementation, keyring keeps credentials in the OS keychain, findpython and virtualenv build the environment, and pbs-installer downloads a managed interpreter. That is a lot of machinery for one command.

Installation is a script URL, and the CI advice lives in the documentation

The installation section is four sentences long. Poetry supports multiple installation methods, one of which is a script at install.python-poetry.org, and everything else, advanced usage of that script, alternate install methods, and CI best practices, is deferred to the installation documentation under python-poetry.org/docs. There is no pip line, no pinned version, and no command to copy, which means a reader pinning their tooling has nothing here to pin to. The same pattern holds for the rest of the project. Documentation is offered for the current version, for the development branch, and for recently out of support versions, which implies a support window exists without saying how long it is. Contributors are pointed at a suggested issues list for poetry and poetry-core, and the README calls the project a large, complex one always in need of contributors. Useful signposts, thin pages.

poetry-plugin-export is the bridge to a requirements.txt world

The Related Projects section names the boundaries of the tool. poetry-core is the PEP 517 build system and the dependency-free core of the Poetry frontend, which is what makes a build possible without Poetry installed. poetry-plugin-export converts projects and lock files into foreign formats such as requirements.txt. poetry-plugin-bundle installs projects and lock files into external formats such as virtual environments. Read those three together and the operating model is clear. Inside your own repository, the pyproject.toml and the committed poetry.lock are the source of truth. Outside it, a consumer who only speaks requirements.txt needs the export plugin, and a deployment that wants a ready environment needs the bundle plugin. Neither is built in. The repository root holds poetry.lock, a .pre-commit-config.yaml and a .pre-commit-hooks.yaml, which is a manifest other projects can consume as a pre-commit hook, plus a CITATION.cff and a CHANGELOG.md. The lock file is committed, and that is a promise about reproducibility your CI has to honour.

Editorial conclusion

Poetry fits a team that wants one declarative file for metadata and dependencies, a committed lock file, and a build backend other tools already understand through PEP 517. It does not fit a team whose downstream consumers only know how to run pip install -r requirements.txt, since the lock format is not a requirements file and the conversion needs poetry-plugin-export. Two things to check first. Read the requires-python line in your own project, because the example in the README allows 3.9 while Poetry 2.5.1 itself will not run below 3.10. Then read the exact poetry-core pin in a checkout before you build anything, because that pin is the version your build backend resolves to and it moves on its own schedule.

Frequently asked questions

how to install poetry

The README points to an installation script at install.python-poetry.org and to the installation documentation at python-poetry.org/docs, which it says also covers advanced script usage, alternate install methods and CI best practices. No version is named in the README itself, and the repository has no other install command to copy.

how to use poetry python

You declare everything in a pyproject.toml, which the README says replaces setup.py, requirements.txt, setup.cfg, MANIFEST.in and Pipfile. The sample names poetry-core>=2.0.0,<3.0.0 as the build requirement and poetry.core.masonry.api as the build backend, so any PEP 517 front end can build the project.

how to use poetry to install packages

Poetry is described as declaring, managing and installing the dependencies of a Python project so you have the right stack everywhere. The README does not show the commands for adding or installing a single package, that content is in the documentation at python-poetry.org/docs, while the dependency declarations themselves appear in the pyproject.toml sample.

how to use poetry env activate

The README does not document the environment commands. It covers declaring, managing and installing dependencies, and points to python-poetry.org/docs for everything else, including the installation documentation and the general documentation pages for the current version, the development branch and recently out of support versions.

how to use poetry instead of pip

The README states that Poetry replaces setup.py, requirements.txt, setup.cfg, MANIFEST.in and Pipfile with a pyproject.toml based project format, which is the difference in artefact rather than in resolver. The project declares a PEP 517 build backend, so pip remains able to install and build what Poetry produces, and poetry-plugin-export converts a project or lock file back into requirements.txt for consumers that need that format.

how to install poetry in windows

The README gives no Windows-specific instruction. It names an installation script at install.python-poetry.org as one of several supported methods and defers the rest, including alternate install methods and CI best practices, to the installation documentation under python-poetry.org/docs.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/python-poetry-poetry.svg)](https://hysenlabs.com/projects/python-poetry-poetry)