Skip to content

Commit dd12458

Browse files
authored
clearer error handling (#514)
- raise and catch more precise errors - version-parsing errors on a package are caught and re-raised with text saying what the package is
1 parent 3905d3e commit dd12458

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

src/poetry/core/constraints/generic/parser.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from poetry.core.constraints.generic.any_constraint import AnyConstraint
88
from poetry.core.constraints.generic.constraint import Constraint
99
from poetry.core.constraints.generic.union_constraint import UnionConstraint
10+
from poetry.core.constraints.version.exceptions import ParseConstraintError
1011

1112

1213
if TYPE_CHECKING:
@@ -61,4 +62,4 @@ def parse_single_constraint(constraint: str) -> Constraint:
6162

6263
return Constraint(version, op)
6364

64-
raise ValueError(f"Could not parse version constraint: {constraint}")
65+
raise ParseConstraintError(f"Could not parse version constraint: {constraint}")

src/poetry/core/constraints/version/parser.py

+27-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
from typing import TYPE_CHECKING
66

7+
from poetry.core.constraints.version.exceptions import ParseConstraintError
8+
from poetry.core.version.exceptions import InvalidVersion
9+
710

811
if TYPE_CHECKING:
912
from poetry.core.constraints.version.version_constraint import VersionConstraint
@@ -66,7 +69,13 @@ def parse_single_constraint(constraint: str) -> VersionConstraint:
6669
# Tilde range
6770
m = TILDE_CONSTRAINT.match(constraint)
6871
if m:
69-
version = Version.parse(m.group("version"))
72+
try:
73+
version = Version.parse(m.group("version"))
74+
except InvalidVersion as e:
75+
raise ParseConstraintError(
76+
f"Could not parse version constraint: {constraint}"
77+
) from e
78+
7079
high = version.stable.next_minor()
7180
if version.release.precision == 1:
7281
high = version.stable.next_major()
@@ -76,7 +85,13 @@ def parse_single_constraint(constraint: str) -> VersionConstraint:
7685
# PEP 440 Tilde range (~=)
7786
m = TILDE_PEP440_CONSTRAINT.match(constraint)
7887
if m:
79-
version = Version.parse(m.group("version"))
88+
try:
89+
version = Version.parse(m.group("version"))
90+
except InvalidVersion as e:
91+
raise ParseConstraintError(
92+
f"Could not parse version constraint: {constraint}"
93+
) from e
94+
8095
if version.release.precision == 2:
8196
high = version.stable.next_major()
8297
else:
@@ -87,7 +102,12 @@ def parse_single_constraint(constraint: str) -> VersionConstraint:
87102
# Caret range
88103
m = CARET_CONSTRAINT.match(constraint)
89104
if m:
90-
version = Version.parse(m.group("version"))
105+
try:
106+
version = Version.parse(m.group("version"))
107+
except InvalidVersion as e:
108+
raise ParseConstraintError(
109+
f"Could not parse version constraint: {constraint}"
110+
) from e
91111

92112
return VersionRange(version, version.next_breaking(), include_min=True)
93113

@@ -127,8 +147,10 @@ def parse_single_constraint(constraint: str) -> VersionConstraint:
127147

128148
try:
129149
version = Version.parse(version_string)
130-
except ValueError:
131-
raise ValueError(f"Could not parse version constraint: {constraint}")
150+
except InvalidVersion as e:
151+
raise ParseConstraintError(
152+
f"Could not parse version constraint: {constraint}"
153+
) from e
132154

133155
if op == "<":
134156
return VersionRange(max=version)
@@ -142,6 +164,4 @@ def parse_single_constraint(constraint: str) -> VersionConstraint:
142164
return VersionUnion(VersionRange(max=version), VersionRange(min=version))
143165
return version
144166

145-
from poetry.core.constraints.version.exceptions import ParseConstraintError
146-
147167
raise ParseConstraintError(f"Could not parse version constraint: {constraint}")

src/poetry/core/packages/package.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
from typing import TypeVar
1313

1414
from poetry.core.constraints.version import parse_constraint
15+
from poetry.core.constraints.version.exceptions import ParseConstraintError
1516
from poetry.core.packages.dependency_group import MAIN_GROUP
1617
from poetry.core.packages.specification import PackageSpecification
1718
from poetry.core.packages.utils.utils import create_nested_marker
19+
from poetry.core.version.exceptions import InvalidVersion
1820
from poetry.core.version.markers import parse_marker
1921

2022

@@ -215,11 +217,15 @@ def _set_version(
215217
from poetry.core.constraints.version import Version
216218

217219
if not isinstance(version, Version):
218-
self._version = Version.parse(version)
219-
self._pretty_version = pretty_version or version
220-
else:
221-
self._version = version
222-
self._pretty_version = pretty_version or self._version.text
220+
try:
221+
version = Version.parse(version)
222+
except InvalidVersion:
223+
raise InvalidVersion(
224+
f"Invalid version '{version}' on package {self.name}"
225+
)
226+
227+
self._version = version
228+
self._pretty_version = pretty_version or version.text
223229

224230
def _get_author(self) -> dict[str, str | None]:
225231
if not self._authors:
@@ -261,8 +267,13 @@ def python_versions(self) -> str:
261267

262268
@python_versions.setter
263269
def python_versions(self, value: str) -> None:
270+
try:
271+
constraint = parse_constraint(value)
272+
except ParseConstraintError:
273+
raise ParseConstraintError(f"Invalid python versions '{value}' on {self}")
274+
264275
self._python_versions = value
265-
self._python_constraint = parse_constraint(value)
276+
self._python_constraint = constraint
266277
self._python_marker = parse_marker(
267278
create_nested_marker("python_version", self._python_constraint)
268279
)

src/poetry/core/version/markers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def __init__(
199199
# Extract operator and value
200200
m = self._CONSTRAINT_RE.match(constraint_string)
201201
if m is None:
202-
raise ValueError(f"Invalid marker '{constraint_string}'")
202+
raise InvalidMarker(f"Invalid marker '{constraint_string}'")
203203

204204
self._operator = m.group(1)
205205
if self._operator is None:

tests/packages/test_package.py

+19
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
import pytest
1010

1111
from poetry.core.constraints.version import Version
12+
from poetry.core.constraints.version.exceptions import ParseConstraintError
1213
from poetry.core.factory import Factory
1314
from poetry.core.packages.dependency import Dependency
1415
from poetry.core.packages.dependency_group import DependencyGroup
1516
from poetry.core.packages.package import Package
1617
from poetry.core.packages.project_package import ProjectPackage
18+
from poetry.core.version.exceptions import InvalidVersion
1719

1820

1921
if TYPE_CHECKING:
@@ -660,3 +662,20 @@ def test_project_package_hash_not_changed_when_version_is_changed() -> None:
660662
assert hash(package) == package_hash, "Hash must not change!"
661663
assert hash(package_clone) == package_hash
662664
assert package != package_clone
665+
666+
667+
def test_package_invalid_version() -> None:
668+
with pytest.raises(InvalidVersion) as exc_info:
669+
Package("foo", "1.2.3.bogus")
670+
671+
expected = "Invalid version '1.2.3.bogus' on package foo"
672+
assert str(exc_info.value) == expected
673+
674+
675+
def test_package_invalid_python_versions() -> None:
676+
package = Package("foo", "1.2.3")
677+
with pytest.raises(ParseConstraintError) as exc_info:
678+
package.python_versions = ">=3.6.y"
679+
680+
expected = "Invalid python versions '>=3.6.y' on foo (1.2.3)"
681+
assert str(exc_info.value) == expected

0 commit comments

Comments
 (0)