Skip to content

Commit

Permalink
add support for PEP 621: explain the difference between `project.depe…
Browse files Browse the repository at this point in the history
…ndencies` and `tool.poetry.dependencies`, update examples (python-poetry#9135)
  • Loading branch information
radoering committed Aug 30, 2024
1 parent 8ff3d27 commit 18541ae
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 42 deletions.
27 changes: 21 additions & 6 deletions docs/basic-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,18 @@ The `pyproject.toml` file is what is the most important here. This will orchestr
your project and its dependencies. For now, it looks like this:

```toml
[tool.poetry]
[project]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = ["Sébastien Eustace <sebastien@eustace.io>"]
authors = [
{name = "Sébastien Eustace", email = "sebastien@eustace.io"}
]
readme = "README.md"
packages = [{include = "poetry_demo"}]
requires-python = ">=3.8"

[tool.poetry.dependencies]
python = "^3.7"
[tool.poetry]
packages = [{include = "poetry_demo"}]


[build-system]
Expand Down Expand Up @@ -122,7 +124,20 @@ In the [pyproject section]({{< relref "pyproject" >}}) you can see which fields

### Specifying dependencies

If you want to add dependencies to your project, you can specify them in the `tool.poetry.dependencies` section.
If you want to add dependencies to your project, you can specify them in the
`project` or `tool.poetry.dependencies` section.
See the [Dependency specification]({{< relref "dependency-specification" >}})
for more information.

```toml
[project]
# ...
dependencies = [
"pendulum (>=2.1,<3.0)"
]
```

or

```toml
[tool.poetry.dependencies]
Expand Down
171 changes: 170 additions & 1 deletion docs/dependency-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,87 @@ menu:
Dependencies for a project can be specified in various forms, which depend on the type
of the dependency and on the optional constraints that might be needed for it to be installed.

## `project.dependencies` and `tool.poetry.dependencies`

Prior Poetry 2.0, dependencies had to be declared in the `tool.poetry.dependencies`
section of the `pyproject.toml` file.

```toml
[tool.poetry.dependencies]
requests = "^2.13.0"
```

With Poetry 2.0, you should consider using the `project.dependencies` section instead.

```toml
[project]
# ...
dependencies = [
"requests (>=2.23.0,<3.0.0)"
]
```

While dependencies in `tool.poetry.dependencies` are specified using toml tables,
dependencies in `project.dependencies` are specified as strings according
to [PEP 508](https://peps.python.org/pep-0508/).

In many cases, `tool.poetry.dependencies` can be replaced with `project.dependencies`.
However, there are some cases where you might still need to use `tool.poetry.dependencies`.
For example, if you want to define additional information that is not required for building
but only for locking (for example an explicit source), you can enrich dependency
information in the `tool.poetry` section.

```toml
[project]
# ...
dependencies = [
"requests>=2.13.0",
]

[tool.poetry.dependencies]
requests = { source = "private-source" }
```

When both are specified, `project.dependencies` are used for metadata when building the project,
`tool.poetry.dependencies` is only used to enrich `project.dependencies` for locking.

Alternatively, you can add `dependencies` to `dynamic` and define your dependencies
completely in the `tool.poetry` section. Using only the `tool.poetry` section might
make sense in non-package mode when you will not build an sdist or a wheel.

```toml
[project]
# ...
dynamic = [ "dependencies" ]

[tool.poetry.dependencies]
requests = { version = ">=2.13.0", source = "private-source" }
```

{{% note %}}
Another use case for `tool.poetry.dependencies` are relative path dependencies
since `project.dependencies` only support absolute paths.
{{% /note %}}

{{% note %}}
Only main dependencies can be specified in the `project` section.
Other [Dependency groups]({{< relref "managing-dependencies#dependency-groups" >}})
must still be specified in the `tool.poetry` section.
{{% /note %}}

## Version constraints

{{% warning %}}
Some of the following constraints can only be used in `tool.poetry.dependencies` and not in `project.dependencies`.
When using `poetry add` such constraints are automatically converted into an equivalent constraint.
{{% /warning %}}

### Caret requirements

{{% warning %}}
Not supported in `project.dependencies`.
{{% /warning %}}

**Caret requirements** allow [SemVer](https://semver.org/) compatible updates to a specified version. An update is allowed if the new version number does not modify the left-most non-zero digit in the major, minor, patch grouping. For instance, if we previously ran `poetry add requests@^2.13.0` and wanted to update the library and ran `poetry update requests`, poetry would update us to version `2.14.0` if it was available, but would not update us to `3.0.0`. If instead we had specified the version string as `^0.1.13`, poetry would update to `0.1.14` but not `0.2.0`. `0.0.x` is not considered compatible with any other version.

Here are some more examples of caret requirements and the versions that would be allowed with them:
Expand All @@ -34,6 +111,10 @@ Here are some more examples of caret requirements and the versions that would be

### Tilde requirements

{{% warning %}}
Not supported in `project.dependencies`.
{{% /warning %}}

**Tilde requirements** specify a minimal version with some ability to update.
If you specify a major, minor, and patch version or only a major and minor version, only patch-level changes are allowed.
If you only specify a major version, then minor- and patch-level changes are allowed.
Expand Down Expand Up @@ -131,6 +212,16 @@ the minimum information you need to specify is the location of the repository wi
requests = { git = "https://github.com/requests/requests.git" }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"requests @ git+https://github.com/requests/requests.git"
]
```

Since we haven’t specified any other information,
Poetry assumes that we intend to use the latest commit on the `main` branch
to build our project.
Expand All @@ -149,6 +240,18 @@ flask = { git = "https://github.com/pallets/flask.git", rev = "38eb5d3b" }
numpy = { git = "https://github.com/numpy/numpy.git", tag = "v0.13.2" }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"requests @ git+https://github.com/requests/requests.git@next",
"flask @ git+https://github.com/pallets/flask.git@38eb5d3b",
"numpy @ git+https://github.com/numpy/numpy.git@v0.13.2",
]
```

In cases where the package you want to install is located in a subdirectory of the VCS repository, you can use the `subdirectory` option, similarly to what [pip](https://pip.pypa.io/en/stable/topics/vcs-support/#url-fragments) provides:

```toml
Expand Down Expand Up @@ -212,6 +315,16 @@ my-package = { path = "../my-package/", develop = false }
my-package = { path = "../my-package/dist/my-package-0.1.0.tar.gz" }
```

In the `project` section, you can only use absolute paths:

```toml
[project]
# ...
dependencies = [
"my-package @ file:///absolute/path/to/my-package/dist/my-package-0.1.0.tar.gz"
]
```

{{% note %}}
Before poetry 1.1 directory path dependencies were installed in editable mode by default. You should set the `develop` attribute explicitly,
to make sure the behavior is the same for all poetry versions.
Expand All @@ -228,6 +341,16 @@ you can use the `url` property:
my-package = { url = "https://example.com/my-package-0.1.0.tar.gz" }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"my-package @ https://example.com/my-package-0.1.0.tar.gz"
]
```

with the corresponding `add` call:

```bash
Expand All @@ -244,6 +367,16 @@ for a dependency as shown here.
gunicorn = { version = "^20.1", extras = ["gevent"] }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"gunicorn[gevent] (>=20.1,<21.0)"
]
```

{{% note %}}
These activate extra defined for the dependency, to configure an optional dependency
for extras in your project refer to [`extras`]({{< relref "pyproject#extras" >}}).
Expand Down Expand Up @@ -275,6 +408,10 @@ In this example, we expect `foo` to be configured correctly. See [using a privat
for further information.
{{% /note %}}

{{% note %}}
It is not possible to define source dependencies in the `project` section.
{{% /note %}}

## Python restricted dependencies

You can also specify that a dependency should be installed only for specific Python versions:
Expand All @@ -286,7 +423,18 @@ tomli = { version = "^2.0.1", python = "<3.11" }

```toml
[tool.poetry.dependencies]
pathlib2 = { version = "^2.2", python = "^3.2" }
pathlib2 = { version = "^2.2", python = "^3.9" }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"tomli (>=2.0.1,<3.11) ; python_version < '3.11'",
"pathlib2 (>=2.2,<3.0) ; python_version >= '3.9' and python_version < '4.0'"
]
```

## Using environment markers
Expand All @@ -300,6 +448,16 @@ via the `markers` property:
pathlib2 = { version = "^2.2", markers = "python_version <= '3.4' or sys_platform == 'win32'" }
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"pathlib2 (>=2.2,<3.0) ; python_version <= '3.4' or sys_platform == 'win32'"
]
```

