Skip to content

Commit

Permalink
Bypass #75
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreDecan committed Jan 28, 2023
1 parent ee80c8f commit e49898c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Speed up lookups in `IntervalDict` for non-interval keys.
- Drop official support for Python 3.6.

### Fixed
- Infinite recursion in `iterate` with `Interval` subclasses (see [#75](https://github.com/AlexandreDecan/portion/issues/75)).



## 2.3.0 (2022-08-31)

Expand Down
25 changes: 19 additions & 6 deletions portion/func.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import operator
from functools import partial

from .const import inf
from .interval import singleton
from .const import Bound, inf


def iterate(interval, step, *, base=None, reverse=False):
Expand Down Expand Up @@ -37,8 +36,22 @@ def iterate(interval, step, *, base=None, reverse=False):
def base(x):
return x

exclude = operator.lt if not reverse else operator.gt
include = operator.le if not reverse else operator.ge
if not reverse:

def exclude(v, i):
return v < i.lower or (i.left is Bound.OPEN and v <= i.lower)

def include(v, i):
return v < i.upper or (i.right is Bound.CLOSED and v <= i.upper)

else:

def exclude(v, i):
return v > i.upper or (i.right is Bound.OPEN and v >= i.upper)

def include(v, i):
return v > i.lower or (i.left is Bound.CLOSED and v >= i.lower)

step = step if callable(step) else partial(operator.add, step)

value = base(interval.lower if not reverse else interval.upper)
Expand All @@ -48,9 +61,9 @@ def base(x):
for i in interval if not reverse else reversed(interval):
value = base(i.lower if not reverse else i.upper)

while exclude(singleton(value), i):
while exclude(value, i):
value = step(value)

while include(singleton(value), i):
while include(value, i):
yield value
value = step(value)
95 changes: 67 additions & 28 deletions tests/test_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,34 +393,73 @@ def test_with_empty_and_infinities(self):
assert not (P.closedopen(0, P.inf) >= P.empty())

def test_with_values(self):
assert 0 < P.closed(1, 2)
assert not (0 < P.closed(-1, 1))
assert not (0 < P.closed(0, 1))
assert 0 < P.open(0, 1)
# assert 0 <= P.closed(1, 2)
# assert 0 <= P.open(0, 1)
# assert 0 <= P.closed(-1, 1)
# assert not (0 <= P.closed(-2, -1))
# assert not (0 <= P.open(-1, 0))

assert P.closed(1, 2) > 0
assert not (P.closed(-1, 1) > 0)
assert not (P.closed(0, 1) > 0)
assert P.open(0, 1) > 0
assert P.closed(1, 2) >= 0
assert P.open(0, 1) >= 0
assert not (P.closed(-1, 1) >= 0)
assert not (P.closed(-2, -1) >= 0)
assert not (P.open(-1, 0) >= 0)

assert not (0 < P.empty())
# assert not (0 <= P.empty())
assert not (0 > P.empty())
# assert not (0 >= P.empty())
assert not (P.empty() < 0)
assert not (P.empty() <= 0)
assert not (P.empty() > 0)
assert not (P.empty() >= 0)
with pytest.deprecated_call():
assert 0 < P.closed(1, 2)

with pytest.deprecated_call():
assert not (0 < P.closed(-1, 1))

with pytest.deprecated_call():
assert not (0 < P.closed(0, 1))

with pytest.deprecated_call():
assert 0 < P.open(0, 1)
# assert 0 <= P.closed(1, 2)
# assert 0 <= P.open(0, 1)
# assert 0 <= P.closed(-1, 1)
# assert not (0 <= P.closed(-2, -1))
# assert not (0 <= P.open(-1, 0))

with pytest.deprecated_call():
assert P.closed(1, 2) > 0

with pytest.deprecated_call():
assert not (P.closed(-1, 1) > 0)

with pytest.deprecated_call():
assert not (P.closed(0, 1) > 0)

with pytest.deprecated_call():
assert P.open(0, 1) > 0

with pytest.deprecated_call():
assert P.closed(1, 2) >= 0

with pytest.deprecated_call():
assert P.open(0, 1) >= 0

with pytest.deprecated_call():
assert not (P.closed(-1, 1) >= 0)

with pytest.deprecated_call():
assert not (P.closed(-2, -1) >= 0)

with pytest.deprecated_call():
assert not (P.open(-1, 0) >= 0)

with pytest.deprecated_call():
assert not (0 < P.empty())

with pytest.deprecated_call():
assert not (0 <= P.empty())

with pytest.deprecated_call():
assert not (0 > P.empty())

with pytest.deprecated_call():
assert not (0 >= P.empty())

with pytest.deprecated_call():
assert not (P.empty() < 0)

with pytest.deprecated_call():
assert not (P.empty() <= 0)

with pytest.deprecated_call():
assert not (P.empty() > 0)

with pytest.deprecated_call():
assert not (P.empty() >= 0)


class TestIntervalContainment:
Expand Down

0 comments on commit e49898c

Please sign in to comment.