Search code examples
setuptoolspypipython-packagingpython-poetrypyproject.toml

What's the difference between the [tool.poetry] and [project] tables in pyproject.toml?


Context

So, I'm trying to create a new Python package following this tutorial: https://packaging.python.org/en/latest/tutorials/packaging-projects/

As the tutorial says, in my pyproject.toml I should have this structure:

[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
  { name="Example Author", email="author@example.com" },
]
description = "A small example package"

but when I created this file with poetry init, it created this structure:

[tool.poetry]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
  { name="Example Author", email="author@example.com" },
]
description = "A small example package"

The main difference between these two is the [project] instead of [tool.poetry] section header. I also see, that poetry can't do anything with the project, when there is no [tool.poetry] section in pyproject.toml


So my questions are:

  1. What are the differences between these two?

  2. Should I have only one or both at the same time in my pyproject.toml? And in case I should keep both, what should it contain?

  3. In case there should be only [tool.poetry], do I need to follow the same rules for the content and sub-sections as for [project]? So for example [project.urls] would be renamed to [tool.poetry.urls]?

  4. What is the best future-proof choice for publishing on PyPI? Or are there no difference?

  5. Is changing the [build-system] from poetry-core to setuptools a good idea? Or I should keep poetry-core?


Solution

  • 1. What are the differences between these two?

    The [project] section is standardized (also known as PEP-621). But Poetry is older than the creation of this standard, so it started by using its own section [tool.poetry]. Poetry added support for the standardized [project] in its version 2.0.0 which was released in January 2025, see the announcement blog for Poetry v2.0.0.

    The differences between the two are relatively small on the surface, they are basically different notations for the same package metadata. The most notable difference (the one you should keep an eye on) is regarding the notation for declaring the dependencies. This is where the divergence is the most critical.

    2. Should I have only one or both at the same time in my pyproject.toml? And in case I should keep both, what should it contain?

    You can combine both. See Poetry's documentation on pyproject.toml for the details. Maybe a good approach would be to place everything you can in [project] as it is standardized and provides better compatibility with the rest of the ecosystem, and leave the rest for [tool.poetry]. For example, if you prefer Poetry's notation for dependencies then you can leave the dependencies out of [project] and keep them in [tool.poetry] instead

    3. In case there should be only [tool.poetry], do I need to follow the same rules for the content and sub-sections as for [project]? So for example [project.urls] would be renamed to [tool.poetry.urls]?

    This is not exactly one-to-one equivalent, there are some differences. Follow Poetry's documentation and the [project] specification.

    4. What is the best future-proof choice for publishing on PyPI? Or are there no difference?

    This is for you (and your team) to decide. One could argue that [project] offers better compatibility with the rest of Python packaging ecosystem as it is a standard. On the other hand [tool.poetry] might have more features and better integration with Poetry itself.

    5. Is changing the [build-system] from poetry-core to setuptools a good idea? Or I should keep poetry-core?

    Poetry the "development workflow tool" does not allow using any other build back-end than poetry-core. So if you want to keep using Poetry for your project, you have no choice but to keep using poetry-core as build back-end.