Skip to content

Commit

Permalink
DEP: Rename names to be PEP8-compliant
Browse files Browse the repository at this point in the history
PdfWriter.get_page: the pageNumber parameter is renamed to page_number
PyPDF2.generic:

* readHexStringFromStream ➔ read_hex_string_from_stream
* TreeObject.emptyTree ➔ TreeObject.empty_tree

xmp:

* XmpInformation.rdfRoot ➔ XmpInformation.rdf_root
* XmpInformation.xmp_createDate ➔ XmpInformation.xmp_create_date
* XmpInformation.xmp_creatorTool ➔ XmpInformation.xmp_creator_tool
* XmpInformation.xmp_metadataDate ➔ XmpInformation.xmp_metadata_date
* XmpInformation.xmp_modifyDate ➔ XmpInformation.xmp_modify_date
* XmpInformation.xmpMetadata ➔ XmpInformation.xmp_metadata
* XmpInformation.xmpmm_documentId ➔ XmpInformation.xmpmm_document_id
* XmpInformation.xmpmm_instanceId ➔ XmpInformation.xmpmm_instance_id
  • Loading branch information
MartinThoma committed Jun 9, 2022
1 parent 336d659 commit 24e2ac4
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 45 deletions.
20 changes: 16 additions & 4 deletions PyPDF2/_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,18 +215,30 @@ def insertPage(self, page: PageObject, index: int = 0) -> None: # pragma: no co
deprecate_with_replacement("insertPage", "insert_page")
self.insert_page(page, index)

def get_page(self, pageNumber: int) -> PageObject: # TODO: PEP8
def get_page(
self, page_number: Optional[int] = None, pageNumber: Optional[int] = None
) -> PageObject:
"""
Retrieve a page by number from this PDF file.
:param int pageNumber: The page number to retrieve
:param int page_number: The page number to retrieve
(pages begin at zero)
:return: the page at the index given by *pageNumber*
:return: the page at the index given by *page_number*
:rtype: :class:`PageObject<PyPDF2._page.PageObject>`
"""
if pageNumber is not None:
if page_number is not None:
raise ValueError("Please only use the page_number parameter")
else:
deprecate_with_replacement(
"get_page(pageNumber)", "get_page(page_number)", "4.0.0"
)
page_number = pageNumber
if page_number is None and pageNumber is None:
raise ValueError("Please specify the page_number")
pages = cast(Dict[str, Any], self.get_object(self._pages))
# XXX: crude hack
return pages[PA.KIDS][pageNumber].get_object()
return pages[PA.KIDS][page_number].get_object()

def getPage(self, pageNumber: int) -> PageObject: # pragma: no cover
"""
Expand Down
12 changes: 4 additions & 8 deletions PyPDF2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,8 @@ def compress(data: bytes) -> bytes:
class FlateDecode:
@staticmethod
def decode(
# TODO: PEP8
data: bytes,
decodeParms: Union[None, ArrayObject, DictionaryObject],
decodeParms: Union[None, ArrayObject, DictionaryObject], # TODO: PEP8
) -> bytes:
"""
:param data: flate-encoded data.
Expand Down Expand Up @@ -171,9 +170,8 @@ class ASCIIHexDecode:

