Skip to content

Commit

Permalink
New Parse WIP: 21 tests to go
Browse files Browse the repository at this point in the history
  • Loading branch information
arthur-debert committed Dec 4, 2024
1 parent 1f9d2fe commit 2047cf8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 22 deletions.
24 changes: 16 additions & 8 deletions rangy/parse.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import re

from rangy.exceptions import ParseRangeError
from rangy import ConverterRegistry, Rangy
from .const import SPECIAL_CHARS
from .registry import ConverterRegistry
from .const import SPECIAL_CHARS, INFINITY

def _split(as_squence):
if None in as_squence:
raise ParseRangeError("Invalid range tuple/list")
if len(as_squence) == 1:
# this is valid, as it
# indicates a single value range
Expand All @@ -28,7 +30,6 @@ def _nomalize_str(range_str):
Returns:
A tuples of parts of the range string.
"""
# FIX: Remove brackets FIRST, then split.
range_str = re.sub(r'^[\[\(]|[\]\)]$', '', range_str.strip()) # Remove brackets
range_str = re.split(r'[\s,;|-]+', range_str) # split
return tuple(part.strip() for part in range_str if part.strip()) # Remove empty strings
Expand All @@ -45,6 +46,7 @@ def _normalize_to_sequence(range_input):
Raises:
ParseRangeError: If the input is invalid or cannot be normalized.
"""
from rangy import Rangy
if isinstance(range_input, Rangy):
range_input = range_input.copy().values

Expand Down Expand Up @@ -86,18 +88,24 @@ def parse_range(range_input):
start, end = _normalize_to_sequence(range_input)

try:
if not isinstance(start, str):
if start == '*':
parsed_start = 0
elif start == '+':
parsed_start = 1
elif not isinstance(start, str):
converter = ConverterRegistry.get(start)
parsed_start = converter(start) # or converter.to_number(start) depending on your Converter interface.
parsed_start = converter(start)
else:
parsed_start = _convert_string_part(start)

if not isinstance(end, str):
if end == '*' or end == '+':
parsed_end = INFINITY
elif not isinstance(end, str):
converter = ConverterRegistry.get(end)
parsed_end = converter(end) # or converter.to_number(end)
parsed_end = converter(end)
else:
parsed_end = _convert_string_part(end)
return parsed_start, parsed_end

except (KeyError, ValueError, TypeError) as e: # Handle converter and TypeRegistry errors.
except (KeyError, ValueError, TypeError) as e:
raise ParseRangeError(f"Error parsing range: {e}") from e
10 changes: 5 additions & 5 deletions rangy/rangy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

RangyType = Union[int, str]


from .parse import parse_range as new_parse


def _parse(self, rangy) -> Tuple[Union[int, float], Union[int, float]]:
Expand Down Expand Up @@ -142,7 +142,7 @@ class Rangy:
_max (int): The maximum range value.
_rangy_type (int): The type of range.
"""
def __init__(self, range: Union[int, str, Tuple[int, int]], parse_func: callable = _parse):
def __init__(self, range: Union[int, str, Tuple[int, int]], parse_func: callable = new_parse):
"""
Initializes a Rangy instance.
Expand All @@ -157,7 +157,7 @@ def __init__(self, range: Union[int, str, Tuple[int, int]], parse_func: callable
self._max = range._max
self._type = range._type
else:
self._min, self._max = parse_func(self, range)
self._min, self._max = parse_func(range)
self._type = self._determine_type()

def _determine_type(self) -> int:
Expand All @@ -167,9 +167,9 @@ def _determine_type(self) -> int:
Returns:
int: The rangy type, one of rangy_EXACT, rangy_RANGE, rangy_ANY, or rangy_AT_LEAST_ONE.
"""
if self._min == 0 and self._max == INFINITY:
if self._min == 0 and self._max == float(INFINITY):
return ANY
elif self._min == 1 and self._max == INFINITY:
elif self._min == 1 and self._max == float(INFINITY):
return AT_LEAST_ONE
elif self._min == self._max:
return EXACT
Expand Down
14 changes: 7 additions & 7 deletions tests/test_comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ def test_ge(count, other, expected):
var_count = Rangy(count)
assert (var_count >= other) == expected

@pytest.mark.parametrize("count", [
(-1, 3),
(3, -1),
(-1, -3),
@pytest.mark.parametrize("count, expected", [
((-1, 3), (-1, 3)),
((3, -1), (-1, 3)),
((-1, -3), (-3, -1)),
], ids=[
"negative_min",
"negative_max",
"negative_both"
])
def test_negative(count):
with pytest.raises(ValueError):
Rangy(count)
def test_negative(count, expected):
var_count = Rangy(count)
assert var_count.values == expected
3 changes: 2 additions & 1 deletion tests/test_contains.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from rangy import Rangy
from rangy.exceptions import ParseRangeError


@pytest.mark.parametrize("count, item, expected", [
Expand Down Expand Up @@ -32,5 +33,5 @@ def test_contains(count, item, expected):
"none_max"
])
def test_invalid_tuple(count):
with pytest.raises(ValueError):
with pytest.raises(ParseRangeError):
Rangy(count)
3 changes: 2 additions & 1 deletion tests/test_parse.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from rangy import INFINITY, _parse
from rangy.exceptions import ParseRangeError


@pytest.mark.parametrize("count, expected", [
Expand Down Expand Up @@ -59,5 +60,5 @@ def test_parse(count, expected):
"invalid_range_semicolon"
])
def test_parse_invalid(count):
with pytest.raises(ValueError):
with pytest.raises(ParseRangeError):
_parse(None, count)

0 comments on commit 2047cf8

Please sign in to comment.