Skip to content

Commit ba2d225

Browse files
committed
fix parsing
1 parent 4029dbd commit ba2d225

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

python/private/version.bzl

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ def _in(reference):
4444
return lambda token: token in reference
4545

4646
def _ctx(start):
47-
return {"norm": "", "start": start}
47+
"""Creates a context, which is state for parsing (or sub-parsing)."""
48+
return {
49+
# The result value from parsing
50+
"norm": "",
51+
# Where in the parser's input string this context starts.
52+
"start": start,
53+
}
4854

4955
def _open_context(self):
5056
"""Open an new parsing ctx.
@@ -60,7 +66,16 @@ def _open_context(self):
6066
return self.contexts[-1]
6167

6268
def _accept(self, key = None):
63-
"""Close the current ctx successfully and merge the results."""
69+
"""Close the current ctx successfully and merge the results.
70+
71+
Args:
72+
self: {type}`Parser}
73+
key: {type}`str | None` the key to store the result in
74+
the most recent context. If not set, the key is "norm".
75+
76+
Returns:
77+
{type}`bool` always True
78+
"""
6479
finished = self.contexts.pop()
6580
self.contexts[-1]["norm"] += finished["norm"]
6681
if key:
@@ -79,7 +94,14 @@ def _discard(self, key = None):
7994
return False
8095

8196
def _new(input):
82-
"""Create a new normalizer"""
97+
"""Create a new parser
98+
99+
Args:
100+
input: {type}`str` input to parse
101+
102+
Returns:
103+
{type}`Parser` a struct for a parser object.
104+
"""
83105
self = struct(
84106
input = input,
85107
contexts = [_ctx(0)],
@@ -167,7 +189,7 @@ def accept_placeholder(parser):
167189
return parser.accept()
168190

169191
def accept_digits(parser):
170-
"""Accept multiple digits (or placeholders).
192+
"""Accept multiple digits (or placeholders), up to a non-digit/placeholder.
171193
172194
Args:
173195
parser: The normalizer.
@@ -275,7 +297,24 @@ def accept_separator_alnum(parser):
275297
Returns:
276298
whether a separator and an alphanumeric string were accepted.
277299
"""
278-
parser.open_context()
300+
301+
# Input is "0.1.0+brt.9e"
302+
ctx = parser.open_context()
303+
304+
if not accept(parser, _in([".", "-", "_"]), "."):
305+
return parser.discard()
306+
307+
if accept_alnum(parser):
308+
# First character is separator; skip it.
309+
value = ctx["norm"][1:]
310+
311+
# PEP 440: Integer Normalization
312+
if value.isdigit():
313+
value = str(int(value))
314+
ctx["norm"] = ctx["norm"][0] + value
315+
return parser.accept()
316+
317+
return parser.discard()
279318

280319
# PEP 440: Local version segments
281320
if (

tests/version/version_test.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def _test_normalize_local(env):
109109
# Verify a local with a [digit][non-digit] sequence parses ok
110110
in_str = "0.1.0+brt.9e"
111111
actual = version.normalize(in_str)
112-
env.expect.that_str(actual).equals("xxx")
112+
env.expect.that_str(actual).equals(in_str)
113113

114114
_tests.append(_test_normalize_local)
115115

0 commit comments

Comments
 (0)