Context
I found this SO question "Is requirements.txt still needed when using pyproject.toml" and have a different use case compared to the one described by the above question. Instead of opening an extra SO question with the same title, I decided to add this answer as kind of a "long comment", supporting users in similar situations.
In my use case I do not install my code as a library/package. Therefore, I do not need both, pinned and unpinned versions.
Unfortunately, the option --only-deps has not been implemented by pip, yet.
I already got rid of extra config files for pytest
, pylint
, ... and use pyproject.toml as a central configuration file in combination with a GitLab CI pipeline (gitlab-ci.yml). => Why should I still use an extra, redundant requirements.txt
file if not only for historical reasons?
My Solution:
I got rid of the extra requirements.txt
by defining the requirements inside pyproject.toml
and installing them with
pip install -e .[dev]
or just
pip install .[dev]
The corresponding sections in pyproject.toml
(min example):
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = 'my_dummy_project_name'
version = '0.0.1'
requires-python = ">=3.11.0"
dependencies = [
'cryptography==41.0.1',
]
[project.optional-dependencies]
lining = [
'pylint==2.17.4'
]
formatting = [
'black[d]==23.3.0'
]
dev = ['my_dummy_project_name[linting, formatting]']
On the path to that solution I faced several issues.
a) Since I do not want to install my code as a package but only its dependencies, I first tried without name
and version
. However, those properties are mandatory if one wants to use the install
commands. Without name
and version
you'll get corresponding error messages.
b) I also tried without specifying a build-backend
. Depending on the python version, you will get an error message and/or setuptools
will be used as default build-backend
. The setuptools
has the disadvantage, that it creates an unwanted directory ./src/micat.egg-info
. My workaround of specifying hatchling
as build-backend
solved all those issues for me (even if I currently do not explicitly need hatchling).
c) Python console commands like pytest
, pylint
might not be found by the GitLab pipline if they are installed this way.
Instead of
pytest src
you might need to use
python -m pytest src
(If you know how to fix this, e.g. with some hatchling
option, please let me know.)
d) If you prefer a shorter variant
pip install .
you could reorganize pyproject.toml
and list all your requirements in a single dependencies
list. However, I would suggest to keep the runtime- and dev-time- dependencies separated.
e) If you would prefer the even shorter variant (similar to npm install
)
pip install
see feature request https://github.com/pypa/pip/issues/12100
f) An alternative approach would be a custom script, reading requirements information from pyproject.toml, see https://github.com/pypa/pip/issues/11440#issuecomment-1615211774.
Related:
https://github.com/pypa/packaging.python.org/issues/685
https://peps.python.org/pep-0631/
https://stackoverflow.com/a/75503961/2876079
https://pip.pypa.io/en/stable/cli/pip_install/#options
https://github.com/winpython/winpython/issues/1128
How to write a minimally working pyproject.toml file that can install packages?