Skip to content

Commit dfac6b3

Browse files
author
Bahtya
committed
Fix requirements-txt-fixer reordering pip options like --index-url
The requirements-txt-fixer was alphabetically sorting all lines, including pip options like --index-url and --extra-index-url. This caused --extra-index-url to be sorted above --index-url, breaking pip's index resolution order since --index-url must come first. Fix by preserving the original relative order of lines that start with `--` (pip options), while still sorting regular package requirements alphabetically. Closes #612 Bahtya
1 parent d128349 commit dfac6b3

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

pre_commit_hooks/requirements_txt_fixer.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ def __lt__(self, requirement: Requirement) -> bool:
4545
elif requirement.value == b'\n':
4646
return False
4747
else:
48+
# if both are pip options (start with --), maintain original
49+
# order to avoid breaking semantic ordering
50+
# (e.g. --index-url must come before --extra-index-url)
51+
if (
52+
self.name.startswith(b'--') and
53+
requirement.name.startswith(b'--')
54+
):
55+
return False
4856
# if 2 requirements have the same name, the one with comments
4957
# needs to go first (so that when removing duplicates, the one
5058
# with comments is kept)

tests/requirements_txt_fixer_test.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,39 @@
107107
PASS,
108108
b'a=2.0.0 \\\n --hash=sha256:abcd\nb==1.0.0\n',
109109
),
110+
# --index-url and --extra-index-url should maintain original order
111+
# see: https://github.com/pre-commit/pre-commit-hooks/issues/612
112+
(
113+
b'--index-url https://example.com/simple\n'
114+
b'--extra-index-url https://example.com/extra\n'
115+
b'foo\n',
116+
PASS,
117+
b'--index-url https://example.com/simple\n'
118+
b'--extra-index-url https://example.com/extra\n'
119+
b'foo\n',
120+
),
121+
# pip options should not be reordered even if out of alpha order
122+
(
123+
b'--extra-index-url https://example.com/extra\n'
124+
b'--index-url https://example.com/simple\n'
125+
b'foo\n',
126+
PASS,
127+
b'--extra-index-url https://example.com/extra\n'
128+
b'--index-url https://example.com/simple\n'
129+
b'foo\n',
130+
),
131+
# packages should still be sorted while pip options stay in place
132+
(
133+
b'--index-url https://example.com/simple\n'
134+
b'--extra-index-url https://example.com/extra\n'
135+
b'foo\n'
136+
b'bar\n',
137+
FAIL,
138+
b'--index-url https://example.com/simple\n'
139+
b'--extra-index-url https://example.com/extra\n'
140+
b'bar\n'
141+
b'foo\n',
142+
),
110143
),
111144
)
112145
def test_integration(input_s, expected_retval, output, tmpdir):

0 commit comments

Comments
 (0)