Skip to content

Commit 2a30d32

Browse files
committed
more accurate translation logic
1 parent 199be25 commit 2a30d32

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

metadata_please/source_checkout.py

Lines changed: 29 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,35 @@ 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+
version_parts = list(version.release)
146+
if version.is_prerelease or version.is_postrelease:
147+
# Return next version, incrementing the least significant number
148+
version_parts[-1] += 1
149+
156150
else:
157-
raise ValueError("All components were zero?")
151+
if version.major > 0 or version.minor == 0:
152+
# Next major version
153+
version_parts[0] += 1
154+
155+
# Set the rest of the values to 0
156+
for i in range(1, len(version_parts)):
157+
version_parts[i] = 0
158+
159+
elif version.minor > 0 or version.micro == 0:
160+
# Next minor version.
161+
version_parts[1] += 1
162+
163+
# Set the rest of the values to 0
164+
for i in range(2, len(version_parts)):
165+
version_parts[i] = 0
166+
167+
else:
168+
# Next patch version
169+
version_parts[2] += 1
170+
171+
incremented_version = ".".join([str(i) for i in version_parts])
158172
return f">={specifier[1:]},<{incremented_version}"
159173

160174

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"
@@ -126,8 +127,9 @@ def test_poetry_full(self) -> None:
126127
[
127128
"a==1.0",
128129
"a2",
129-
"b>=1.2.3,<2",
130-
"b2>=0.2.3,<0.3",
130+
"b>=1.2.3,<2.0.0",
131+
"b2>=0.2.3,<0.3.0",
132+
"b3>=0.44b0,<0.45",
131133
"c>=1.2.3,<1.3",
132134
"c2>=1.2,<1.3",
133135
"c3>=1,<2",
@@ -137,7 +139,7 @@ def test_poetry_full(self) -> None:
137139
"https://example.com/my-package-0.1.0.tar.gz",
138140
"../my-package/dist/my-other-package-0.1.0.tar.gz",
139141
"complex[bar,baz]==2",
140-
'opt>=2.9,<3 ; extra == "foo"',
142+
'opt>=2.9,<3.0 ; extra == "foo"',
141143
],
142144
rv.reqs,
143145
)

0 commit comments

Comments
 (0)