Skip to content

Commit

Permalink
Improve error for local version label with unsupported operators
Browse files Browse the repository at this point in the history
This makes it clearer why the failure happens the way it happened.
  • Loading branch information
pradyunsg committed Jan 31, 2023
1 parent 068a0b5 commit 7477eba
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/packaging/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ def _parse_version_many(tokenizer: Tokenizer) -> str:
span_start=span_start,
span_end=tokenizer.position + 1,
)
if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
tokenizer.raise_syntax_error(
"Local version label can only be used with `==` or `!=` operators",
span_start=span_start,
span_end=tokenizer.position,
)
tokenizer.consume("WS")
if not tokenizer.check("COMMA"):
break
Expand Down
1 change: 1 addition & 0 deletions src/packaging/_tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def __str__(self) -> str:
"URL": r"[^ \t]+",
"IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
"VERSION_PREFIX_TRAIL": r"\.\*",
"VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
"WS": r"[ \t]+",
"END": r"$",
}
Expand Down
20 changes: 20 additions & 0 deletions tests/test_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,26 @@ def test_error_when_prefix_match_is_used_incorrectly(self) -> None:
" ~~~~~^"
)

@pytest.mark.parametrize("operator", [">=", "<=", ">", "<", "~="])
def test_error_when_local_version_label_is_used_incorrectly(
self, operator: str
) -> None:
# GIVEN
to_parse = f"name {operator} 1.0+local.version.label"
op_tilde = len(operator) * "~"

# WHEN
with pytest.raises(InvalidRequirement) as ctx:
Requirement(to_parse)

# THEN
assert ctx.exconly() == (
"packaging.requirements.InvalidRequirement: "
"Local version label can only be used with `==` or `!=` operators\n"
f" name {operator} 1.0+local.version.label\n"
f" {op_tilde}~~~~^"
)

def test_error_when_bracket_not_closed_correctly(self) -> None:
# GIVEN
to_parse = "name[bar, baz >= 1.0"
Expand Down

0 comments on commit 7477eba

Please sign in to comment.