diff --git a/src/packaging/_parser.py b/src/packaging/_parser.py index 020ea716..64a4a3de 100644 --- a/src/packaging/_parser.py +++ b/src/packaging/_parser.py @@ -89,7 +89,7 @@ def _parse_requirement_details( tokenizer: Tokenizer, ) -> Tuple[str, str, Optional[MarkerList]]: """ - requirement_details = AT URL (WS requirement_marker)? + requirement_details = AT URL (WS requirement_marker?)? | specifier WS? (requirement_marker)? """ @@ -108,6 +108,10 @@ def _parse_requirement_details( tokenizer.expect("WS", expected="whitespace after URL") + # The input might end after whitespace. + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + marker = _parse_requirement_marker( tokenizer, span_start=url_start, after="URL and whitespace" ) diff --git a/tests/test_requirements.py b/tests/test_requirements.py index 0a597be7..caaf39e0 100644 --- a/tests/test_requirements.py +++ b/tests/test_requirements.py @@ -581,14 +581,14 @@ def test_str_and_repr( self, extras: str, url_or_specifier: str, marker: str ) -> None: # GIVEN - to_parse = f"name{extras}{url_or_specifier}{marker}".strip() + to_parse = f"name{extras}{url_or_specifier}{marker}" # WHEN req = Requirement(to_parse) # THEN - assert str(req) == to_parse - assert repr(req) == f"" + assert str(req) == to_parse.strip() + assert repr(req) == f"" @pytest.mark.parametrize("dep1, dep2", EQUAL_DEPENDENCIES) def test_equal_reqs_equal_hashes(self, dep1: str, dep2: str) -> None: