Skip to content

Commit 53f683f

Browse files
authored
Merge pull request #8 from jag250/main
Improve caret translation logic
2 parents 9bbb7cc + 8e9ffb9 commit 53f683f

File tree

2 files changed

+40
-18
lines changed

2 files changed

+40
-18
lines changed

metadata_please/source_checkout.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from configparser import NoOptionError, NoSectionError, RawConfigParser
2626

2727
from packaging.utils import canonicalize_name
28+
from packaging.version import Version
2829

2930
from .source_checkout_ast import SetupFindingVisitor, UNKNOWN
3031

@@ -139,22 +140,41 @@ def _translate_caret(specifier: str) -> str:
139140
Given a string like "^0.2.3" returns ">=0.2.3,<0.3.0".
140141
"""
141142
assert "," not in specifier
142-
parts = specifier[1:].split(".")
143-
while len(parts) < 3:
144-
parts.append("0")
145-
146-
for i in range(len(parts)):
147-
if parts[i] != "0":
148-
# The docs are not super clear about how this behaves, but let's
149-
# assume integer-valued parts and just let the exception raise
150-
# otherwise.
151-
incremented = parts[:]
152-
incremented[i] = str(int(parts[i]) + 1)
153-
del incremented[i + 1 :]
154-
incremented_version = ".".join(incremented)
155-
break
143+
144+
version = Version(specifier[1:])
145+
146+
# version.release takes out the pre- and post- parts and leaves only numbers
147+
version_parts = list(version.release)
148+
149+
if version.is_prerelease or version.is_postrelease:
150+
# Return next version, incrementing the least significant number
151+
version_parts[-1] += 1
152+
156153
else:
157-
raise ValueError("All components were zero?")
154+
if version.major == version.minor == version.micro == 0:
155+
raise ValueError("All components were zero?")
156+
157+
if version.major > 0 or version.minor == 0:
158+
# Next major version
159+
version_parts[0] += 1
160+
161+
# Set the rest of the values to 0
162+
for i in range(1, len(version_parts)):
163+
version_parts[i] = 0
164+
165+
elif version.minor > 0 or version.micro == 0:
166+
# Next minor version.
167+
version_parts[1] += 1
168+
169+
# Set the rest of the values to 0
170+
for i in range(2, len(version_parts)):
171+
version_parts[i] = 0
172+
173+
else:
174+
# Next patch version
175+
version_parts[2] += 1
176+
177+
incremented_version = ".".join([str(i) for i in version_parts])
158178
return f">={specifier[1:]},<{incremented_version}"
159179

160180

metadata_please/tests/source_checkout.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def test_poetry_full(self) -> None:
105105
a2 = "*"
106106
b = "^1.2.3"
107107
b2 = "^0.2.3"
108+
b3 = "^0.44b0"
108109
c = "~1.2.3"
109110
c2 = "~1.2"
110111
c3 = "~1"
@@ -124,15 +125,16 @@ def test_poetry_full(self) -> None:
124125
[
125126
"a==1.0",
126127
"a2",
127-
"b>=1.2.3,<2",
128-
"b2>=0.2.3,<0.3",
128+
"b>=1.2.3,<2.0.0",
129+
"b2>=0.2.3,<0.3.0",
130+
"b3>=0.44b0,<0.45",
129131
"c>=1.2.3,<1.3",
130132
"c2>=1.2,<1.3",
131133
"c3>=1,<2",
132134
"d==2 ; python_version < '3.11'",
133135
"e==2 ; sys_platform == 'darwin'",
134136
"complex[bar,baz]==2",
135-
'opt>=2.9,<3 ; extra == "foo"',
137+
'opt>=2.9,<3.0 ; extra == "foo"',
136138
],
137139
rv.reqs,
138140
)

0 commit comments

Comments
 (0)