Skip to content

Commit

Permalink
ENH: Allow adding PageRange objects (#948)
Browse files Browse the repository at this point in the history
Now the following is possible:

    >>> from PyPDF2 import PageRange
    >>> a = PageRange("0:5")
    >>> b = PageRange("2:7")
    >>> a + b
    PageRange("0:7")

Closes #759
See #751
See #752
  • Loading branch information
MartinThoma authored Jun 6, 2022
1 parent 4baedb2 commit 2a1db78
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
17 changes: 17 additions & 0 deletions PyPDF2/pagerange.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,23 @@ def __eq__(self, other: Any) -> bool:
return False
return self._slice == other._slice

def __add__(self, other: "PageRange") -> "PageRange":
if not isinstance(other, PageRange):
raise TypeError(f"Can't add PageRange and {type(other)}")
if self._slice.step is not None or other._slice.step is not None:
raise ValueError("Can't add PageRange with stride")
a = self._slice.start, self._slice.stop
b = other._slice.start, other._slice.stop

if a[0] > b[0]:
a, b = b, a

# Now a[0] is the smallest
if b[0] > a[1]:
# There is a gap between a and b.
raise ValueError("Can't add PageRanges with gap")
return PageRange(slice(a[0], max(a[1], b[1])))


PAGE_RANGE_ALL = PageRange(":") # The range of all pages.

Expand Down
42 changes: 42 additions & 0 deletions tests/test_pagerange.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,45 @@ def test_parse_filename_page_ranges_err():
assert (
exc.value.args[0] == "The first argument must be a filename, not a page range."
)


@pytest.mark.parametrize(
"a, b, expected",
[
(PageRange(slice(0, 5)), PageRange(slice(2, 10)), slice(0, 10)),
(PageRange(slice(0, 5)), PageRange(slice(2, 3)), slice(0, 5)),
(PageRange(slice(0, 5)), PageRange(slice(5, 10)), slice(0, 10)),
],
)
def test_addition(a, b, expected):
pr1 = PageRange(a)
pr2 = PageRange(b)
assert pr1 + pr2 == PageRange(expected)
assert pr2 + pr1 == PageRange(expected) # addition is commutative


@pytest.mark.parametrize(
"a, b",
[
(PageRange(slice(0, 5)), PageRange(slice(7, 10))),
(PageRange(slice(7, 10)), PageRange(slice(0, 5))),
],
)
def test_addition_gap(a: PageRange, b: PageRange):
with pytest.raises(ValueError) as exc:
a + b
assert exc.value.args[0] == "Can't add PageRanges with gap"


def test_addition_non_page_range():
with pytest.raises(TypeError) as exc:
PageRange(slice(0, 5)) + "2:7"
assert exc.value.args[0] == "Can't add PageRange and <class 'str'>"


def test_addition_stride():
a = PageRange(slice(0, 5, 2))
b = PageRange(slice(7, 9))
with pytest.raises(ValueError) as exc:
a + b
assert exc.value.args[0] == "Can't add PageRange with stride"

0 comments on commit 2a1db78

Please sign in to comment.