spec_parser: check next_token if not expecting next token (#49408)

This commit is contained in:
Harmen Stoppels 2025-03-12 08:39:23 +01:00 committed by GitHub
parent 9f69d9b286
commit db7ab9826d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 12 deletions

View File

@ -485,23 +485,18 @@ def parse_one_or_raise(
text (str): text to be parsed text (str): text to be parsed
initial_spec: buffer where to parse the spec. If None a new one will be created. initial_spec: buffer where to parse the spec. If None a new one will be created.
""" """
stripped_text = text.strip() parser = SpecParser(text)
parser = SpecParser(stripped_text)
result = parser.next_spec(initial_spec) result = parser.next_spec(initial_spec)
last_token = parser.ctx.current_token next_token = parser.ctx.next_token
if last_token is not None and last_token.end != len(stripped_text): if next_token:
message = "a single spec was requested, but parsed more than one:" message = f"expected a single spec, but got more:\n{text}"
message += f"\n{text}" underline = f"\n{' ' * next_token.start}{'^' * len(next_token.value)}"
if last_token is not None: message += color.colorize(f"@*r{{{underline}}}")
underline = f"\n{' ' * last_token.end}{'^' * (len(text) - last_token.end)}"
message += color.colorize(f"@*r{{{underline}}}")
raise ValueError(message) raise ValueError(message)
if result is None: if result is None:
message = "a single spec was requested, but none was parsed:" raise ValueError("expected a single spec, but got none")
message += f"\n{text}"
raise ValueError(message)
return result return result

View File

@ -21,6 +21,7 @@
SpecParsingError, SpecParsingError,
SpecTokenizationError, SpecTokenizationError,
SpecTokens, SpecTokens,
parse_one_or_raise,
) )
from spack.tokenize import Token from spack.tokenize import Token
@ -1285,3 +1286,19 @@ def test_git_ref_spec_equivalences(mock_packages, lhs_str, rhs_str, expected):
def test_platform_is_none_if_not_present(spec_str): def test_platform_is_none_if_not_present(spec_str):
s = SpecParser(spec_str).next_spec() s = SpecParser(spec_str).next_spec()
assert s.architecture.platform is None, s assert s.architecture.platform is None, s
def test_parse_one_or_raise_error_message():
with pytest.raises(ValueError) as exc:
parse_one_or_raise(" x y z")
msg = """\
expected a single spec, but got more:
x y z
^\
"""
assert str(exc.value) == msg
with pytest.raises(ValueError, match="expected a single spec, but got none"):
parse_one_or_raise(" ")