## Multiple constraints dependencies

Sometimes, one of your dependency may have different version ranges depending
Expand All @@ -317,6 +475,17 @@ foo = [
]
```

or in the `project` section:

```toml
[project]
# ...
dependencies = [
"foo (<=1.9) ; python_version >= '3.6' and python_version < '3.8'",
"foo (>=2.0,<3.0) ; python_version >= '3.8'"
]
```

{{% note %}}
The constraints **must** have different requirements (like `python`)
otherwise it will cause an error when resolving dependencies.
Expand Down
12 changes: 12 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,18 @@ Usually you will want to match the supported Python range of your project with t
Alternatively you can tell Poetry to install this dependency [only for a specific range of Python versions]({{< relref "dependency-specification#multiple-constraints-dependencies" >}}),
if you know that it's not needed in all versions.

If you do not want to set an upper bound in the metadata when building your project,
you can omit it in the `project` section and only set it in `tool.poetry.dependencies`:

```toml
[project]
# ...
requires-python = ">=3.7" # used for metadata when building the project

[tool.poetry.dependencies]
python = ">=3.7,<3.11" # used for locking dependencies
```


### Why does Poetry enforce PEP 440 versions?

Expand Down
26 changes: 24 additions & 2 deletions docs/managing-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ type: docs

# Managing dependencies

{{% note %}}
Since Poetry 2.0, main dependencies can be specified in `project.dependencies`
instead of `tool.poetry.dependencies`.
See [Dependency specification]({{< relref "dependency-specification" >}}) for more information.
Only main dependencies can be specified in the `project` section.
Other groups must still be specified in the `tool.poetry` section.
{{% /note %}}

## Dependency groups

Poetry provides a way to **organize** your dependencies by **groups**. For instance, you might have
Expand All @@ -37,7 +45,22 @@ the dependencies logically.
{{% /note %}}

{{% note %}}
The dependencies declared in `tool.poetry.dependencies` are part of an implicit `main` group.
The dependencies declared in `project.dependencies` respectively `tool.poetry.dependencies`
are part of an implicit `main` group.
{{% /note %}}

```toml
[project]
# ...
dependencies = [ # main dependency group
"httpx",
"pendulum",
]

[tool.poetry.group.test.dependencies]
pytest = "^6.0.0"
pytest-mock = "*"
```

```toml
[tool.poetry.dependencies] # main dependency group
Expand All @@ -48,7 +71,6 @@ pendulum = "*"
pytest = "^6.0.0"
pytest-mock = "*"
```
{{% /note %}}

{{% note %}}
Dependency groups, other than the implicit `main` group, must only contain dependencies you need in your development
Expand Down
12 changes: 6 additions & 6 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ The plugin package must depend on Poetry
and declare a proper [plugin]({{< relref "pyproject#plugins" >}}) in the `pyproject.toml` file.

```toml
[tool.poetry]
[project]
name = "my-poetry-plugin"
version = "1.0.0"

# ...
[tool.poetry.dependencies]
python = "^3.7"
poetry = "^1.2"
requires-python = ">=3.7"
dependencies = [
"poetry (>=1.2,<2.0)",
]

[tool.poetry.plugins."poetry.plugin"]
[project.entry-points."poetry.plugin"]
demo = "poetry_demo_plugin.plugin:MyPlugin"
```

Expand Down
Loading

0 comments on commit 18541ae

Please sign in to comment.