Skip to content

Commit

Permalink
Remove redundant @Property accessors from PdfFileReader.
Browse files Browse the repository at this point in the history
`PdfFileReader` contained methods of the form `getX()` followed by `x =
@Property(getX)`. Since `getX()` and `x` were functionally equivalent, where it
was possible only `x` was retained. In a few other cases, where the original
method required arguments e.g., the `getX()` form was maintained.
  • Loading branch information
acsor committed Oct 5, 2018
1 parent cb6f169 commit f020613
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 74 deletions.
6 changes: 3 additions & 3 deletions pypdf/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ class DocumentInformation(DictionaryObject):
"""
A class representing the basic document metadata provided in a PDF File.
This class is accessible through
:meth:`getDocumentInfo()<pypdf.PdfFileReader.getDocumentInfo()>`
:meth:`documentInfo()<pypdf.PdfFileReader.documentInfo()>`
All text properties of the document metadata have
*two* properties, e.g. author and author_raw. The non-raw property will
Expand Down Expand Up @@ -1406,8 +1406,8 @@ def createBlankPage(pdf=None, width=None, height=None):
page.__setitem__(NameObject('/Resources'), DictionaryObject())

if width is None or height is None:
if pdf is not None and pdf.getNumPages() > 0:
lastpage = pdf.getPage(pdf.getNumPages() - 1)
if pdf is not None and pdf.numPages > 0:
lastpage = pdf.getPage(pdf.numPages - 1)
width = lastpage.mediaBox.getWidth()
height = lastpage.mediaBox.getHeight()
else:
Expand Down
4 changes: 2 additions & 2 deletions pypdf/merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ def merge(

# Find the range of pages to merge.
if pages is None:
pages = (0, pdfr.getNumPages())
pages = (0, pdfr.numPages)
elif isinstance(pages, PageRange):
pages = pages.indices(pdfr.getNumPages())
pages = pages.indices(pdfr.numPages)
elif not isinstance(pages, tuple):
raise TypeError('"pages" must be a tuple of (start, stop[, step])')

Expand Down
77 changes: 17 additions & 60 deletions pypdf/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,8 @@ def appendPagesFromReader(self, reader, afterPageAppend=None):
that references to the page appended to the writer.
"""
# Get page count from writer and reader
readerNumPages = reader.getNumPages()
writerNumPages = self.getNumPages()
readerNumPages = reader.numPages

# Copy pages from reader to writer
for rpagenum in range(readerNumPages):
Expand Down Expand Up @@ -1386,7 +1386,8 @@ def close(self):
and callable(self._stream.close):
self._stream.close()

def getDocumentInfo(self):
@property
def documentInfo(self):
"""
Retrieves the PDF file's document information dictionary, if it exists.
Note that some PDF files use metadata streams instead of docinfo
Expand All @@ -1405,13 +1406,8 @@ def getDocumentInfo(self):

return retval

documentInfo = property(getDocumentInfo)
"""
Read-only property that accesses the
:meth:`getDocumentInfo()<PdfFileReader.getDocumentInfo>` function.
"""

def getXmpMetadata(self):
@property
def xmpMetadata(self):
"""
Retrieves XMP (Extensible Metadata Platform) data from the PDF document
root.
Expand All @@ -1427,13 +1423,8 @@ def getXmpMetadata(self):
finally:
self._overrideEncryption = False

xmpMetadata = property(getXmpMetadata)
"""
Read-only property that accesses the
:meth:`getXmpMetadata()<PdfFileReader.getXmpMetadata>` function.
"""

def getNumPages(self):
@property
def numPages(self):
"""
Calculates the number of pages in this PDF file.
Expand Down Expand Up @@ -1461,12 +1452,6 @@ def getNumPages(self):

return len(self._flattenedPages)

numPages = property(getNumPages)
"""
Read-only property that accesses the
:meth:`getNumPages()<PdfFileReader.getNumPages>` function.
"""

def getPage(self, pageNumber):
"""
Retrieves a page by number from this PDF file.
Expand Down Expand Up @@ -1580,7 +1565,8 @@ def _writeField(self, fileobj, field, fieldAttributes):
# Field attribute is N/A or unknown, so don't write anything
pass

def getFormTextFields(self):
@property
def formTextFields(self):
"""
Retrieves form fields from the document with textual data (inputs,
dropdowns).
Expand Down Expand Up @@ -1635,13 +1621,6 @@ def getNamedDestinations(self, tree=None, retval=None):

return retval

namedDestinations = property(getNamedDestinations)
"""
Read-only property that accesses the
:meth:`getNamedDestinations()<PdfFileReader.getNamedDestinations>`
function.
"""

def getOutlines(self, node=None, outlines=None):
"""
Retrieves the document outline present in the document.
Expand Down Expand Up @@ -1691,12 +1670,6 @@ def getOutlines(self, node=None, outlines=None):

return outlines

outlines = property(getOutlines)
"""
Read-only property that accesses the
:meth:`getOutlines()<PdfFileReader.getOutlines>` function.
"""

def _getPageNumberByIndirect(self, indirectRef):
"""Generate _pageId2Num"""
if self._pageId2Num is None:
Expand Down Expand Up @@ -1773,16 +1746,17 @@ def _buildOutline(self, node):

