Skip to content

Commit 95efd0e

Browse files
committed
Read constraints from constraints.txt
... and fallback to ``requirements.txt.in`` as the former name better matches the purpose of the file.
1 parent cb1d070 commit 95efd0e

File tree

5 files changed

+42
-23
lines changed

5 files changed

+42
-23
lines changed

README.rst

+12-12
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ To update one or more dependencies to the latest allowed version, run:
119119
If you need to add some dependencies from VCS references (e.g. when a library
120120
with a patch you need is not available as a release on a package index), add
121121
the dependency as usual in your project, then add the VCS reference to a file
122-
named ``requirements.txt.in`` like this::
122+
named ``constraints.txt`` like this::
123123

124124
DEPENDENCYNAME @ git+https://g.c/org/project@branch
125125

@@ -129,7 +129,7 @@ reference pinned at the exact commit that was installed (you need pip version
129129
the same branch, simply use ``pip-df sync --update DEPENDENCYNAME``.
130130

131131
When, later again, your branch is merged upstream and the project has published
132-
a release, remove the line from ``requirements.txt.in`` and run ``pip-df sync
132+
a release, remove the line from ``constraints.txt`` and run ``pip-df sync
133133
--update DEPENDENCYNAME`` to update to the latest released version.
134134

135135
How to
@@ -173,11 +173,11 @@ Refreshing all pinned dependencies.
173173
``pip-df sync --update-all``. This is equivalent to removing
174174
``requirements.txt`` then running ``pip-df sync``. This is also roughly
175175
equivalent to reinstalling in an empty virtualenv with ``pip install -e . -c
176-
requirements.txt.in`` then running ``pip freeze > requirements.txt``.
176+
constraints.txt`` then running ``pip freeze > requirements.txt``.
177177

178178
Using another package index than PyPI.
179179

180-
Create a file named ``requirements.txt.in`` in your project root, and add
180+
Create a file named ``constraints.txt`` in your project root, and add
181181
pip options to it, such as ``--extra-index-url`` or ``--find-links``. You
182182
can add any option that `pip supports in requirements files
183183
<https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format>`_.
@@ -189,14 +189,14 @@ Installing dependencies from VCS.
189189
it. Assume for instance your project depends on the ``packaging`` library
190190
and you want to install a pull request you made to it. To do so, make sure
191191
``packaging`` is declared as a regular dependency of your project. Then
192-
add the VCS reference in ``requirements.txt.in`` like so::
192+
add the VCS reference in ``constraints.txt`` like so::
193193

194194
packaging @ git+https://github.com/you/packaging@your-branch
195195

196196
Then run ``pip-df sync --update packaging`` to install from the branch and
197197
pin the exact commit in ``requirements.txt`` for reproducibility. When
198198
upstream merges your PR and cuts a release, you can simply remove the line
199-
from ``requirements.txt.in`` and run ``pip-df sync --update packaging`` to
199+
from ``constraints.txt`` and run ``pip-df sync --update packaging`` to
200200
refresh to the latest released version.
201201

202202
Working with extras.
@@ -212,16 +212,16 @@ Working with extras.
212212
FAQ
213213
---
214214

215-
What should I put in ``requirements.txt.in``? Should I add all my dependencies
215+
What should I put in ``constraints.txt``? Should I add all my dependencies
216216
there?
217217

218-
``requirements.txt.in`` is optional. The dependencies of your project must be
218+
``constraints.txt`` is optional. The dependencies of your project must be
219219
declared primarily in ``pyproject.toml`` (or the legacy ``setup.py/setup.cfg``).
220-
``requirements.txt.in`` may contain additional constraints if needed, such as version
220+
``constraints.txt`` may contain additional constraints if needed, such as version
221221
constraints on indirect dependencies that you don't control, or VCS links for
222222
dependencies that you need to install from VCS source.
223223

224-
I have added a constraint in ``requirements.txt.in`` but ``pip-df sync`` does
224+
I have added a constraint in ``constraints.txt`` but ``pip-df sync`` does
225225
not honor it. What is going on?
226226

227227
``pip-df sync`` always gives priority to versions pinned in ``requirements.txt``,
@@ -243,7 +243,7 @@ not honor it. What is going on?
243243
How can I pass options to pip?
244244

245245
The most reliable and repeatable way to pass options to pip is to add them
246-
in ``requirements.txt.in``. The pip documentation lists `options that are
246+
in ``constraints.txt``. The pip documentation lists `options that are
247247
allowed in requirements files
248248
<https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format>`_.
249249
Global options can also be set in the pip configuration file or passed via
@@ -321,7 +321,7 @@ pip-df sync
321321
322322
Install/reinstall the project. Install/update dependencies to the latest
323323
allowed version according to pinned dependencies in requirements.txt or
324-
constraints in requirements.txt.in. On demand update of dependencies to to
324+
constraints in constraints.txt. On demand update of dependencies to to
325325
the latest version that matches constraints. Optionally uninstall unneeded
326326
dependencies.
327327

news/59.feature

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Read constraints from ``constraints.txt`` first and fallback to ``requirements.txt.in``
2+
as the former name better matches the purpose of the file.

src/pip_deepfreeze/__main__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def sync(
7777
7878
Install/reinstall the project. Install/update dependencies to the
7979
latest allowed version according to pinned dependencies in
80-
requirements.txt or constraints in requirements.txt.in. On demand
80+
requirements.txt or constraints in constraints.txt/requirements.txt.in. On demand
8181
update of dependencies to to the latest version that matches
8282
constraints. Optionally uninstall unneeded dependencies.
8383
"""

src/pip_deepfreeze/sync.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@ def _req_line_sort_key(req_line: str) -> str:
3636
return req_name
3737

3838

39+
def _constraints_path(project_root: Path) -> Path:
40+
constraints_txt = project_root / "constraints.txt"
41+
if not constraints_txt.is_file():
42+
# fallback to requirements.txt.in if it exists, for backward compatibility
43+
requirements_txt_in = project_root / "requirements.txt.in"
44+
if requirements_txt_in.is_file():
45+
log_debug(
46+
"Reading constraints and pip options "
47+
"from 'requirements.txt.in'. "
48+
"Consider renaming it to 'constraints.txt' "
49+
"as this name better describes the purpose of the file."
50+
)
51+
return requirements_txt_in
52+
return constraints_txt
53+
54+
3955
def sync(
4056
python: str,
4157
upgrade_all: bool,
@@ -48,7 +64,7 @@ def sync(
4864
) -> None:
4965
project_name = get_project_name(python, project_root)
5066
project_name_with_extras = make_project_name_with_extras(project_name, extras)
51-
constraints_path = project_root / "requirements.txt.in"
67+
constraints_path = _constraints_path(project_root)
5268
# upgrade project and its dependencies, if needed
5369
merged_constraints_path = get_temp_path_in_dir(
5470
dir=project_root, prefix="requirements.", suffix=".txt.df"
@@ -83,7 +99,8 @@ def sync(
8399
print("# frozen requirements generated by pip-deepfreeze", file=f)
84100
# output pip options in main requirements only
85101
if not extra and constraints_path.exists():
86-
# XXX can we avoid this second parse of requirements.txt.in?
102+
# XXX can we avoid this second parse of
103+
# constraints.txt/requirements.txt.in?
87104
for parsed_req_line in parse_req_file(
88105
str(constraints_path),
89106
reqs_only=False,

tests/test_sync.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
def test_sync(virtualenv_python, testpkgs, tmp_path):
14-
(tmp_path / "requirements.txt.in").write_text(
14+
(tmp_path / "constraints.txt").write_text(
1515
textwrap.dedent(
1616
f"""\
1717
--pre
@@ -48,7 +48,7 @@ def test_sync(virtualenv_python, testpkgs, tmp_path):
4848

4949

5050
def test_sync_normalization(virtualenv_python, testpkgs, tmp_path):
51-
(tmp_path / "requirements.txt.in").write_text(
51+
(tmp_path / "constraints.txt").write_text(
5252
textwrap.dedent(
5353
f"""\
5454
--no-index
@@ -158,7 +158,7 @@ def test_sync_editable_dep(virtualenv_python, tmp_path):
158158
"""
159159
)
160160
)
161-
constraints = tmp_path / "requirements.txt.in"
161+
constraints = tmp_path / "constraints.txt"
162162
constraints.write_text(
163163
"-e git+https://github.com/PyPA/pip-test-package#egg=pip-test-package\n"
164164
)
@@ -189,7 +189,7 @@ def test_sync_uninstall(virtualenv_python, tmp_path, testpkgs):
189189
)
190190
)
191191
(tmp_path / "setup.cfg").write_text("[metadata]\nname = foobar\n") # for perf
192-
in_reqs = tmp_path / "requirements.txt.in"
192+
in_reqs = tmp_path / "constraints.txt"
193193
in_reqs.write_text(f"--no-index\n-f {testpkgs}")
194194
sync(
195195
virtualenv_python,
@@ -261,7 +261,7 @@ def test_sync_update_new_dep(virtualenv_python, testpkgs, tmp_path):
261261
)
262262
)
263263
(tmp_path / "setup.cfg").write_text("[metadata]\nname = theproject\n") # for perf
264-
(tmp_path / "requirements.txt.in").write_text(
264+
(tmp_path / "constraints.txt").write_text(
265265
textwrap.dedent(
266266
f"""\
267267
--no-index
@@ -309,7 +309,7 @@ def test_sync_update_all_new_dep(virtualenv_python, testpkgs, tmp_path):
309309
)
310310
)
311311
(tmp_path / "setup.cfg").write_text("[metadata]\nname = theproject\n") # for perf
312-
(tmp_path / "requirements.txt.in").write_text(
312+
(tmp_path / "constraints.txt").write_text(
313313
textwrap.dedent(
314314
f"""\
315315
--no-index
@@ -344,7 +344,7 @@ def test_sync_extras(virtualenv_python, testpkgs, tmp_path):
344344
)
345345
)
346346
(tmp_path / "setup.cfg").write_text("[metadata]\nname = theproject\n") # for perf
347-
(tmp_path / "requirements.txt.in").write_text(
347+
(tmp_path / "constraints.txt").write_text(
348348
textwrap.dedent(
349349
f"""\
350350
--no-index
@@ -389,7 +389,7 @@ def test_sync_extras(virtualenv_python, testpkgs, tmp_path):
389389

390390

391391
def test_post_sync_command(virtualenv_python, testpkgs, tmp_path):
392-
(tmp_path / "requirements.txt.in").write_text(
392+
(tmp_path / "constraints.txt").write_text(
393393
textwrap.dedent(
394394
f"""\
395395
--no-index

0 commit comments

Comments
 (0)