Skip to content

Commit b7cbebb

Browse files
committed
Refactor to not use regex
Signed-off-by: Samk <sampurnapyne1710@gmail.com>
1 parent 063a468 commit b7cbebb

1 file changed

Lines changed: 42 additions & 9 deletions

File tree

src/univers/version_range.py

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -790,23 +790,56 @@ def from_ossa_native(cls, string):
790790
791791
>>> str(PypiVersionRange.from_ossa_native("<20.2.1, >=21.0.0 <21.2.1, ==22.0.0"))
792792
'vers:pypi/<20.2.1|>=21.0.0|<21.2.1|22.0.0'
793+
794+
>>> str(PypiVersionRange.from_ossa_native(">=1.15.0<1.15.2, 1.16.0"))
795+
'vers:pypi/>=1.15.0|<1.15.2|1.16.0'
793796
"""
794797

795798
# Normalize "and" keyword to comma
796799
# "<=5.0.3, >=6.0.0 <=6.1.0 and ==7.0.0" -> "<=5.0.3, >=6.0.0 <=6.1.0, ==7.0.0"
797800
string = string.replace(" and ", ",")
798801

799-
# Remove spaces around operators
800-
# "<=5.0.3, >=6.0.0 <=6.1.0, ==7.0.0" -> "<=5.0.3,>=6.0.0<=6.1.0,==7.0.0"
801-
string = re.sub(r"\s+([<>=!]+)", r"\1", string)
802-
string = re.sub(r"([<>=!]+)\s+", r"\1", string)
803-
804-
# Insert comma between consecutive constraints
805-
# "<=5.0.3,>=6.0.0<=6.1.0,==7.0.0" -> "<=5.0.3,>=6.0.0,<=6.1.0,==7.0.0"
806-
string = re.sub(r"(\d)([<>=!])", r"\1,\2", string)
802+
# Split on commas then whitespace to get individual tokens
803+
# "<=5.0.3 >=6.0.0 " -> ["<=5.0.3", ">=6.0.0"]
804+
raw_tokens = [token for chunk in string.split(",") for token in chunk.split()]
805+
806+
if not raw_tokens:
807+
raise InvalidVersionRange(f"Empty or invalid OSSA version string: {string!r}")
808+
809+
# Merge tokens where the operator and version are separated by a space
810+
# ["<=", "5.0.3", ">=", "6.0.0"] -> ["<=5.0.3", ">=6.0.0"]
811+
raw_iter = iter(raw_tokens)
812+
fused_tokens = []
813+
for current in raw_iter:
814+
is_bare_operator = all(c in "<>=!" for c in current)
815+
if is_bare_operator:
816+
fused_tokens.append(current + next(raw_iter))
817+
else:
818+
fused_tokens.append(current)
819+
820+
# Split tokens that contain multiple concatenated constraints without separator
821+
# ">=1.15.0<1.15.2" -> [">=1.15.0", "<1.15.2"]
822+
parts = []
823+
for token in fused_tokens:
824+
825+
token_len = len(token)
826+
pos = 0
827+
while pos < token_len and token[pos] in "<>=!":
828+
pos += 1
829+
830+
segment_start = 0
831+
while pos < token_len:
832+
if token[pos] in "<>=!":
833+
parts.append(token[segment_start:pos])
834+
segment_start = pos
835+
while pos < token_len and token[pos] in "<>=!":
836+
pos += 1
837+
else:
838+
pos += 1
839+
parts.append(token[segment_start:])
807840

808841
constraints = []
809-
for part in string.split(","):
842+
for part in parts:
810843

811844
# Default to exact match for bare version numbers
812845
# "1.16.0" -> "=1.16.0"

0 commit comments

Comments
 (0)