@staticmethod
def decode(
# TODO: PEP8
data: str,
decodeParms: Union[None, ArrayObject, DictionaryObject] = None,
decodeParms: Union[None, ArrayObject, DictionaryObject] = None, # TODO: PEP8
) -> str:
"""
:param data: a str sequence of hexadecimal-encoded values to be
Expand Down Expand Up @@ -289,9 +287,8 @@ def decode(self) -> str:

@staticmethod
def decode(
# TODO: PEP8
data: bytes,
decodeParms: Union[None, ArrayObject, DictionaryObject] = None,
decodeParms: Union[None, ArrayObject, DictionaryObject] = None, # TODO: PEP8
) -> str:
"""
:param data: ``bytes`` or ``str`` text to decode.
Expand Down Expand Up @@ -404,8 +401,7 @@ def _get_parameters(
@staticmethod
def decode(
data: bytes,
# TODO: PEP8
decodeParms: Union[None, ArrayObject, DictionaryObject] = None,
decodeParms: Union[None, ArrayObject, DictionaryObject] = None, # TODO: PEP8
height: int = 0,
) -> bytes:
parms = CCITTFaxDecode._get_parameters(decodeParms, height)
Expand Down
30 changes: 25 additions & 5 deletions PyPDF2/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,16 @@ def readFromStream(
return NumberObject.read_from_stream(stream)


def readHexStringFromStream( # TODO: PEP8
def readHexStringFromStream(
stream: StreamType,
) -> Union["TextStringObject", "ByteStringObject"]:
deprecate_with_replacement(
"readHexStringFromStream", "read_hex_string_from_stream", "4.0.0"
)
return read_hex_string_from_stream(stream)


def read_hex_string_from_stream(
stream: StreamType,
) -> Union["TextStringObject", "ByteStringObject"]:
stream.read(1)
Expand All @@ -380,7 +389,15 @@ def readHexStringFromStream( # TODO: PEP8
return createStringObject(b_(txt))


def readStringFromStream( # TODO: PEP8
def readStringFromStream(
stream: StreamType,
forced_encoding: Union[None, str, List[str], Dict[int, str]] = None,
) -> Union["TextStringObject", "ByteStringObject"]:
deprecate_with_replacement("readStringFromStream", "read_string_from_stream")
return read_string_from_stream(stream, forced_encoding)


def read_string_from_stream(
stream: StreamType,
forced_encoding: Union[None, str, List[str], Dict[int, str]] = None,
) -> Union["TextStringObject", "ByteStringObject"]:
Expand Down Expand Up @@ -941,7 +958,10 @@ def remove_child(self, child: Any) -> None:
del child_obj[NameObject("/Prev")]

def emptyTree(self) -> None:
# TODO: Missing rename
deprecate_with_replacement("emptyTree", "empty_tree", "4.0.0")
self.empty_tree()

def empty_tree(self) -> None:
for child in self:
child_obj = child.get_object()
del child_obj[NameObject("/Parent")]
Expand Down Expand Up @@ -1251,13 +1271,13 @@ def read_object(
if peek == b_("<<"):
return DictionaryObject.read_from_stream(stream, pdf, forced_encoding)
else:
return readHexStringFromStream(stream)
return read_hex_string_from_stream(stream)
elif idx == 2:
return ArrayObject.read_from_stream(stream, pdf, forced_encoding)
elif idx == 3 or idx == 4:
return BooleanObject.read_from_stream(stream)
elif idx == 5:
return readStringFromStream(stream, forced_encoding)
return read_string_from_stream(stream, forced_encoding)
elif idx == 6:
return NullObject.read_from_stream(stream)
elif idx == 7:
Expand Down
89 changes: 74 additions & 15 deletions PyPDF2/xmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,16 @@ class XmpInformation(PdfObject):
def __init__(self, stream: ContentStream) -> None:
self.stream = stream
doc_root: Document = parseString(self.stream.get_data())
self.rdfRoot: XmlElement = doc_root.getElementsByTagNameNS( # TODO: PEP8
self.rdf_root: XmlElement = doc_root.getElementsByTagNameNS(
RDF_NAMESPACE, "RDF"
)[0]
self.cache: Dict[Any, Any] = {}

@property
def rdfRoot(self) -> XmlElement:
deprecate_with_replacement("rdfRoot", "rdf_root", "4.0.0")
return self.rdf_root

def write_to_stream(
self, stream: StreamType, encryption_key: Union[None, str, bytes]
) -> None:
Expand All @@ -226,7 +231,7 @@ def writeToStream(
self.write_to_stream(stream, encryption_key)

def get_element(self, about_uri: str, namespace: str, name: str) -> Iterator[Any]:
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
for desc in self.rdf_root.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == about_uri:
attr = desc.getAttributeNodeNS(namespace, name)
if attr is not None:
Expand All @@ -245,7 +250,7 @@ def getElement(
return self.get_element(aboutUri, namespace, name)

def get_nodes_in_namespace(self, about_uri: str, namespace: str) -> Iterator[Any]:
for desc in self.rdfRoot.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
for desc in self.rdf_root.getElementsByTagNameNS(RDF_NAMESPACE, "Description"):
if desc.getAttributeNS(RDF_NAMESPACE, "about") == about_uri:
for i in range(desc.attributes.length):
attr = desc.attributes.item(i)
Expand Down Expand Up @@ -370,26 +375,43 @@ def _get_text(self, element: XmlElement) -> str:
The name of the tool that created the PDF document.
"""

# TODO: PEP8
xmp_createDate = property(
xmp_create_date = property(
_getter_single(XMP_NAMESPACE, "CreateDate", _converter_date)
)
"""
The date and time the resource was originally created. The date and
time are returned as a UTC datetime.datetime object.
"""

# TODO: PEP8
xmp_modifyDate = property(
@property
def xmp_createDate(self) -> datetime.datetime:
deprecate_with_replacement("xmp_createDate", "xmp_create_date")
return self.xmp_create_date

@xmp_createDate.setter
def xmp_createDate(self, value: datetime.datetime):
deprecate_with_replacement("xmp_createDate", "xmp_create_date")
self.xmp_create_date = value

xmp_modify_date = property(
_getter_single(XMP_NAMESPACE, "ModifyDate", _converter_date)
)
"""
The date and time the resource was last modified. The date and time
are returned as a UTC datetime.datetime object.
"""

# TODO: PEP8
xmp_metadataDate = property(
@property
def xmp_modifyDate(self) -> datetime.datetime:
deprecate_with_replacement("xmp_modifyDate", "xmp_modify_date")
return self.xmp_modify_date

@xmp_modifyDate.setter
def xmp_modifyDate(self, value: datetime.datetime):
deprecate_with_replacement("xmp_modifyDate", "xmp_modify_date")
self.xmp_modify_date = value

xmp_metadata_date = property(
_getter_single(XMP_NAMESPACE, "MetadataDate", _converter_date)
)
"""
Expand All @@ -398,25 +420,62 @@ def _get_text(self, element: XmlElement) -> str:
object.
"""

# TODO: PEP8
xmp_creatorTool = property(_getter_single(XMP_NAMESPACE, "CreatorTool"))
@property
def xmp_metadataDate(self) -> datetime.datetime:
deprecate_with_replacement("xmp_metadataDate", "xmp_metadata_date")
return self.xmp_metadata_date

@xmp_metadataDate.setter
def xmp_metadataDate(self, value: datetime.datetime):
deprecate_with_replacement("xmp_metadataDate", "xmp_metadata_date")
self.xmp_metadata_date = value

xmp_creator_tool = property(_getter_single(XMP_NAMESPACE, "CreatorTool"))
"""
The name of the first known tool used to create the resource.
"""

# TODO: PEP8
xmpmm_documentId = property(_getter_single(XMPMM_NAMESPACE, "DocumentID"))
@property
def xmp_creatorTool(self) -> str:
deprecate_with_replacement("xmp_creatorTool", "xmp_creator_tool")
return self.xmp_creator_tool

@xmp_creatorTool.setter
def xmp_creatorTool(self, value: str):
deprecate_with_replacement("xmp_creatorTool", "xmp_creator_tool")
self.xmp_creator_tool = value

xmpmm_document_id = property(_getter_single(XMPMM_NAMESPACE, "DocumentID"))
"""
The common identifier for all versions and renditions of this resource.
"""

# TODO: PEP8
xmpmm_instanceId = property(_getter_single(XMPMM_NAMESPACE, "InstanceID"))
@property
def xmpmm_documentId(self) -> str:
deprecate_with_replacement("xmpmm_documentId", "xmpmm_document_id")
return self.xmpmm_document_id

@xmpmm_documentId.setter
def xmpmm_documentId(self, value: str):
deprecate_with_replacement("xmpmm_documentId", "xmpmm_document_id")
self.xmpmm_document_id = value

xmpmm_instance_id = property(_getter_single(XMPMM_NAMESPACE, "InstanceID"))
"""
An identifier for a specific incarnation of a document, updated each
time a file is saved.
"""

@property
def xmpmm_instanceId(self) -> str:
deprecate_with_replacement("xmpmm_instanceId", "xmpmm_instance_id")
return self.xmpmm_instance_id

@xmpmm_instanceId.setter
def xmpmm_instanceId(self, value: str):
deprecate_with_replacement("xmpmm_instanceId", "xmpmm_instance_id")
self.xmpmm_instance_id = value

@property
def custom_properties(self) -> Dict[Any, Any]:
"""
Expand Down
2 changes: 1 addition & 1 deletion make_changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def main(changelog_path: str):
changes = get_formatted_changes(git_tag)
print("-" * 80)
print(changes)
# TODO: Write changes to changelog

new_version = version_bump(git_tag)
today = datetime.now()
header = f"Version {new_version}, {today:%Y-%m-%d}\n"
Expand Down
22 changes: 11 additions & 11 deletions tests/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
TreeObject,
createStringObject,
encode_pdfdocencoding,
read_hex_string_from_stream,
read_object,
readHexStringFromStream,
readStringFromStream,
read_string_from_stream,
)

TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
Expand Down Expand Up @@ -115,43 +115,43 @@ def test_indirect_object_premature(value):

def test_readHexStringFromStream():
stream = BytesIO(b"a1>")
assert readHexStringFromStream(stream) == "\x10"
assert read_hex_string_from_stream(stream) == "\x10"


def test_readHexStringFromStream_exception():
stream = BytesIO(b"")
with pytest.raises(PdfStreamError) as exc:
readHexStringFromStream(stream)
read_hex_string_from_stream(stream)
assert exc.value.args[0] == "Stream has ended unexpectedly"


def test_readStringFromStream_exception():
stream = BytesIO(b"x")
with pytest.raises(PdfStreamError) as exc:
readStringFromStream(stream)
read_string_from_stream(stream)
assert exc.value.args[0] == "Stream has ended unexpectedly"


def test_readStringFromStream_not_in_escapedict_no_digit():
stream = BytesIO(b"x\\y")
with pytest.raises(PdfReadError) as exc:
readStringFromStream(stream)
read_string_from_stream(stream)
assert exc.value.args[0] == "Stream has ended unexpectedly"


def test_readStringFromStream_multichar_eol():
stream = BytesIO(b"x\\\n )")
assert readStringFromStream(stream) == " "
assert read_string_from_stream(stream) == " "


def test_readStringFromStream_multichar_eol2():
stream = BytesIO(b"x\\\n\n)")
assert readStringFromStream(stream) == ""
assert read_string_from_stream(stream) == ""


def test_readStringFromStream_excape_digit():
stream = BytesIO(b"x\\1a )")
assert readStringFromStream(stream) == "\x01 "
assert read_string_from_stream(stream) == "\x01 "


def test_NameObject():
Expand Down Expand Up @@ -179,7 +179,7 @@ def test_destination_fit_r():
assert d.top == FloatObject(0)
assert d.bottom == FloatObject(0)
assert list(d) == []
d.emptyTree()
d.empty_tree()


def test_destination_fit_v():
Expand Down Expand Up @@ -401,4 +401,4 @@ def test_remove_child_in_tree():
tree.add_child(obj, writer)
tree.remove_child(obj)
tree.add_child(obj, writer)
tree.emptyTree()
tree.empty_tree()
2 changes: 1 addition & 1 deletion tests/test_xmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_regression_issue774():
def test_regression_issue914():
path = os.path.join(RESOURCE_ROOT, "issue-914-xmp-data.pdf")
reader = PdfReader(path)
assert reader.xmp_metadata.xmp_modifyDate == datetime(2022, 4, 9, 15, 22, 43)
assert reader.xmp_metadata.xmp_modify_date == datetime(2022, 4, 9, 15, 22, 43)


@pytest.mark.parametrize(
Expand Down

0 comments on commit 24e2ac4

Please sign in to comment.