pages = property(
lambda self: ConvertFunctionsToVirtualList(
self.getNumPages, self.getPage
lambda: self.numPages, self.getPage
)
)
"""
Read-only property that emulates a list based upon the
:meth:`getNumPages()<PdfFileReader.getNumPages>` and
:meth:`numPages<PdfFileReader.numPages>` and
:meth:`getPage()<PdfFileReader.getPage>` methods.
"""

def getPageLayout(self):
@property
def pageLayout(self):
"""
Get the page layout.
See :meth:`setPageLayout()<PdfFileWriter.setPageLayout>`
Expand All @@ -1796,13 +1770,8 @@ def getPageLayout(self):
except KeyError:
return None

pageLayout = property(getPageLayout)
"""
Read-only property accessing the
:meth:`getPageLayout()<PdfFileReader.getPageLayout>` method.
"""

def getPageMode(self):
@property
def pageMode(self):
"""
Get the page mode.
See :meth:`setPageMode()<PdfFileWriter.setPageMode>`
Expand All @@ -1816,12 +1785,6 @@ def getPageMode(self):
except KeyError:
return None

pageMode = property(getPageMode)
"""
Read-only property accessing the
:meth:`getPageMode()<PdfFileReader.getPageMode>` method.
"""

def _flatten(self, pages=None, inherit=None, indirectRef=None):
inheritablePageAttributes = (
NameObject("/Resources"), NameObject("/MediaBox"),
Expand Down Expand Up @@ -2641,16 +2604,10 @@ def _authenticateUserPassword(self, password):

return U == real_U, key

def getIsEncrypted(self):
@property
def isEncrypted(self):
return "/Encrypt" in self._trailer

isEncrypted = property(getIsEncrypted)
"""
Read-only boolean property showing whether this PDF file is encrypted.
Note that this property, if True, will remain True even after the
:meth:`decrypt()<PdfFileReader.decrypt>` method is called.
"""


def _convertToInt(d, size):
if size > 8:
Expand Down
2 changes: 1 addition & 1 deletion pypdf/xmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
class XmpInformation(PdfObject):
"""
An object that represents Adobe XMP metadata. Usually accessed by
:meth:`getXmpMetadata()<pypdf.PdfFileReader.getXmpMetadata>`
:meth:`xmpMetadata()<pypdf.PdfFileReader.xmpMetadata>`
"""
def __init__(self, stream):
self.stream = stream
Expand Down
2 changes: 1 addition & 1 deletion samplecode/basic_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def main():
exit(1)
else:
print(
"'%s' has %d pages... OK" % (filename, reader.getNumPages())
"'%s' has %d pages... OK" % (filename, reader.numPages)
)

# Add page 1 from reader to output document, unchanged
Expand Down
4 changes: 2 additions & 2 deletions scripts/2-up.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def main():
input1 = PdfFileReader(open(sys.argv[1], "rb"))
output = PdfFileWriter()

for iter in range(0, input1.getNumPages() - 1, 2):
for iter in range(0, input1.numPages - 1, 2):
lhs = input1.getPage(iter)
rhs = input1.getPage(iter+1)
lhs.mergeTranslatedPage(rhs, lhs.mediaBox.getUpperRight_x(), 0, True)
Expand All @@ -51,7 +51,7 @@ def main():
input1 = PdfFileReader(open(sys.argv[1], "rb"))
output = PdfFileWriter()

for i in range (0, input1.getNumPages()-1, 2):
for i in range (0, input1.numPages - 1, 2):
lhs = input1.getPage(i)
rhs = input1.getPage(i + 1)
lhs.mergeTranslatedPage(rhs, lhs.mediaBox.getUpperRight_x(), 0, True)
Expand Down
2 changes: 1 addition & 1 deletion scripts/pdfcat
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ if __name__ == "__main__":
fallbackName = fallbackName[:fallbackName.rfind(".")]

merger.addBookmark(
getattr(r.getDocumentInfo(), "title", fallbackName)
getattr(r.documentInfo, "title", fallbackName)
or fallbackName, curr_page
)

Expand Down
22 changes: 18 additions & 4 deletions tests/test_pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,19 +401,33 @@ def _parseXRefTable(filepath, mask=tuple()):
def testProperties(self):
"""
The switch from PyPDF2 to PyPDF4 sees many stylistic changes, including
the use of the @property decorator (where possible) and pruning out
of unnecessary arguments to property() as a function.
the use of the ``@property`` decorator (where possible) and pruning out
of unnecessary arguments to ``property()`` as a function.
In some cases, functions that previously had a ``@property`` accessor
have it no more (to remove duplicate accesses).
This test ensures that the two styles, the older and the newer, are
functionally equivalent.
"""
properties = (
"documentInfo", "xmpMetadata", "numPages", "namedDestinations",
"outlines", "pages", "pageLayout", "pageMode", "isEncrypted"
"documentInfo", "xmpMetadata", "numPages", "pages", "pageLayout",
"pageMode", "isEncrypted"
)
methods = ("getNamedDestinations", "getOutlines")

for p in properties:
self.assertIsInstance(getattr(PdfFileReader, p), property)

for m in methods:
self.assertTrue(
hasattr(PdfFileReader, m),
"%s() is not part of %s" % (m, PdfFileReader.__name__)
)
self.assertTrue(
callable(getattr(PdfFileReader, m)),
"%s.%s() is not callable" % (PdfFileReader.__name__, m)
)


class AddJsTestCase(unittest.TestCase):
def setUp(self):
Expand Down

0 comments on commit f020613

Please sign in to comment.