---
title: "FAQ"
draft: false
type: docs
layout: single

menu:
  docs:
    weight: 110
---

# FAQ

### Why is the dependency resolution process slow?

While the dependency resolver at the heart of Poetry is highly optimized and
should be fast enough for most cases, with certain sets of dependencies
it can take time to find a valid solution.

This is due to the fact that not all libraries on PyPI have properly declared their metadata
and, as such, they are not available via the PyPI JSON API. At this point, Poetry has no choice
but to download the packages and inspect them to get the necessary information. This is an expensive
operation, both in bandwidth and time, which is why it seems this is a long process.

At the moment there is no way around it. However, if you notice that Poetry
is downloading many versions of a single package, you can lessen the workload
by constraining that one package in your pyproject.toml more narrowly. That way
Poetry does not have to sift through so many versions of it, which may speed up
the locking process considerably in some cases.

{{% note %}}
Once Poetry has cached the releases' information on your machine, the dependency resolution process
will be much faster.
{{% /note %}}

### What kind of versioning scheme does Poetry use for itself?

Poetry uses "major.minor.micro" version identifiers as mentioned in
[PEP 440](https://peps.python.org/pep-0440/#final-releases).

Version bumps are done similar to Python's versioning:
* A major version bump (incrementing the first number) is only done for breaking changes
  if a deprecation cycle is not possible and many users have to perform some manual steps
  to migrate from one version to the next one.
* A minor version bump (incrementing the second number) may include new features as well
  as new deprecations and drop features deprecated in an earlier minor release.
* A micro version bump (incrementing the third number) usually only includes bug fixes.
  Deprecated features will not be dropped in a micro release.

### Why does Poetry not adhere to semantic versioning?

Because of its large user base, even small changes not considered relevant by most users
can turn out to be a breaking change for some users in hindsight.
Sticking to strict [semantic versioning](https://semver.org) and (almost) always bumping
the major version instead of the minor version does not seem desirable
since the minor version will not carry any meaning anymore.

### Are unbound version constraints a bad idea?

A version constraint without an upper bound such as `*` or `>=3.4` will allow updates to any future version of the dependency.
This includes major versions breaking backward compatibility.

Once a release of your package is published, you cannot tweak its dependencies anymore in case a dependency breaks BC
– you have to do a new release but the previous one stays broken.
(Users can still work around the broken dependency by restricting it by themselves.)

To avoid such issues you can define an upper bound on your constraints,
which you can increase in a new release after testing that your package is compatible
with the new major version of your dependency.

For example instead of using `>=3.4` you can use `^3.4` which allows all versions `<4.0`.
The `^` operator works very well with libraries following [semantic versioning](https://semver.org).

However, when defining an upper bound, users of your package are not able to update
a dependency beyond the upper bound even if it does not break anything
and is fully compatible with your package.
You have to release a new version of your package with an increased upper bound first.

If your package will be used as a library in other packages, it might be better to avoid
upper bounds and thus unnecessary dependency conflicts (unless you already know for sure
that the next release of the dependency will break your package).
If your package will be used as an application, it might be worth to define an upper bound.

### Is tox supported?

**Yes**. Provided that you are using `tox` >= 4, you can use it in combination with
the PEP 517 compliant build system provided by Poetry. (With tox 3, you have to set the
[isolated build](https://tox.wiki/en/3.27.1/config.html#conf-isolated_build) option.)

So, in your `pyproject.toml` file, add this section if it does not already exist:

```toml
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
```

`tox` can be configured in multiple ways. It depends on what should be the code under test and which dependencies
should be installed.

#### Use case #1
```ini
[tox]

[testenv]
deps =
    pytest
commands =
    pytest tests/ --import-mode importlib
```

`tox` will create an `sdist` package of the project and uses `pip` to install it in a fresh environment.
Thus, dependencies are resolved by `pip`.

#### Use case #2
```ini
[tox]

[testenv]
allowlist_externals = poetry
commands_pre =
    poetry install --no-root --sync
commands =
    poetry run pytest tests/ --import-mode importlib
```

`tox` will create an `sdist` package of the project and uses `pip` to install it in a fresh environment.
Thus, dependencies are resolved by `pip` in the first place. But afterward we run Poetry,
 which will install the locked dependencies into the environment.

#### Use case #3
```ini
[tox]

[testenv]
skip_install = true
allowlist_externals = poetry
commands_pre =
    poetry install
commands =
    poetry run pytest tests/ --import-mode importlib
```

`tox` will not do any install. Poetry installs all the dependencies and the current package in editable mode.
Thus, tests are running against the local files and not the built and installed package.

#### Note about credentials

Note that `tox` does not forward the environment variables of your current shell session by default.
This may cause Poetry to not be able to install dependencies in the `tox` environments if you have configured
credentials using the system keyring on Linux systems or using environment variables in general.
You can use the `passenv` [configuration option](https://tox.wiki/en/latest/config.html#passenv) to forward the
required variables explicitly or `passenv = "*"` to forward all of them.
Linux systems may require forwarding the `DBUS_SESSION_BUS_ADDRESS` variable to allow access to the system keyring,
though this may vary between desktop environments.

Alternatively, you can disable the keyring completely:

```bash
poetry config keyring.enabled false
```

Be aware that this will cause Poetry to write passwords to plaintext config files.
You will need to set the credentials again after changing this setting.

### Is Nox supported?

Use the [`nox-poetry`](https://github.com/cjolowicz/nox-poetry) package to install locked versions of
dependencies specified in `poetry.lock` into [Nox](https://nox.thea.codes/en/stable/) sessions.

### I don't want Poetry to manage my virtual environments. Can I disable it?

While Poetry automatically creates virtual environments to always work isolated
from the global Python installation, there are rare scenarios where the use a Poetry managed
virtual environment is not possible or preferred.

In this case, you can disable this feature by setting the `virtualenvs.create` setting to `false`:

```bash
poetry config virtualenvs.create false
```

{{% warning %}}
The recommended best practice, including when installing an application within a container, is to make
use of a virtual environment. This can also be managed by another tool.

The Poetry team strongly encourages the use of a virtual environment.
{{% /warning %}}

### Why is Poetry telling me that the current project's supported Python range is not compatible with one or more packages' Python requirements?

Unlike `pip`, Poetry doesn't resolve for just the Python in the current environment. Instead it makes sure that a dependency
is resolvable within the given Python version range in `pyproject.toml`.

Assume you have the following `pyproject.toml`:

```toml
[tool.poetry.dependencies]
python = "^3.7"
```

This means your project aims to be compatible with any Python version >=3.7,<4.0. Whenever you try to add a dependency
whose Python requirement doesn't match the whole range Poetry will tell you this, e.g.:

```
The current project's supported Python range (>=3.7.0,<4.0.0) is not compatible with some of the required packages Python requirement:
    - scipy requires Python >=3.7,<3.11, so it will not be installable for Python >=3.11,<4.0.0
```

Usually you will want to match the supported Python range of your project with the upper bound of the failing dependency.
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?

This is done to be compliant with the broader Python ecosystem.

For example, if Poetry builds a distribution for a project that uses a version that is not valid according to
[PEP 440](https://peps.python.org/pep-0440), third party tools will be unable to parse the version correctly.


### Poetry busts my Docker cache because it requires me to COPY my source files in before installing 3rd party dependencies

By default, running `poetry install ...` requires you to have your source files present (both the "root" package and any directory path dependencies you might have).
This interacts poorly with Docker's caching mechanisms because any change to a source file will make any layers (subsequent commands in your Dockerfile) re-run.
For example, you might have a Dockerfile that looks something like this:

```text
FROM python
COPY pyproject.toml poetry.lock .
COPY src/ ./src
RUN pip install poetry && poetry install --only main
```

As soon as *any* source file changes, the cache for the `RUN` layer will be invalidated, which forces all 3rd party dependencies (likely the slowest step out of these) to be installed again if you changed any files in `src/`.

To avoid this cache busting you can split this into two steps:

1. Install 3rd party dependencies.
2. Copy over your source code and install just the source code.

This might look something like this:

```text
FROM python
COPY pyproject.toml poetry.lock .
RUN pip install poetry && poetry install --only main --no-root --no-directory
COPY src/ ./src
RUN poetry install --only main
```

The two key options we are using here are `--no-root` (skips installing the project source) and `--no-directory` (skips installing any local directory path dependencies, you can omit this if you don't have any).
[More information on the options available for `poetry install`]({{< relref "cli#install" >}}).


### My requests are timing out!

Poetry's default HTTP request timeout is 15 seconds, the same as `pip`.
Similar to `PIP_REQUESTS_TIMEOUT`, the **experimental** environment variable `POETRY_REQUESTS_TIMEOUT`
can be set to alter this value.


### How do I migrate an existing Poetry project using `tools.poetry` section to use the new `project` section (PEP 621)?

{{% note %}}
Poetry `>=2.0.0` should seamlessly support both `tools.poetry` section only configuration as well using the `project` section. This
lets you decide when and if you would like to migrate to using the `project` section as [described by PyPA](https://packaging.python.org/en/latest/specifications/pyproject-toml/#declaring-project-metadata-the-project-table).

See documentation on [the `pyproject.toml` file]({{< relref "pyproject" >}}), for information specific to Poetry.
{{% /note %}}

Due to the nature of this change some manual changes to your `pyproject.toml` file is unavoidable in order start using the `project` section. The following tabs
show a transition example. If you wish to retain Poetry's richer [dependency specification]({{< relref "dependency-specification" >}}) syntax it is recommended that
you use dynamic dependencies as described in the second tab below.

{{< tabs tabTotal="3" tabID1="migrate-pep621-old" tabName1="Original" tabID2="migrate-pep621-new-dynamic" tabName2="Using Dynamic Dependencies" tabID3="migrate-pep621-new-static" tabName3="Using Static Dependencies">}}

{{< tab tabID="migrate-pep621-old" >}}

```toml
[tool.poetry]
name = "foobar"
version = "0.1.0"
description = ""
authors = ["Baz Qux <baz.qux@example.com>"]
readme = "README.md"
packages = [{ include = "awesome", from = "src" }]
include = [{ path = "tests", format = "sdist" }]
homepage = "https://python-foobar.org/"
repository = "https://github.com/python-foobar/foobar"
documentation = "https://python-foobar.org/docs"
keywords = ["packaging", "dependency", "foobar"]
classifiers = [
    "Topic :: Software Development :: Build Tools",
    "Topic :: Software Development :: Libraries :: Python Modules",
]

[tool.poetry.scripts]
foobar = "foobar.console.application:main"

[tool.poetry.dependencies]
python = "^3.13"
httpx = "^0.28.1"

[tool.poetry.group.dev.dependencies]
pre-commit = ">=2.10"

[tool.poetry.group.test.dependencies]
pytest = ">=8.0"

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

{{< /tab >}}

{{< tab tabID="migrate-pep621-new-static" >}}

```toml
[project]
name = "foobar"
version = "0.1.0"
description = ""
authors = [
    { name = "Baz Qux", email = "baz.qux@example.com" }
]
readme = "README.md"
requires-python = ">=3.13"
keywords = ["packaging", "dependency", "foobar"]
# classifiers property is dynamic because we want to create Python classifiers automatically
# dependencies are dynamic because we want to keep Poetry's rich dependency definition format
dynamic = ["classifiers", "dependencies"]

[project.urls]
homepage = "https://python-foobar.org/"
repository = "https://github.com/python-foobar/foobar"
documentation = "https://python-foobar.org/docs"

[project.scripts]
foobar = "foobar.console.application:main"

[tool.poetry]
requires-poetry = ">=2.0"
packages = [{ include = "foobar", from = "src" }]
include = [{ path = "tests", format = "sdist" }]
classifiers = [
    "Topic :: Software Development :: Build Tools",
    "Topic :: Software Development :: Libraries :: Python Modules",
]

[tool.poetry.dependencies]
httpx = "^0.28.1"

[tool.poetry.group.dev.dependencies]
pre-commit = ">=2.10"

[tool.poetry.group.test.dependencies]
pytest = ">=8.0"

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

{{< /tab >}}

{{< tab tabID="migrate-pep621-new-static" >}}

```toml
[project]
name = "foobar"
version = "0.1.0"
description = ""
authors = [
    { name = "Baz Qux", email = "baz.qux@example.com" }
]
readme = "README.md"
requires-python = ">=3.13"
keywords = ["packaging", "dependency", "foobar"]
# classifiers property is dynamic because we want to create Python classifiers automatically
dynamic = ["classifiers"]
dependencies = [
    "httpx (>=0.28.1,<0.29.0)"
]

[project.urls]
homepage = "https://python-foobar.org/"
repository = "https://github.com/python-foobar/foobar"
documentation = "https://python-foobar.org/docs"

[project.scripts]
foobar = "foobar.console.application:main"

[tool.poetry]
requires-poetry = ">=2.0"
packages = [{ include = "foobar", from = "src" }]
include = [{ path = "tests", format = "sdist" }]
classifiers = [
    "Topic :: Software Development :: Build Tools",
    "Topic :: Software Development :: Libraries :: Python Modules",
]

[tool.poetry.group.dev.dependencies]
pre-commit = ">=2.10"

[tool.poetry.group.test.dependencies]
pytest = ">=8.0"

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

{{< /tab >}}

{{< /tabs >}}

{{% note %}}
- The `classifiers` property is dynamic to allow Poetry to create and manage Python classifiers in accordance with supported Python version.
- The `python` dependency, in this example was replaced with `project.requires-python`. However, note that if you need an upper bound on supported Python versions refer to the documentation [here]({{< relref "pyproject#requires-python" >}}).
- The [`requires-poetry`]({{< relref "pyproject#requires-poetry" >}}) is added to the `tools.poetry` section.
{{% /note %}}
