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?