Skip to content

Commit c1dfdaa

Browse files
authored
TST: Reader and page properties (#835)
1 parent eef03d9 commit c1dfdaa

File tree

9 files changed

+78
-17
lines changed

9 files changed

+78
-17
lines changed

PyPDF2/pdf.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,11 +1422,13 @@ def getPage(self, pageNumber):
14221422
self._flatten()
14231423
return self.flattenedPages[pageNumber]
14241424

1425-
namedDestinations = property(lambda self: self.getNamedDestinations(), None, None)
1426-
"""
1427-
Read-only property that accesses the
1428-
:meth:`getNamedDestinations()<PdfFileReader.getNamedDestinations>` function.
1429-
"""
1425+
@property
1426+
def namedDestinations(self):
1427+
"""
1428+
Read-only property that accesses the
1429+
:meth:`getNamedDestinations()<PdfFileReader.getNamedDestinations>` function.
1430+
"""
1431+
return self.getNamedDestinations()
14301432

14311433
# A select group of relevant field attributes. For the complete list,
14321434
# see section 8.6.2 of the PDF 1.7 reference.

Scripts/2-up.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def main():
1818
print("2-up input " + sys.argv[1])
1919
reader = PdfFileReader(sys.argv[1])
2020
writer = PdfFileWriter()
21-
for iter in range(0, reader.getNumPages() - 1, 2):
21+
for iter in range(0, reader.numPages - 1, 2):
2222
lhs = reader.getPage(iter)
2323
rhs = reader.getPage(iter + 1)
2424
lhs.mergeTranslatedPage(rhs, lhs.mediaBox.getUpperRight_x(), 0, True)

Scripts/booklet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def main():
2323
args = parser.parse_args()
2424

2525
reader = PyPDF2.PdfFileReader(args.input)
26-
numPages = reader.getNumPages()
26+
numPages = reader.numPages
2727
print("Pages in file:", numPages)
2828

2929
pagesPerSheet = 4

Tests/test_basic_features.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def test_basic_features():
1616
reader = PdfFileReader(pdf_path)
1717
writer = PdfFileWriter()
1818

19-
reader.getNumPages()
19+
assert reader.numPages == 1
2020

2121
# add page 1 from input1 to output document, unchanged
2222
writer.addPage(reader.getPage(0))

Tests/test_page.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55

66
from PyPDF2 import PdfFileReader
7+
from PyPDF2.generic import RectangleObject
78

89
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
910
PROJECT_ROOT = os.path.dirname(TESTS_ROOT)
@@ -92,3 +93,21 @@ def test_compress_content_streams(pdf_path, password):
9293
reader.decrypt(password)
9394
for page in reader.pages:
9495
page.compressContentStreams()
96+
97+
98+
def test_page_properties():
99+
reader = PdfFileReader(os.path.join(RESOURCE_ROOT, "crazyones.pdf"))
100+
page = reader.pages[0]
101+
assert page.mediaBox == RectangleObject([0, 0, 612, 792])
102+
assert page.cropBox == RectangleObject([0, 0, 612, 792])
103+
assert page.bleedBox == RectangleObject([0, 0, 612, 792])
104+
assert page.trimBox == RectangleObject([0, 0, 612, 792])
105+
assert page.artBox == RectangleObject([0, 0, 612, 792])
106+
107+
108+
def test_page_rotation_non90():
109+
reader = PdfFileReader(os.path.join(RESOURCE_ROOT, "crazyones.pdf"))
110+
page = reader.pages[0]
111+
with pytest.raises(ValueError) as exc:
112+
page.rotateClockwise(91)
113+
assert exc.value.args[0] == "Rotation angle must be a multiple of 90"

Tests/test_pagerange.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ def test_parse_filename_page_ranges(params, expected):
7373

7474

7575
def test_parse_filename_page_ranges_err():
76-
with pytest.raises(ValueError):
76+
with pytest.raises(ValueError) as exc:
7777
parse_filename_page_ranges(["1:5", "foo.pdf"])
78+
assert (
79+
exc.value.args[0] == "The first argument must be a filename, not a page range."
80+
)
7881

7982

8083
def test_page_range_help():

Tests/test_reader.py

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
def test_get_num_pages(src, num_pages):
3333
src = os.path.join(RESOURCE_ROOT, src)
3434
reader = PdfFileReader(src)
35-
assert reader.getNumPages() == num_pages
35+
assert reader.numPages == num_pages
3636

3737

3838
@pytest.mark.parametrize(
@@ -71,7 +71,7 @@ def test_get_num_pages(src, num_pages):
7171
def test_read_metadata(pdf_path, expected):
7272
with open(pdf_path, "rb") as inputfile:
7373
reader = PdfFileReader(inputfile)
74-
docinfo = reader.getDocumentInfo()
74+
docinfo = reader.documentInfo
7575
metadict = dict(docinfo)
7676
assert metadict == expected
7777
docinfo.title
@@ -117,7 +117,7 @@ def test_get_attachments(src):
117117
reader = PdfFileReader(src)
118118

119119
attachments = {}
120-
for i in range(reader.getNumPages()):
120+
for i in range(reader.numPages):
121121
page = reader.getPage(i)
122122
if PG.ANNOTS in page:
123123
for annotation in page[PG.ANNOTS]:
@@ -485,20 +485,20 @@ def test_read_unknown_zero_pages():
485485
pdf_stream = io.BytesIO(pdf_data)
486486
with pytest.raises(PdfReadError) as exc:
487487
reader = PdfFileReader(pdf_stream, strict=True)
488-
reader.getNumPages()
488+
reader.numPages
489489

490490
assert exc.value.args[0] == "Could not find object."
491491
reader = PdfFileReader(pdf_stream, strict=False)
492492
with pytest.raises(AttributeError) as exc:
493-
reader.getNumPages()
493+
reader.numPages
494494
assert exc.value.args[0] == "'NoneType' object has no attribute 'getObject'"
495495

496496

497497
def test_read_encrypted_without_decryption():
498498
src = os.path.join(RESOURCE_ROOT, "libreoffice-writer-password.pdf")
499499
reader = PdfFileReader(src)
500500
with pytest.raises(PdfReadError) as exc:
501-
reader.getNumPages()
501+
reader.numPages
502502
assert exc.value.args[0] == "File has not been decrypted"
503503

504504

@@ -537,3 +537,34 @@ def test_PdfReaderDecryptWhenNoID():
537537
ipdf = PdfFileReader(inputfile)
538538
ipdf.decrypt("")
539539
assert ipdf.getDocumentInfo() == {"/Producer": "European Patent Office"}
540+
541+
542+
def test_reader_properties():
543+
reader = PdfFileReader(os.path.join(RESOURCE_ROOT, "crazyones.pdf"))
544+
assert reader.outlines == []
545+
assert len(reader.pages) == 1
546+
assert reader.pageLayout is None
547+
assert reader.pageMode is None
548+
assert reader.isEncrypted is False
549+
550+
551+
def test_decode_permissions():
552+
reader = PdfFileReader(os.path.join(RESOURCE_ROOT, "crazyones.pdf"))
553+
base = {
554+
"accessability": False,
555+
"annotations": False,
556+
"assemble": False,
557+
"copy": False,
558+
"forms": False,
559+
"modify": False,
560+
"print_high_quality": False,
561+
"print": False,
562+
}
563+
564+
print_ = base.copy()
565+
print_["print"] = True
566+
assert reader.decode_permissions(4) == print_
567+
568+
modify = base.copy()
569+
modify["modify"] = True
570+
assert reader.decode_permissions(8) == modify

Tests/test_writer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def test_io_streams():
343343

344344
# Read from bytes stream
345345
reader = PdfFileReader(bytes_stream)
346-
assert reader.getNumPages() == 4
346+
assert reader.numPages == 4
347347

348348
# Write to bytes stream
349349
writer = PdfFileWriter()

Tests/test_xmp.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
)
2020
def test_read_xmp(src, has_xmp):
2121
reader = PdfFileReader(src)
22-
xmp = reader.getXmpMetadata()
22+
xmp = reader.xmpMetadata
2323
assert (xmp is None) == (not has_xmp)
2424
if has_xmp:
2525
for el in xmp.getElement(
@@ -48,3 +48,9 @@ def test_regression_issue774():
4848
cls = PyPDF2.xmp.XmpInformation
4949
date = cls._converter_date("2021-04-28T12:23:34.123Z")
5050
assert date.year == 2021
51+
assert date.month == 4
52+
assert date.day == 28
53+
assert date.hour == 12
54+
assert date.minute == 23
55+
assert date.second == 34
56+
assert date.microsecond == 123000

0 commit comments

Comments
 (0)