From c5dfb5005d981961f9001647417802cd48e982b6 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 00:17:00 +0100 Subject: [PATCH 01/10] MAINT: Deprecate features with PyPDF2==3.0.0 --- PyPDF2/_merger.py | 18 ++++---- PyPDF2/_page.py | 80 ++++++++++++++++++++---------------- PyPDF2/_reader.py | 5 ++- PyPDF2/_utils.py | 34 ++++++++++++++- PyPDF2/errors.py | 6 +++ PyPDF2/generic/_outline.py | 4 +- PyPDF2/generic/_rectangle.py | 4 +- 7 files changed, 101 insertions(+), 50 deletions(-) diff --git a/PyPDF2/_merger.py b/PyPDF2/_merger.py index 338584b5c..3b09ae3c0 100644 --- a/PyPDF2/_merger.py +++ b/PyPDF2/_merger.py @@ -47,7 +47,7 @@ from ._utils import ( StrByteType, deprecate_bookmark, - deprecate_with_replacement, + deprecation_with_replacement, str_, ) from ._writer import PdfWriter @@ -375,7 +375,7 @@ def addMetadata(self, infos: Dict[str, Any]) -> None: # pragma: no cover Use :meth:`add_metadata` instead. """ - deprecate_with_replacement("addMetadata", "add_metadata") + deprecation_with_replacement("addMetadata", "add_metadata") self.add_metadata(infos) def setPageLayout(self, layout: LayoutType) -> None: # pragma: no cover @@ -384,7 +384,7 @@ def setPageLayout(self, layout: LayoutType) -> None: # pragma: no cover Use :meth:`set_page_layout` instead. """ - deprecate_with_replacement("setPageLayout", "set_page_layout") + deprecation_with_replacement("setPageLayout", "set_page_layout") self.set_page_layout(layout) def set_page_layout(self, layout: LayoutType) -> None: @@ -421,7 +421,7 @@ def setPageMode(self, mode: PagemodeType) -> None: # pragma: no cover Use :meth:`set_page_mode` instead. """ - deprecate_with_replacement("setPageMode", "set_page_mode") + deprecation_with_replacement("setPageMode", "set_page_mode", "3.0.0") self.set_page_mode(mode) def set_page_mode(self, mode: PagemodeType) -> None: @@ -723,7 +723,7 @@ def addBookmark( .. deprecated:: 1.28.0 Use :meth:`add_outline_item` instead. """ - deprecate_with_replacement("addBookmark", "add_outline_item") + deprecation_with_replacement("addBookmark", "add_outline_item", "3.0.0") return self.add_outline_item( title, pagenum, @@ -749,7 +749,7 @@ def add_bookmark( .. deprecated:: 2.9.0 Use :meth:`add_outline_item` instead. """ - deprecate_with_replacement("addBookmark", "add_outline_item") + deprecation_with_replacement("addBookmark", "add_outline_item", "3.0.0") return self.add_outline_item( title, pagenum, @@ -765,7 +765,9 @@ def addNamedDestination(self, title: str, pagenum: int) -> None: # pragma: no c .. deprecated:: 1.28.0 Use :meth:`add_named_destination` instead. """ - deprecate_with_replacement("addNamedDestination", "add_named_destination") + deprecation_with_replacement( + "addNamedDestination", "add_named_destination", "3.0.0" + ) return self.add_named_destination(title, pagenum) def add_named_destination( @@ -805,7 +807,7 @@ def add_named_destination( class PdfFileMerger(PdfMerger): # pragma: no cover def __init__(self, *args: Any, **kwargs: Any) -> None: - deprecate_with_replacement("PdfFileMerger", "PdfMerger") + deprecation_with_replacement("PdfFileMerger", "PdfMerger", "3.0.0") if "strict" not in kwargs and len(args) < 1: kwargs["strict"] = True # maintain the default diff --git a/PyPDF2/_page.py b/PyPDF2/_page.py index e944947b3..86a129eb1 100644 --- a/PyPDF2/_page.py +++ b/PyPDF2/_page.py @@ -50,8 +50,8 @@ CompressedTransformationMatrix, File, TransformationMatrixType, - deprecate_no_replacement, - deprecate_with_replacement, + deprecation_no_replacement, + deprecation_with_replacement, logger_warning, matrix_multiply, ) @@ -132,7 +132,7 @@ def _get_rectangle(self: Any, name: str, defaults: Iterable[str]) -> RectangleOb def getRectangle( self: Any, name: str, defaults: Iterable[str] ) -> RectangleObject: # pragma: no cover - deprecate_no_replacement("getRectangle") + deprecation_no_replacement("getRectangle", "3.0.0") return _get_rectangle(self, name, defaults) @@ -144,7 +144,7 @@ def _set_rectangle(self: Any, name: str, value: Union[RectangleObject, float]) - def setRectangle( self: Any, name: str, value: Union[RectangleObject, float] ) -> None: # pragma: no cover - deprecate_no_replacement("setRectangle") + deprecation_no_replacement("setRectangle", "3.0.0") _set_rectangle(self, name, value) @@ -153,7 +153,7 @@ def _delete_rectangle(self: Any, name: str) -> None: def deleteRectangle(self: Any, name: str) -> None: # pragma: no cover - deprecate_no_replacement("deleteRectangle") + deprecation_no_replacement("deleteRectangle", "3.0.0") del self[name] @@ -168,7 +168,7 @@ def _create_rectangle_accessor(name: str, fallback: Iterable[str]) -> property: def createRectangleAccessor( name: str, fallback: Iterable[str] ) -> property: # pragma: no cover - deprecate_no_replacement("createRectangleAccessor") + deprecation_no_replacement("createRectangleAccessor", "3.0.0") return _create_rectangle_accessor(name, fallback) @@ -385,7 +385,7 @@ def createBlankPage( Use :meth:`create_blank_page` instead. """ - deprecate_with_replacement("createBlankPage", "create_blank_page") + deprecation_with_replacement("createBlankPage", "create_blank_page", "3.0.0") return PageObject.create_blank_page(pdf, width, height) @property @@ -476,7 +476,7 @@ def rotate(self, angle: int) -> "PageObject": return self def rotate_clockwise(self, angle: int) -> "PageObject": # pragma: no cover - deprecate_with_replacement("rotate_clockwise", "rotate") + deprecation_with_replacement("rotate_clockwise", "rotate", "3.0.0") return self.rotate(angle) def rotateClockwise(self, angle: int) -> "PageObject": # pragma: no cover @@ -485,7 +485,7 @@ def rotateClockwise(self, angle: int) -> "PageObject": # pragma: no cover Use :meth:`rotate_clockwise` instead. """ - deprecate_with_replacement("rotateClockwise", "rotate") + deprecation_with_replacement("rotateClockwise", "rotate", "3.0.0") return self.rotate(angle) def rotateCounterClockwise(self, angle: int) -> "PageObject": # pragma: no cover @@ -494,7 +494,7 @@ def rotateCounterClockwise(self, angle: int) -> "PageObject": # pragma: no cove Use :meth:`rotate_clockwise` with a negative argument instead. """ - deprecate_with_replacement("rotateCounterClockwise", "rotate") + deprecation_with_replacement("rotateCounterClockwise", "rotate", "3.0.0") return self.rotate(-angle) @staticmethod @@ -590,7 +590,7 @@ def getContents(self) -> Optional[ContentStream]: # pragma: no cover Use :meth:`get_contents` instead. """ - deprecate_with_replacement("getContents", "get_contents") + deprecation_with_replacement("getContents", "get_contents", "3.0.0") return self.get_contents() def merge_page(self, page2: "PageObject", expand: bool = False) -> None: @@ -616,7 +616,7 @@ def mergePage(self, page2: "PageObject") -> None: # pragma: no cover Use :meth:`merge_page` instead. """ - deprecate_with_replacement("mergePage", "merge_page") + deprecation_with_replacement("mergePage", "merge_page", "3.0.0") return self.merge_page(page2) def _merge_page( @@ -783,9 +783,10 @@ def mergeTransformedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeTransformedPage(page2, ctm)", "page2.add_transformation(ctm); page.merge_page(page2)", + "3.0.0", ) if isinstance(ctm, Transformation): ctm = ctm.ctm @@ -816,9 +817,10 @@ def mergeScaledPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeScaledPage(page2, scale, expand)", "page2.add_transformation(Transformation().scale(scale)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().scale(scale, scale) self.mergeTransformedPage(page2, op, expand) @@ -840,9 +842,10 @@ def mergeRotatedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeRotatedPage(page2, rotation, expand)", "page2.add_transformation(Transformation().rotate(rotation)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().rotate(rotation) self.mergeTransformedPage(page2, op, expand) @@ -865,9 +868,10 @@ def mergeTranslatedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeTranslatedPage(page2, tx, ty, expand)", "page2.add_transformation(Transformation().translate(tx, ty)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().translate(tx, ty) self.mergeTransformedPage(page2, op, expand) @@ -896,9 +900,10 @@ def mergeRotatedTranslatedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeRotatedTranslatedPage(page2, rotation, tx, ty, expand)", "page2.add_transformation(Transformation().rotate(rotation).translate(tx, ty)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().translate(-tx, -ty).rotate(rotation).translate(tx, ty) return self.mergeTransformedPage(page2, op, expand) @@ -921,9 +926,10 @@ def mergeRotatedScaledPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeRotatedScaledPage(page2, rotation, scale, expand)", "page2.add_transformation(Transformation().rotate(rotation).scale(scale)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().rotate(rotation).scale(scale, scale) self.mergeTransformedPage(page2, op, expand) @@ -952,9 +958,10 @@ def mergeScaledTranslatedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeScaledTranslatedPage(page2, scale, tx, ty, expand)", "page2.add_transformation(Transformation().scale(scale).translate(tx, ty)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().scale(scale, scale).translate(tx, ty) return self.mergeTransformedPage(page2, op, expand) @@ -986,9 +993,10 @@ def mergeRotatedScaledTranslatedPage( Use :meth:`add_transformation` and :meth:`merge_page` instead. """ - deprecate_with_replacement( + deprecation_with_replacement( "page.mergeRotatedScaledTranslatedPage(page2, rotation, tx, ty, expand)", "page2.add_transformation(Transformation().rotate(rotation).scale(scale)); page.merge_page(page2, expand)", + "3.0.0", ) op = Transformation().rotate(rotation).scale(scale, scale).translate(tx, ty) self.mergeTransformedPage(page2, op, expand) @@ -1057,7 +1065,7 @@ def addTransformation( Use :meth:`add_transformation` instead. """ - deprecate_with_replacement("addTransformation", "add_transformation") + deprecation_with_replacement("addTransformation", "add_transformation", "3.0.0") self.add_transformation(ctm) def scale(self, sx: float, sy: float) -> None: @@ -1127,7 +1135,7 @@ def scaleBy(self, factor: float) -> None: # pragma: no cover Use :meth:`scale_by` instead. """ - deprecate_with_replacement("scaleBy", "scale_by") + deprecation_with_replacement("scaleBy", "scale_by", "3.0.0") self.scale(factor, factor) def scale_to(self, width: float, height: float) -> None: @@ -1148,7 +1156,7 @@ def scaleTo(self, width: float, height: float) -> None: # pragma: no cover Use :meth:`scale_to` instead. """ - deprecate_with_replacement("scaleTo", "scale_to") + deprecation_with_replacement("scaleTo", "scale_to", "3.0.0") self.scale_to(width, height) def compress_content_streams(self) -> None: @@ -1171,7 +1179,9 @@ def compressContentStreams(self) -> None: # pragma: no cover Use :meth:`compress_content_streams` instead. """ - deprecate_with_replacement("compressContentStreams", "compress_content_streams") + deprecation_with_replacement( + "compressContentStreams", "compress_content_streams", "3.0.0" + ) self.compress_content_streams() def _extract_text_old( @@ -1880,7 +1890,7 @@ def extractText( Use :meth:`extract_text` instead. """ - deprecate_with_replacement("extractText", "extract_text") + deprecation_with_replacement("extractText", "extract_text", "3.0.0") return self.extract_text() def _get_fonts(self) -> Tuple[Set[str], Set[str]]: @@ -1909,7 +1919,7 @@ def mediaBox(self) -> RectangleObject: # pragma: no cover Use :py:attr:`mediabox` instead. """ - deprecate_with_replacement("mediaBox", "mediabox") + deprecation_with_replacement("mediaBox", "mediabox", "3.0.0") return self.mediabox @mediaBox.setter @@ -1919,7 +1929,7 @@ def mediaBox(self, value: RectangleObject) -> None: # pragma: no cover Use :py:attr:`mediabox` instead. """ - deprecate_with_replacement("mediaBox", "mediabox") + deprecation_with_replacement("mediaBox", "mediabox", "3.0.0") self.mediabox = value cropbox = _create_rectangle_accessor("/CropBox", (PG.MEDIABOX,)) @@ -1938,12 +1948,12 @@ def cropBox(self) -> RectangleObject: # pragma: no cover Use :py:attr:`cropbox` instead. """ - deprecate_with_replacement("cropBox", "cropbox") + deprecation_with_replacement("cropBox", "cropbox", "3.0.0") return self.cropbox @cropBox.setter def cropBox(self, value: RectangleObject) -> None: # pragma: no cover - deprecate_with_replacement("cropBox", "cropbox") + deprecation_with_replacement("cropBox", "cropbox", "3.0.0") self.cropbox = value bleedbox = _create_rectangle_accessor("/BleedBox", ("/CropBox", PG.MEDIABOX)) @@ -1960,12 +1970,12 @@ def bleedBox(self) -> RectangleObject: # pragma: no cover Use :py:attr:`bleedbox` instead. """ - deprecate_with_replacement("bleedBox", "bleedbox") + deprecation_with_replacement("bleedBox", "bleedbox", "3.0.0") return self.bleedbox @bleedBox.setter def bleedBox(self, value: RectangleObject) -> None: # pragma: no cover - deprecate_with_replacement("bleedBox", "bleedbox") + deprecation_with_replacement("bleedBox", "bleedbox", "3.0.0") self.bleedbox = value trimbox = _create_rectangle_accessor("/TrimBox", ("/CropBox", PG.MEDIABOX)) @@ -1981,12 +1991,12 @@ def trimBox(self) -> RectangleObject: # pragma: no cover Use :py:attr:`trimbox` instead. """ - deprecate_with_replacement("trimBox", "trimbox") + deprecation_with_replacement("trimBox", "trimbox", "3.0.0") return self.trimbox @trimBox.setter def trimBox(self, value: RectangleObject) -> None: # pragma: no cover - deprecate_with_replacement("trimBox", "trimbox") + deprecation_with_replacement("trimBox", "trimbox", "3.0.0") self.trimbox = value artbox = _create_rectangle_accessor("/ArtBox", ("/CropBox", PG.MEDIABOX)) @@ -2003,12 +2013,12 @@ def artBox(self) -> RectangleObject: # pragma: no cover Use :py:attr:`artbox` instead. """ - deprecate_with_replacement("artBox", "artbox") + deprecation_with_replacement("artBox", "artbox", "3.0.0") return self.artbox @artBox.setter def artBox(self, value: RectangleObject) -> None: # pragma: no cover - deprecate_with_replacement("artBox", "artbox") + deprecation_with_replacement("artBox", "artbox", "3.0.0") self.artbox = value @property diff --git a/PyPDF2/_reader.py b/PyPDF2/_reader.py index 914a55317..0f5d65e11 100644 --- a/PyPDF2/_reader.py +++ b/PyPDF2/_reader.py @@ -54,6 +54,7 @@ b_, deprecate_no_replacement, deprecate_with_replacement, + deprecation_no_replacement, logger_warning, read_non_whitespace, read_previous_line, @@ -146,7 +147,7 @@ def getText(self, key: str) -> Optional[str]: # pragma: no cover Use the attributes (e.g. :py:attr:`title` / :py:attr:`author`). """ - deprecate_no_replacement("getText") + deprecation_no_replacement("getText", "3.0.0") return self._get_text(key) @property @@ -1870,7 +1871,7 @@ def readNextEndLine( self, stream: StreamType, limit_offset: int = 0 ) -> bytes: # pragma: no cover """.. deprecated:: 1.28.0""" - deprecate_no_replacement("readNextEndLine") + deprecation_no_replacement("readNextEndLine", "3.0.0") return self.read_next_end_line(stream, limit_offset) def decrypt(self, password: Union[str, bytes]) -> PasswordType: diff --git a/PyPDF2/_utils.py b/PyPDF2/_utils.py index 2dd91e533..62e0fedfe 100644 --- a/PyPDF2/_utils.py +++ b/PyPDF2/_utils.py @@ -59,7 +59,11 @@ except ImportError: from typing_extensions import TypeAlias -from .errors import STREAM_TRUNCATED_PREMATURELY, PdfStreamError +from .errors import ( + STREAM_TRUNCATED_PREMATURELY, + DeprecationError, + PdfStreamError, +) TransformationMatrixType: TypeAlias = Tuple[ Tuple[float, float, float], Tuple[float, float, float], Tuple[float, float, float] @@ -72,7 +76,9 @@ StrByteType = Union[str, StreamType] DEPR_MSG_NO_REPLACEMENT = "{} is deprecated and will be removed in PyPDF2 {}." +DEPR_MSG_NO_REPLACEMENT_HAPPENED = "{} is deprecated and was removed in PyPDF2 {}." DEPR_MSG = "{} is deprecated and will be removed in PyPDF2 3.0.0. Use {} instead." +DEPR_MSG_HAPPENED = "{} is deprecated and was removed in PyPDF2 {}. Use {} instead." def _get_max_pdf_version_header(header1: bytes, header2: bytes) -> bytes: @@ -346,16 +352,42 @@ def deprecate(msg: str, stacklevel: int = 3) -> None: warnings.warn(msg, PendingDeprecationWarning, stacklevel=stacklevel) +def deprecation(msg: str) -> None: + raise DeprecationError(msg) + + def deprecate_with_replacement( old_name: str, new_name: str, removed_in: str = "3.0.0" ) -> None: + """ + Raise an exception that a feature will be removed, but has a replacement. + """ deprecate(DEPR_MSG.format(old_name, new_name, removed_in), 4) +def deprecation_with_replacement( + old_name: str, new_name: str, removed_in: str = "3.0.0" +) -> None: + """ + Raise an exception that a feature was already removed, but has a replacement. + """ + deprecation(DEPR_MSG_HAPPENED.format(old_name, removed_in, new_name)) + + def deprecate_no_replacement(name: str, removed_in: str = "3.0.0") -> None: + """ + Raise an exception that a feature will be removed without replacement. + """ deprecate(DEPR_MSG_NO_REPLACEMENT.format(name, removed_in), 4) +def deprecation_no_replacement(name: str, removed_in: str = "3.0.0") -> None: + """ + Raise an exception that a feature was already removed without replacement. + """ + deprecation(DEPR_MSG_NO_REPLACEMENT_HAPPENED.format(name, removed_in)) + + def logger_warning(msg: str, src: str) -> None: """ Use this instead of logger.warning directly. diff --git a/PyPDF2/errors.py b/PyPDF2/errors.py index d00bc7c12..a84b05691 100644 --- a/PyPDF2/errors.py +++ b/PyPDF2/errors.py @@ -5,6 +5,12 @@ """ +class DeprecationError(Exception): + """Raised when a deprecated feature is used.""" + + pass + + class DependencyError(Exception): pass diff --git a/PyPDF2/generic/_outline.py b/PyPDF2/generic/_outline.py index 0c8b17cdf..c2e72c0ab 100644 --- a/PyPDF2/generic/_outline.py +++ b/PyPDF2/generic/_outline.py @@ -1,6 +1,6 @@ from typing import Any, Union -from .._utils import StreamType, deprecate_with_replacement +from .._utils import StreamType, deprecation_with_replacement from ._base import NameObject from ._data_structures import Destination @@ -31,5 +31,5 @@ def write_to_stream( class Bookmark(OutlineItem): # pragma: no cover def __init__(self, *args: Any, **kwargs: Any) -> None: - deprecate_with_replacement("Bookmark", "OutlineItem") + deprecation_with_replacement("Bookmark", "OutlineItem", "3.0.0") super().__init__(*args, **kwargs) diff --git a/PyPDF2/generic/_rectangle.py b/PyPDF2/generic/_rectangle.py index 2cbd1e2c4..7b0bab809 100644 --- a/PyPDF2/generic/_rectangle.py +++ b/PyPDF2/generic/_rectangle.py @@ -1,7 +1,7 @@ import decimal from typing import Any, List, Tuple, Union -from .._utils import deprecate_no_replacement, deprecate_with_replacement +from .._utils import deprecate_with_replacement, deprecation_no_replacement from ._base import FloatObject, NumberObject from ._data_structures import ArrayObject @@ -42,7 +42,7 @@ def scale(self, sx: float, sy: float) -> "RectangleObject": def ensureIsNumber( self, value: Any ) -> Union[FloatObject, NumberObject]: # pragma: no cover - deprecate_no_replacement("ensureIsNumber") + deprecation_no_replacement("ensureIsNumber", "3.0.0") return self._ensure_is_number(value) def __repr__(self) -> str: From 70fe5cea38da5856cecee82b4d8f236a6a5e7a58 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 09:27:42 +0100 Subject: [PATCH 02/10] Adjust tests --- PyPDF2/_reader.py | 62 ++++++++++++++++++++-------------------- PyPDF2/_utils.py | 2 +- PyPDF2/_writer.py | 14 ++++++--- docs/dev/deprecations.md | 10 +++---- tests/test_generic.py | 5 +++- tests/test_page.py | 20 +++++++------ tests/test_reader.py | 7 +++-- tests/test_utils.py | 2 +- tests/test_writer.py | 14 +++++---- 9 files changed, 76 insertions(+), 60 deletions(-) diff --git a/PyPDF2/_reader.py b/PyPDF2/_reader.py index 7ce53b0b6..f3cdcedda 100644 --- a/PyPDF2/_reader.py +++ b/PyPDF2/_reader.py @@ -53,7 +53,7 @@ StreamType, b_, deprecate_no_replacement, - deprecate_with_replacement, + deprecation_with_replacement, deprecation_no_replacement, logger_warning, read_non_whitespace, @@ -112,7 +112,7 @@ def convert_to_int(d: bytes, size: int) -> Union[int, Tuple[Any, ...]]: def convertToInt( d: bytes, size: int ) -> Union[int, Tuple[Any, ...]]: # pragma: no cover - deprecate_with_replacement("convertToInt", "convert_to_int") + deprecation_with_replacement("convertToInt", "convert_to_int") return convert_to_int(d, size) @@ -383,7 +383,7 @@ def getDocumentInfo(self) -> Optional[DocumentInformation]: # pragma: no cover Use the attribute :py:attr:`metadata` instead. """ - deprecate_with_replacement("getDocumentInfo", "metadata") + deprecation_with_replacement("getDocumentInfo", "metadata", "3.0.0") return self.metadata @property @@ -393,7 +393,7 @@ def documentInfo(self) -> Optional[DocumentInformation]: # pragma: no cover Use the attribute :py:attr:`metadata` instead. """ - deprecate_with_replacement("documentInfo", "metadata") + deprecation_with_replacement("documentInfo", "metadata", "3.0.0") return self.metadata @property @@ -417,7 +417,7 @@ def getXmpMetadata(self) -> Optional[XmpInformation]: # pragma: no cover Use the attribute :py:attr:`xmp_metadata` instead. """ - deprecate_with_replacement("getXmpMetadata", "xmp_metadata") + deprecation_with_replacement("getXmpMetadata", "xmp_metadata", "3.0.0") return self.xmp_metadata @property @@ -427,7 +427,7 @@ def xmpMetadata(self) -> Optional[XmpInformation]: # pragma: no cover Use the attribute :py:attr:`xmp_metadata` instead. """ - deprecate_with_replacement("xmpMetadata", "xmp_metadata") + deprecation_with_replacement("xmpMetadata", "xmp_metadata", "3.0.0") return self.xmp_metadata def _get_num_pages(self) -> int: @@ -454,7 +454,7 @@ def getNumPages(self) -> int: # pragma: no cover Use :code:`len(reader.pages)` instead. """ - deprecate_with_replacement("reader.getNumPages", "len(reader.pages)") + deprecation_with_replacement("reader.getNumPages", "len(reader.pages)", "3.0.0") return self._get_num_pages() @property @@ -464,7 +464,7 @@ def numPages(self) -> int: # pragma: no cover Use :code:`len(reader.pages)` instead. """ - deprecate_with_replacement("reader.numPages", "len(reader.pages)") + deprecation_with_replacement("reader.numPages", "len(reader.pages)", "3.0.0") return self._get_num_pages() def getPage(self, pageNumber: int) -> PageObject: # pragma: no cover @@ -473,8 +473,8 @@ def getPage(self, pageNumber: int) -> PageObject: # pragma: no cover Use :code:`reader.pages[page_number]` instead. """ - deprecate_with_replacement( - "reader.getPage(pageNumber)", "reader.pages[page_number]" + deprecation_with_replacement( + "reader.getPage(pageNumber)", "reader.pages[page_number]", "3.0.0" ) return self._get_page(pageNumber) @@ -500,7 +500,7 @@ def namedDestinations(self) -> Dict[str, Any]: # pragma: no cover Use :py:attr:`named_destinations` instead. """ - deprecate_with_replacement("namedDestinations", "named_destinations") + deprecation_with_replacement("namedDestinations", "named_destinations", "3.0.0") return self.named_destinations @property @@ -570,7 +570,7 @@ def getFields( Use :meth:`get_fields` instead. """ - deprecate_with_replacement("getFields", "get_fields") + deprecation_with_replacement("getFields", "get_fields", "3.0.0") return self.get_fields(tree, retval, fileobj) def _build_field( @@ -665,7 +665,7 @@ def getFormTextFields(self) -> Dict[str, Any]: # pragma: no cover Use :meth:`get_form_text_fields` instead. """ - deprecate_with_replacement("getFormTextFields", "get_form_text_fields") + deprecation_with_replacement("getFormTextFields", "get_form_text_fields", "3.0.0") return self.get_form_text_fields() def _get_named_destinations( @@ -727,7 +727,7 @@ def getNamedDestinations( Use :py:attr:`named_destinations` instead. """ - deprecate_with_replacement("getNamedDestinations", "named_destinations") + deprecation_with_replacement("getNamedDestinations", "named_destinations", "3.0.0") return self._get_named_destinations(tree, retval) @property @@ -747,7 +747,7 @@ def outlines(self) -> OutlineType: # pragma: no cover Use :py:attr:`outline` instead. """ - deprecate_with_replacement("outlines", "outline") + deprecation_with_replacement("outlines", "outline", "3.0.0") return self.outline def _get_outline( @@ -799,7 +799,7 @@ def getOutlines( Use :py:attr:`outline` instead. """ - deprecate_with_replacement("getOutlines", "outline") + deprecation_with_replacement("getOutlines", "outline", "3.0.0") return self._get_outline(node, outline) @property @@ -851,7 +851,7 @@ def getPageNumber(self, page: PageObject) -> int: # pragma: no cover Use :meth:`get_page_number` instead. """ - deprecate_with_replacement("getPageNumber", "get_page_number") + deprecation_with_replacement("getPageNumber", "get_page_number", "3.0.0") return self.get_page_number(page) def get_destination_page_number(self, destination: Destination) -> int: @@ -871,8 +871,8 @@ def getDestinationPageNumber( Use :meth:`get_destination_page_number` instead. """ - deprecate_with_replacement( - "getDestinationPageNumber", "get_destination_page_number" + deprecation_with_replacement( + "getDestinationPageNumber", "get_destination_page_number", "3.0.0" ) return self.get_destination_page_number(destination) @@ -1017,7 +1017,7 @@ def getPageLayout(self) -> Optional[str]: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement("getPageLayout", "page_layout") + deprecation_with_replacement("getPageLayout", "page_layout", "3.0.0") return self.page_layout @property @@ -1027,7 +1027,7 @@ def pageLayout(self) -> Optional[str]: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement("pageLayout", "page_layout") + deprecation_with_replacement("pageLayout", "page_layout", "3.0.0") return self.page_layout @property @@ -1064,7 +1064,7 @@ def getPageMode(self) -> Optional[PagemodeType]: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("getPageMode", "page_mode") + deprecation_with_replacement("getPageMode", "page_mode", "3.0.0") return self.page_mode @property @@ -1074,7 +1074,7 @@ def pageMode(self) -> Optional[PagemodeType]: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("pageMode", "page_mode") + deprecation_with_replacement("pageMode", "page_mode", "3.0.0") return self.page_mode def _flatten( @@ -1322,7 +1322,7 @@ def getObject( Use :meth:`get_object` instead. """ - deprecate_with_replacement("getObject", "get_object") + deprecation_with_replacement("getObject", "get_object", "3.0.0") return self.get_object(indirectReference) def read_object_header(self, stream: StreamType) -> Tuple[int, int]: @@ -1361,7 +1361,7 @@ def readObjectHeader( Use :meth:`read_object_header` instead. """ - deprecate_with_replacement("readObjectHeader", "read_object_header") + deprecation_with_replacement("readObjectHeader", "read_object_header", "3.0.0") return self.read_object_header(stream) def cache_get_indirect_object( @@ -1377,8 +1377,8 @@ def cacheGetIndirectObject( Use :meth:`cache_get_indirect_object` instead. """ - deprecate_with_replacement( - "cacheGetIndirectObject", "cache_get_indirect_object" + deprecation_with_replacement( + "cacheGetIndirectObject", "cache_get_indirect_object", "3.0.0" ) return self.cache_get_indirect_object(generation, idnum) @@ -1403,7 +1403,7 @@ def cacheIndirectObject( Use :meth:`cache_indirect_object` instead. """ - deprecate_with_replacement("cacheIndirectObject", "cache_indirect_object") + deprecation_with_replacement("cacheIndirectObject", "cache_indirect_object") return self.cache_indirect_object(generation, idnum, obj) def read(self, stream: StreamType) -> None: @@ -1927,7 +1927,7 @@ def getIsEncrypted(self) -> bool: # pragma: no cover Use :py:attr:`is_encrypted` instead. """ - deprecate_with_replacement("getIsEncrypted", "is_encrypted") + deprecation_with_replacement("getIsEncrypted", "is_encrypted", "3.0.0") return self.is_encrypted @property @@ -1937,7 +1937,7 @@ def isEncrypted(self) -> bool: # pragma: no cover Use :py:attr:`is_encrypted` instead. """ - deprecate_with_replacement("isEncrypted", "is_encrypted") + deprecation_with_replacement("isEncrypted", "is_encrypted", "3.0.0") return self.is_encrypted @property @@ -1967,7 +1967,7 @@ def xfa(self) -> Optional[Dict[str, Any]]: class PdfFileReader(PdfReader): # pragma: no cover def __init__(self, *args: Any, **kwargs: Any) -> None: - deprecate_with_replacement("PdfFileReader", "PdfReader") + deprecation_with_replacement("PdfFileReader", "PdfReader", "3.0.0") if "strict" not in kwargs and len(args) < 2: kwargs["strict"] = True # maintain the default super().__init__(*args, **kwargs) diff --git a/PyPDF2/_utils.py b/PyPDF2/_utils.py index 62e0fedfe..5f5e73b5f 100644 --- a/PyPDF2/_utils.py +++ b/PyPDF2/_utils.py @@ -349,7 +349,7 @@ def paeth_predictor(left: int, up: int, up_left: int) -> int: def deprecate(msg: str, stacklevel: int = 3) -> None: - warnings.warn(msg, PendingDeprecationWarning, stacklevel=stacklevel) + warnings.warn(msg, DeprecationWarning, stacklevel=stacklevel) def deprecation(msg: str) -> None: diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index db5e394ac..3a5d83f19 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -66,6 +66,7 @@ _get_max_pdf_version_header, b_, deprecate_bookmark, + deprecation_with_replacement, deprecate_with_replacement, logger_warning, ) @@ -1289,7 +1290,7 @@ def add_outline_item_destination( page_destination: Union[None, PageObject, TreeObject] = None, parent: Union[None, TreeObject, IndirectObject] = None, before: Union[None, TreeObject, IndirectObject] = None, - dest: Union[None, PageObject, TreeObject] = None, # deprecated + dest: Union[None, PageObject, TreeObject] = None, # deprecated ) -> IndirectObject: if page_destination is not None and dest is not None: # deprecated raise ValueError( @@ -1893,7 +1894,7 @@ def add_link( fit: FitType = "/Fit", *args: ZoomArgType, ) -> None: - deprecate_with_replacement( + deprecation_with_replacement( "add_link", "add_annotation(AnnotationBuilder.link(...))" ) @@ -2483,7 +2484,9 @@ def _add_articles_thread( pag_obj = cast("PageObject", pag.get_object()) if "/B" not in pag_obj: pag_obj[NameObject("/B")] = ArrayObject() - cast("ArrayObject", pag_obj["/B"]).append(new_article.indirect_reference) + cast("ArrayObject", pag_obj["/B"]).append( + new_article.indirect_reference + ) current_article = cast("DictionaryObject", current_article["/N"]) if current_article == first_article: new_article[NameObject("/N")] = new_first.indirect_reference # type: ignore @@ -2674,7 +2677,10 @@ def find_outline_item( i = 0 while o is not None: - if o.indirect_reference == outline_item or o.get("/Title", None) == outline_item: + if ( + o.indirect_reference == outline_item + or o.get("/Title", None) == outline_item + ): return [i] else: if "/First" in o: diff --git a/docs/dev/deprecations.md b/docs/dev/deprecations.md index f439429f3..89f778e44 100644 --- a/docs/dev/deprecations.md +++ b/docs/dev/deprecations.md @@ -29,14 +29,14 @@ we do it: and when it will happen. The docs let users know about the deprecation and when it will happen and the new function. The CHANGELOG informs about it. -2. `(x+1).0.0`: Remove / change the code in the breaking way, - but keep/add DeprecationWarnings messages. +2. `(x+1).0.0`: Remove / change the code in the breaking way by replacing + DeprecationWarnings by DeprecationErrors. We do this to help people who didn't look at the warnings before. The CHANGELOG informs about it. -3. `(x+2).0.0`: The DeprecationWarnings are removed. +3. `(x+2).0.0`: The DeprecationErrors are removed. -This means the users have 3 warnings in the CHANGELOG, a PendingDeprecationWarning -until the next major release and a DeprecationWarning until the major release +This means the users have 3 warnings in the CHANGELOG, a DeprecationWarning +until the next major release and a DeprecationError until the major release after that. Please note that adding warnings can be a breaking change for some users; most diff --git a/tests/test_generic.py b/tests/test_generic.py index cffacc964..b02692d97 100644 --- a/tests/test_generic.py +++ b/tests/test_generic.py @@ -967,7 +967,10 @@ def test_cloning(caplog): obj3 = obj2.indirect_reference.clone(writer) assert len(writer._objects) == n + 1 assert obj2.indirect_reference == obj3.indirect_reference - assert obj2.indirect_reference == obj2._reference_clone(obj2, writer).indirect_reference + assert ( + obj2.indirect_reference + == obj2._reference_clone(obj2, writer).indirect_reference + ) assert len(writer._objects) == n + 1 assert obj2.indirect_reference == obj3.indirect_reference diff --git a/tests/test_page.py b/tests/test_page.py index 2c2ea3a9f..1674b0248 100644 --- a/tests/test_page.py +++ b/tests/test_page.py @@ -10,7 +10,7 @@ from PyPDF2 import PdfReader, PdfWriter, Transformation from PyPDF2._page import PageObject, set_custom_rtl from PyPDF2.constants import PageAttributes as PG -from PyPDF2.errors import PdfReadWarning +from PyPDF2.errors import PdfReadWarning, DeprecationError from PyPDF2.generic import ( ArrayObject, DictionaryObject, @@ -131,8 +131,10 @@ def test_transformation_equivalence(): # Option 2: The old way page_box2 = deepcopy(page_box) page_base2 = deepcopy(page_base) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page_base2.mergeTransformedPage(page_box2, op, expand=False) + page_box2.add_transformation(op) + page_base2.merge_page(page_box2) # Should be the same assert page_base1[NameObject(PG.CONTENTS)] == page_base2[NameObject(PG.CONTENTS)] @@ -165,21 +167,21 @@ def test_page_transformations(): reader = PdfReader(pdf_path) page: PageObject = reader.pages[0] - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeRotatedPage(page, 90, expand=True) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeRotatedScaledPage(page, 90, 1, expand=True) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeRotatedScaledTranslatedPage( page, 90, scale=1, tx=1, ty=1, expand=True ) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeRotatedTranslatedPage(page, 90, 100, 100, expand=False) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeScaledPage(page, 2, expand=False) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeScaledTranslatedPage(page, 1, 1, 1) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): page.mergeTranslatedPage(page, 100, 100, expand=False) page.add_transformation((1, 0, 0, 0, 0, 0)) diff --git a/tests/test_reader.py b/tests/test_reader.py index 25018ae0f..cb433ca7b 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -12,6 +12,7 @@ from PyPDF2.constants import PageAttributes as PG from PyPDF2.errors import ( EmptyFileError, + DeprecationError, FileNotDecryptedError, PdfReadError, PdfReadWarning, @@ -739,11 +740,11 @@ def test_convert_to_int_error(): def test_convertToInt_deprecated(): msg = ( - "convertToInt is deprecated and will be removed in PyPDF2 3.0.0. " + "convertToInt is deprecated and was removed in PyPDF2 3.0.0. " "Use convert_to_int instead." ) - with pytest.warns( - PendingDeprecationWarning, + with pytest.raises( + DeprecationError, match=msg, ): assert convertToInt(b"\x01", 8) == 1 diff --git a/tests/test_utils.py b/tests/test_utils.py index a5f5fa186..4c64ce01b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -109,7 +109,7 @@ def test_b(): def test_deprecate_no_replacement(): - with pytest.warns(PendingDeprecationWarning) as warn: + with pytest.warns(DeprecationWarning) as warn: PyPDF2._utils.deprecate_no_replacement("foo") error_msg = "foo is deprecated and will be removed in PyPDF2 3.0.0." assert warn[0].message.args[0] == error_msg diff --git a/tests/test_writer.py b/tests/test_writer.py index f179a1443..544cc8c23 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -3,9 +3,10 @@ from pathlib import Path import pytest +import re from PyPDF2 import PageObject, PdfMerger, PdfReader, PdfWriter -from PyPDF2.errors import PageSizeNotDefinedError +from PyPDF2.errors import PageSizeNotDefinedError, DeprecationError from PyPDF2.generic import ( Fit, ArrayObject, @@ -112,7 +113,7 @@ def writer_operate(writer): ) writer.add_blank_page() writer.add_uri(2, "https://example.com", RectangleObject([0, 0, 100, 100])) - with pytest.warns(PendingDeprecationWarning): + with pytest.raises(DeprecationError): writer.add_link(2, 1, RectangleObject([0, 0, 100, 100])) assert writer._get_page_layout() is None writer.page_layout = "broken" @@ -582,9 +583,12 @@ def test_add_link(): for page in reader.pages: writer.add_page(page) - with pytest.warns( - PendingDeprecationWarning, - match="add_link is deprecated and will be removed in PyPDF2", + with pytest.raises( + DeprecationError, + match=( + re.escape("add_link is deprecated and was removed in PyPDF2 3.0.0. " + "Use add_annotation(AnnotationBuilder.link(...)) instead.") + ), ): writer.add_link( 1, From 0c26da12f2061070a29e5a1b9a6ead8542ad6040 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 09:35:54 +0100 Subject: [PATCH 03/10] More --- PyPDF2/_writer.py | 90 ++++++++++++++++++++--------------------- PyPDF2/generic/_base.py | 30 +++++++------- PyPDF2/xmp.py | 20 ++++----- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index 3a5d83f19..38cb06724 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -245,7 +245,7 @@ def getObject( Use :meth:`get_object` instead. """ - deprecate_with_replacement("getObject", "get_object") + deprecation_with_replacement("getObject", "get_object", "3.0.0") return self.get_object(ido) def _add_page( @@ -329,7 +329,7 @@ def addPage( Use :meth:`add_page` instead. """ - deprecate_with_replacement("addPage", "add_page") + deprecation_with_replacement("addPage", "add_page", "3.0.0") return self.add_page(page, excluded_keys) def insert_page( @@ -358,7 +358,7 @@ def insertPage( Use :meth:`insert_page` instead. """ - deprecate_with_replacement("insertPage", "insert_page") + deprecation_with_replacement("insertPage", "insert_page", "3.0.0") return self.insert_page(page, index, excluded_keys) def get_page( @@ -390,7 +390,7 @@ def getPage(self, pageNumber: int) -> PageObject: # pragma: no cover Use :code:`writer.pages[page_number]` instead. """ - deprecate_with_replacement("getPage", "writer.pages[page_number]") + deprecation_with_replacement("getPage", "writer.pages[page_number]", "3.0.0") return self.get_page(pageNumber) def _get_num_pages(self) -> int: @@ -403,7 +403,7 @@ def getNumPages(self) -> int: # pragma: no cover Use :code:`len(writer.pages)` instead. """ - deprecate_with_replacement("getNumPages", "len(writer.pages)") + deprecation_with_replacement("getNumPages", "len(writer.pages)", "3.0.0") return self._get_num_pages() @property @@ -438,7 +438,7 @@ def addBlankPage( Use :meth:`add_blank_page` instead. """ - deprecate_with_replacement("addBlankPage", "add_blank_page") + deprecation_with_replacement("addBlankPage", "add_blank_page", "3.0.0") return self.add_blank_page(width, height) def insert_blank_page( @@ -479,7 +479,7 @@ def insertBlankPage( Use :meth:`insertBlankPage` instead. """ - deprecate_with_replacement("insertBlankPage", "insert_blank_page") + deprecation_with_replacement("insertBlankPage", "insert_blank_page", "3.0.0") return self.insert_blank_page(width, height, index) @property @@ -573,7 +573,7 @@ def addJS(self, javascript: str) -> None: # pragma: no cover Use :meth:`add_js` instead. """ - deprecate_with_replacement("addJS", "add_js") + deprecation_with_replacement("addJS", "add_js", "3.0.0") return self.add_js(javascript) def add_attachment(self, filename: str, data: Union[str, bytes]) -> None: @@ -666,7 +666,7 @@ def addAttachment( Use :meth:`add_attachment` instead. """ - deprecate_with_replacement("addAttachment", "add_attachment") + deprecation_with_replacement("addAttachment", "add_attachment", "3.0.0") return self.add_attachment(fname, fdata) def append_pages_from_reader( @@ -707,7 +707,7 @@ def appendPagesFromReader( Use :meth:`append_pages_from_reader` instead. """ - deprecate_with_replacement("appendPagesFromReader", "append_pages_from_reader") + deprecation_with_replacement("appendPagesFromReader", "append_pages_from_reader", "3.0.0") self.append_pages_from_reader(reader, after_page_append) def update_page_form_field_values( @@ -786,8 +786,8 @@ def updatePageFormFieldValues( Use :meth:`update_page_form_field_values` instead. """ - deprecate_with_replacement( - "updatePageFormFieldValues", "update_page_form_field_values" + deprecation_with_replacement( + "updatePageFormFieldValues", "update_page_form_field_values", "3.0.0" ) return self.update_page_form_field_values(page, fields, flags) @@ -805,8 +805,8 @@ def cloneReaderDocumentRoot(self, reader: PdfReader) -> None: # pragma: no cove Use :meth:`clone_reader_document_root` instead. """ - deprecate_with_replacement( - "cloneReaderDocumentRoot", "clone_reader_document_root" + deprecation_with_replacement( + "cloneReaderDocumentRoot", "clone_reader_document_root", "3.0.0" ) self.clone_reader_document_root(reader) @@ -840,8 +840,8 @@ def cloneDocumentFromReader( Use :meth:`clone_document_from_reader` instead. """ - deprecate_with_replacement( - "cloneDocumentFromReader", "clone_document_from_reader" + deprecation_with_replacement( + "cloneDocumentFromReader", "clone_document_from_reader", "3.0.0" ) self.clone_document_from_reader(reader, after_page_append) @@ -1057,7 +1057,7 @@ def addMetadata(self, infos: Dict[str, Any]) -> None: # pragma: no cover Use :meth:`add_metadata` instead. """ - deprecate_with_replacement("addMetadata", "add_metadata") + deprecation_with_replacement("addMetadata", "add_metadata", "3.0.0") self.add_metadata(infos) def _sweep_indirect_references( @@ -1191,7 +1191,7 @@ def getReference(self, obj: PdfObject) -> IndirectObject: # pragma: no cover Use :meth:`get_reference` instead. """ - deprecate_with_replacement("getReference", "get_reference") + deprecation_with_replacement("getReference", "get_reference", "3.0.0") return self.get_reference(obj) def get_outline_root(self) -> TreeObject: @@ -1238,7 +1238,7 @@ def getOutlineRoot(self) -> TreeObject: # pragma: no cover Use :meth:`get_outline_root` instead. """ - deprecate_with_replacement("getOutlineRoot", "get_outline_root") + deprecation_with_replacement("getOutlineRoot", "get_outline_root", "3.0.0") return self.get_outline_root() def get_named_dest_root(self) -> ArrayObject: @@ -1282,7 +1282,7 @@ def getNamedDestRoot(self) -> ArrayObject: # pragma: no cover Use :meth:`get_named_dest_root` instead. """ - deprecate_with_replacement("getNamedDestRoot", "get_named_dest_root") + deprecation_with_replacement("getNamedDestRoot", "get_named_dest_root", "3.0.0") return self.get_named_dest_root() def add_outline_item_destination( @@ -1330,8 +1330,8 @@ def add_bookmark_destination( Use :meth:`add_outline_item_destination` instead. """ - deprecate_with_replacement( - "add_bookmark_destination", "add_outline_item_destination" + deprecation_with_replacement( + "add_bookmark_destination", "add_outline_item_destination", "3.0.0" ) return self.add_outline_item_destination(dest, parent) @@ -1343,8 +1343,8 @@ def addBookmarkDestination( Use :meth:`add_outline_item_destination` instead. """ - deprecate_with_replacement( - "addBookmarkDestination", "add_outline_item_destination" + deprecation_with_replacement( + "addBookmarkDestination", "add_outline_item_destination", "3.0.0" ) return self.add_outline_item_destination(dest, parent) @@ -1379,7 +1379,7 @@ def add_bookmark_dict( Use :meth:`add_outline_item_dict` instead. """ - deprecate_with_replacement("add_bookmark_dict", "add_outline_item_dict") + deprecation_with_replacement("add_bookmark_dict", "add_outline_item_dict", "3.0.0") return self.add_outline_item_dict(outline_item, parent) @deprecate_bookmark(bookmark="outline_item") @@ -1391,7 +1391,7 @@ def addBookmarkDict( Use :meth:`add_outline_item_dict` instead. """ - deprecate_with_replacement("addBookmarkDict", "add_outline_item_dict") + deprecation_with_replacement("addBookmarkDict", "add_outline_item_dict", "3.0.0") return self.add_outline_item_dict(outline_item, parent) def add_outline_item( @@ -1486,7 +1486,7 @@ def add_bookmark( Use :meth:`add_outline_item` instead. """ - deprecate_with_replacement("add_bookmark", "add_outline_item") + deprecation_with_replacement("add_bookmark", "add_outline_item", "3.0.0") return self.add_outline_item( title, pagenum, @@ -1513,7 +1513,7 @@ def addBookmark( Use :meth:`add_outline_item` instead. """ - deprecate_with_replacement("addBookmark", "add_outline_item") + deprecation_with_replacement("addBookmark", "add_outline_item", "3.0.0") return self.add_outline_item( title, pagenum, @@ -1581,8 +1581,8 @@ def addNamedDestinationObject( Use :meth:`add_named_destination_object` instead. """ - deprecate_with_replacement( - "addNamedDestinationObject", "add_named_destination_object" + deprecation_with_replacement( + "addNamedDestinationObject", "add_named_destination_object", "3.0.0" ) return self.add_named_destination_object(dest) @@ -1633,7 +1633,7 @@ def addNamedDestination( Use :meth:`add_named_destination` instead. """ - deprecate_with_replacement("addNamedDestination", "add_named_destination") + deprecation_with_replacement("addNamedDestination", "add_named_destination", "3.0.0") return self.add_named_destination(title, pagenum) def remove_links(self) -> None: @@ -1651,7 +1651,7 @@ def removeLinks(self) -> None: # pragma: no cover Use :meth:`remove_links` instead. """ - deprecate_with_replacement("removeLinks", "remove_links") + deprecation_with_replacement("removeLinks", "remove_links", "3.0.0") return self.remove_links() def remove_images(self, ignore_byte_string_object: bool = False) -> None: @@ -1739,7 +1739,7 @@ def removeImages( Use :meth:`remove_images` instead. """ - deprecate_with_replacement("removeImages", "remove_images") + deprecation_with_replacement("removeImages", "remove_images", "3.0.0") return self.remove_images(ignoreByteStringObject) def remove_text(self, ignore_byte_string_object: bool = False) -> None: @@ -1794,7 +1794,7 @@ def removeText( Use :meth:`remove_text` instead. """ - deprecate_with_replacement("removeText", "remove_text") + deprecation_with_replacement("removeText", "remove_text", "3.0.0") return self.remove_text(ignoreByteStringObject) def add_uri( @@ -1882,7 +1882,7 @@ def addURI( Use :meth:`add_uri` instead. """ - deprecate_with_replacement("addURI", "add_uri") + deprecation_with_replacement("addURI", "add_uri", "3.0.0") return self.add_uri(pagenum, uri, rect, border) def add_link( @@ -1957,7 +1957,7 @@ def getPageLayout(self) -> Optional[LayoutType]: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement("getPageLayout", "page_layout") + deprecation_with_replacement("getPageLayout", "page_layout", "3.0.0") return self._get_page_layout() def _set_page_layout(self, layout: Union[NameObject, LayoutType]) -> None: @@ -2025,8 +2025,8 @@ def setPageLayout(self, layout: LayoutType) -> None: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement( - "writer.setPageLayout(val)", "writer.page_layout = val" + deprecation_with_replacement( + "writer.setPageLayout(val)", "writer.page_layout = val", "3.0.0" ) return self._set_page_layout(layout) @@ -2066,7 +2066,7 @@ def pageLayout(self) -> Optional[LayoutType]: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement("pageLayout", "page_layout") + deprecation_with_replacement("pageLayout", "page_layout", "3.0.0") return self.page_layout @pageLayout.setter @@ -2076,7 +2076,7 @@ def pageLayout(self, layout: LayoutType) -> None: # pragma: no cover Use :py:attr:`page_layout` instead. """ - deprecate_with_replacement("pageLayout", "page_layout") + deprecation_with_replacement("pageLayout", "page_layout", "3.0.0") self.page_layout = layout _valid_modes = ( @@ -2100,7 +2100,7 @@ def getPageMode(self) -> Optional[PagemodeType]: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("getPageMode", "page_mode") + deprecation_with_replacement("getPageMode", "page_mode", "3.0.0") return self._get_page_mode() def set_page_mode(self, mode: PagemodeType) -> None: @@ -2125,7 +2125,7 @@ def setPageMode(self, mode: PagemodeType) -> None: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("writer.setPageMode(val)", "writer.page_mode = val") + deprecation_with_replacement("writer.setPageMode(val)", "writer.page_mode = val", "3.0.0") self.set_page_mode(mode) @property @@ -2162,7 +2162,7 @@ def pageMode(self) -> Optional[PagemodeType]: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("pageMode", "page_mode") + deprecation_with_replacement("pageMode", "page_mode", "3.0.0") return self.page_mode @pageMode.setter @@ -2172,7 +2172,7 @@ def pageMode(self, mode: PagemodeType) -> None: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecate_with_replacement("pageMode", "page_mode") + deprecation_with_replacement("pageMode", "page_mode", "3.0.0") self.page_mode = mode def add_annotation(self, page_number: int, annotation: Dict[str, Any]) -> None: @@ -2799,5 +2799,5 @@ def _create_outline_item( class PdfFileWriter(PdfWriter): # pragma: no cover def __init__(self, *args: Any, **kwargs: Any) -> None: - deprecate_with_replacement("PdfFileWriter", "PdfWriter") + deprecation_with_replacement("PdfFileWriter", "PdfWriter", "3.0.0") super().__init__(*args, **kwargs) diff --git a/PyPDF2/generic/_base.py b/PyPDF2/generic/_base.py index 872c529ad..00b9c17bf 100644 --- a/PyPDF2/generic/_base.py +++ b/PyPDF2/generic/_base.py @@ -37,7 +37,7 @@ from .._utils import ( StreamType, b_, - deprecate_with_replacement, + deprecation_with_replacement, hex_str, hexencode, logger_warning, @@ -119,7 +119,7 @@ def get_object(self) -> Optional["PdfObject"]: return self def getObject(self) -> Optional["PdfObject"]: # pragma: no cover - deprecate_with_replacement("getObject", "get_object") + deprecation_with_replacement("getObject", "get_object", "3.0.0") return self.get_object() def write_to_stream( @@ -153,7 +153,7 @@ def read_from_stream(stream: StreamType) -> "NullObject": def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) def __repr__(self) -> str: @@ -161,7 +161,7 @@ def __repr__(self) -> str: @staticmethod def readFromStream(stream: StreamType) -> "NullObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return NullObject.read_from_stream(stream) @@ -202,7 +202,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @staticmethod @@ -218,7 +218,7 @@ def read_from_stream(stream: StreamType) -> "BooleanObject": @staticmethod def readFromStream(stream: StreamType) -> "BooleanObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return BooleanObject.read_from_stream(stream) @@ -284,7 +284,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @staticmethod @@ -318,7 +318,7 @@ def read_from_stream(stream: StreamType, pdf: Any) -> "IndirectObject": # PdfRe def readFromStream( stream: StreamType, pdf: Any # PdfReader ) -> "IndirectObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return IndirectObject.read_from_stream(stream, pdf) @@ -363,7 +363,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @@ -397,7 +397,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @staticmethod @@ -411,7 +411,7 @@ def read_from_stream(stream: StreamType) -> Union["NumberObject", "FloatObject"] def readFromStream( stream: StreamType, ) -> Union["NumberObject", "FloatObject"]: # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return NumberObject.read_from_stream(stream) @@ -455,7 +455,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @@ -537,7 +537,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @@ -569,7 +569,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) def renumber(self) -> bytes: @@ -632,7 +632,7 @@ def read_from_stream(stream: StreamType, pdf: Any) -> "NameObject": # PdfReader def readFromStream( stream: StreamType, pdf: Any # PdfReader ) -> "NameObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return NameObject.read_from_stream(stream, pdf) diff --git a/PyPDF2/xmp.py b/PyPDF2/xmp.py index b93b797bd..ffbcb1886 100644 --- a/PyPDF2/xmp.py +++ b/PyPDF2/xmp.py @@ -23,7 +23,7 @@ from xml.dom.minidom import parseString from xml.parsers.expat import ExpatError -from ._utils import StreamType, deprecate_with_replacement +from ._utils import StreamType, deprecate_with_replacement, deprecation_with_replacement from .errors import PdfReadError from .generic import ContentStream, PdfObject @@ -242,7 +242,7 @@ def writeToStream( Use :meth:`write_to_stream` instead. """ - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) def get_element(self, about_uri: str, namespace: str, name: str) -> Iterator[Any]: @@ -261,7 +261,7 @@ def getElement( Use :meth:`get_element` instead. """ - deprecate_with_replacement("getElement", "get_element") + deprecation_with_replacement("getElement", "get_element", "3.0.0") return self.get_element(aboutUri, namespace, name) def get_nodes_in_namespace(self, about_uri: str, namespace: str) -> Iterator[Any]: @@ -283,7 +283,7 @@ def getNodesInNamespace( Use :meth:`get_nodes_in_namespace` instead. """ - deprecate_with_replacement("getNodesInNamespace", "get_nodes_in_namespace") + deprecation_with_replacement("getNodesInNamespace", "get_nodes_in_namespace", "3.0.0") return self.get_nodes_in_namespace(aboutUri, namespace) def _get_text(self, element: XmlElement) -> str: @@ -450,12 +450,12 @@ def xmp_metadataDate(self, value: datetime.datetime) -> None: # pragma: no cove @property def xmp_creatorTool(self) -> str: # pragma: no cover - deprecate_with_replacement("xmp_creatorTool", "xmp_creator_tool") + deprecation_with_replacement("xmp_creatorTool", "xmp_creator_tool", "3.0.0") return self.xmp_creator_tool @xmp_creatorTool.setter def xmp_creatorTool(self, value: str) -> None: # pragma: no cover - deprecate_with_replacement("xmp_creatorTool", "xmp_creator_tool") + deprecation_with_replacement("xmp_creatorTool", "xmp_creator_tool", "3.0.0") self.xmp_creator_tool = value xmpmm_document_id = property(_getter_single(XMPMM_NAMESPACE, "DocumentID")) @@ -465,12 +465,12 @@ def xmp_creatorTool(self, value: str) -> None: # pragma: no cover @property def xmpmm_documentId(self) -> str: # pragma: no cover - deprecate_with_replacement("xmpmm_documentId", "xmpmm_document_id") + deprecation_with_replacement("xmpmm_documentId", "xmpmm_document_id", "3.0.0") return self.xmpmm_document_id @xmpmm_documentId.setter def xmpmm_documentId(self, value: str) -> None: # pragma: no cover - deprecate_with_replacement("xmpmm_documentId", "xmpmm_document_id") + deprecation_with_replacement("xmpmm_documentId", "xmpmm_document_id", "3.0.0") self.xmpmm_document_id = value xmpmm_instance_id = property(_getter_single(XMPMM_NAMESPACE, "InstanceID")) @@ -481,12 +481,12 @@ def xmpmm_documentId(self, value: str) -> None: # pragma: no cover @property def xmpmm_instanceId(self) -> str: # pragma: no cover - deprecate_with_replacement("xmpmm_instanceId", "xmpmm_instance_id") + deprecation_with_replacement("xmpmm_instanceId", "xmpmm_instance_id", "3.0.0") return cast(str, self.xmpmm_instance_id) @xmpmm_instanceId.setter def xmpmm_instanceId(self, value: str) -> None: # pragma: no cover - deprecate_with_replacement("xmpmm_instanceId", "xmpmm_instance_id") + deprecation_with_replacement("xmpmm_instanceId", "xmpmm_instance_id", "3.0.0") self.xmpmm_instance_id = value @property From 6eb2b930726bbc6dd58f4104d23d3cacfbaf81c6 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 09:41:13 +0100 Subject: [PATCH 04/10] Remaining ones --- PyPDF2/generic/_data_structures.py | 47 +++++++++++++------------- PyPDF2/generic/_rectangle.py | 54 +++++++++++++++--------------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/PyPDF2/generic/_data_structures.py b/PyPDF2/generic/_data_structures.py index a60133532..19f5be9fb 100644 --- a/PyPDF2/generic/_data_structures.py +++ b/PyPDF2/generic/_data_structures.py @@ -40,6 +40,7 @@ StreamType, b_, deprecate_with_replacement, + deprecation_with_replacement, hex_str, logger_warning, read_non_whitespace, @@ -121,7 +122,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @staticmethod @@ -153,7 +154,7 @@ def read_from_stream( def readFromStream( stream: StreamType, pdf: Any # PdfReader ) -> "ArrayObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return ArrayObject.read_from_stream(stream, pdf) @@ -295,7 +296,7 @@ def getXmpMetadata( Use :meth:`xmp_metadata` instead. """ - deprecate_with_replacement("getXmpMetadata", "xmp_metadata") + deprecation_with_replacement("getXmpMetadata", "xmp_metadata", "3.0.0") return self.xmp_metadata @property @@ -305,7 +306,7 @@ def xmpMetadata(self) -> Optional[PdfObject]: # pragma: no cover Use :meth:`xmp_metadata` instead. """ - deprecate_with_replacement("xmpMetadata", "xmp_metadata") + deprecation_with_replacement("xmpMetadata", "xmp_metadata", "3.0.0") return self.xmp_metadata def write_to_stream( @@ -322,7 +323,7 @@ def write_to_stream( def writeToStream( self, stream: StreamType, encryption_key: Union[None, str, bytes] ) -> None: # pragma: no cover - deprecate_with_replacement("writeToStream", "write_to_stream") + deprecation_with_replacement("writeToStream", "write_to_stream", "3.0.0") self.write_to_stream(stream, encryption_key) @staticmethod @@ -465,7 +466,7 @@ def read_unsized_from_steam(stream: StreamType, pdf: Any) -> bytes: # PdfReader def readFromStream( stream: StreamType, pdf: Any # PdfReader ) -> "DictionaryObject": # pragma: no cover - deprecate_with_replacement("readFromStream", "read_from_stream") + deprecation_with_replacement("readFromStream", "read_from_stream", "3.0.0") return DictionaryObject.read_from_stream(stream, pdf) @@ -499,7 +500,7 @@ def children(self) -> Iterable[Any]: child = child_ref.get_object() def addChild(self, child: Any, pdf: Any) -> None: # pragma: no cover - deprecate_with_replacement("addChild", "add_child") + deprecation_with_replacement("addChild", "add_child", "3.0.0") self.add_child(child, pdf) def add_child(self, child: Any, pdf: PdfWriterProtocol) -> None: @@ -561,7 +562,7 @@ def inc_parent_counter( inc_parent_counter(self, child_obj.get("/Count", 1)) def removeChild(self, child: Any) -> None: # pragma: no cover - deprecate_with_replacement("removeChild", "remove_child") + deprecation_with_replacement("removeChild", "remove_child", "3.0.0") self.remove_child(child) def _remove_node_from_tree( @@ -707,12 +708,12 @@ def hash_value_data(self) -> bytes: @property def decodedSelf(self) -> Optional["DecodedStreamObject"]: # pragma: no cover - deprecate_with_replacement("decodedSelf", "decoded_self") + deprecation_with_replacement("decodedSelf", "decoded_self", "3.0.0") return self.decoded_self @decodedSelf.setter def decodedSelf(self, value: "DecodedStreamObject") -> None: # pragma: no cover - deprecate_with_replacement("decodedSelf", "decoded_self") + deprecation_with_replacement("decodedSelf", "decoded_self", "3.0.0") self.decoded_self = value @property @@ -760,7 +761,7 @@ def initialize_from_dictionary( return retval def flateEncode(self) -> "EncodedStreamObject": # pragma: no cover - deprecate_with_replacement("flateEncode", "flate_encode") + deprecation_with_replacement("flateEncode", "flate_encode", "3.0.0") return self.flate_encode() def flate_encode(self) -> "EncodedStreamObject": @@ -791,11 +792,11 @@ def set_data(self, data: Any) -> Any: self._data = data def getData(self) -> Any: # pragma: no cover - deprecate_with_replacement("getData", "get_data") + deprecation_with_replacement("getData", "get_data", "3.0.0") return self._data def setData(self, data: Any) -> None: # pragma: no cover - deprecate_with_replacement("setData", "set_data") + deprecation_with_replacement("setData", "set_data", "3.0.0") self.set_data(data) @@ -805,12 +806,12 @@ def __init__(self) -> None: @property def decodedSelf(self) -> Optional["DecodedStreamObject"]: # pragma: no cover - deprecate_with_replacement("decodedSelf", "decoded_self") + deprecation_with_replacement("decodedSelf", "decoded_self", "3.0.0") return self.decoded_self @decodedSelf.setter def decodedSelf(self, value: DecodedStreamObject) -> None: # pragma: no cover - deprecate_with_replacement("decodedSelf", "decoded_self") + deprecation_with_replacement("decodedSelf", "decoded_self", "3.0.0") self.decoded_self = value def get_data(self) -> Union[None, str, bytes]: @@ -831,14 +832,14 @@ def get_data(self) -> Union[None, str, bytes]: return decoded._data def getData(self) -> Union[None, str, bytes]: # pragma: no cover - deprecate_with_replacement("getData", "get_data") + deprecation_with_replacement("getData", "get_data", "3.0.0") return self.get_data() def set_data(self, data: Any) -> None: # pragma: no cover raise PdfReadError("Creating EncodedStreamObject is not currently supported") def setData(self, data: Any) -> None: # pragma: no cover - deprecate_with_replacement("setData", "set_data") + deprecation_with_replacement("setData", "set_data", "3.0.0") return self.set_data(data) @@ -1114,7 +1115,7 @@ def fieldType(self) -> Optional[NameObject]: # pragma: no cover Use :py:attr:`field_type` instead. """ - deprecate_with_replacement("fieldType", "field_type") + deprecation_with_replacement("fieldType", "field_type", "3.0.0") return self.field_type @property @@ -1144,7 +1145,7 @@ def altName(self) -> Optional[str]: # pragma: no cover Use :py:attr:`alternate_name` instead. """ - deprecate_with_replacement("altName", "alternate_name") + deprecation_with_replacement("altName", "alternate_name", "3.0.0") return self.alternate_name @property @@ -1163,7 +1164,7 @@ def mappingName(self) -> Optional[str]: # pragma: no cover Use :py:attr:`mapping_name` instead. """ - deprecate_with_replacement("mappingName", "mapping_name") + deprecation_with_replacement("mappingName", "mapping_name", "3.0.0") return self.mapping_name @property @@ -1194,7 +1195,7 @@ def defaultValue(self) -> Optional[Any]: # pragma: no cover Use :py:attr:`default_value` instead. """ - deprecate_with_replacement("defaultValue", "default_value") + deprecation_with_replacement("defaultValue", "default_value", "3.0.0") return self.default_value @property @@ -1213,7 +1214,7 @@ def additionalActions(self) -> Optional[DictionaryObject]: # pragma: no cover Use :py:attr:`additional_actions` instead. """ - deprecate_with_replacement("additionalActions", "additional_actions") + deprecation_with_replacement("additionalActions", "additional_actions", "3.0.0") return self.additional_actions @@ -1296,7 +1297,7 @@ def getDestArray(self) -> "ArrayObject": # pragma: no cover Use :py:attr:`dest_array` instead. """ - deprecate_with_replacement("getDestArray", "dest_array") + deprecation_with_replacement("getDestArray", "dest_array", "3.0.0") return self.dest_array def write_to_stream( diff --git a/PyPDF2/generic/_rectangle.py b/PyPDF2/generic/_rectangle.py index 7b0bab809..3f41bfd59 100644 --- a/PyPDF2/generic/_rectangle.py +++ b/PyPDF2/generic/_rectangle.py @@ -1,7 +1,7 @@ import decimal from typing import Any, List, Tuple, Union -from .._utils import deprecate_with_replacement, deprecation_no_replacement +from .._utils import deprecation_no_replacement, deprecation_with_replacement from ._base import FloatObject, NumberObject from ._data_structures import ArrayObject @@ -81,35 +81,35 @@ def top(self, f: float) -> None: self[3] = FloatObject(f) def getLowerLeft_x(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getLowerLeft_x", "left") + deprecation_with_replacement("getLowerLeft_x", "left", "3.0.0") return self.left def getLowerLeft_y(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getLowerLeft_y", "bottom") + deprecation_with_replacement("getLowerLeft_y", "bottom", "3.0.0") return self.bottom def getUpperRight_x(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getUpperRight_x", "right") + deprecation_with_replacement("getUpperRight_x", "right", "3.0.0") return self.right def getUpperRight_y(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getUpperRight_y", "top") + deprecation_with_replacement("getUpperRight_y", "top", "3.0.0") return self.top def getUpperLeft_x(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getUpperLeft_x", "left") + deprecation_with_replacement("getUpperLeft_x", "left", "3.0.0") return self.left def getUpperLeft_y(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getUpperLeft_y", "top") + deprecation_with_replacement("getUpperLeft_y", "top", "3.0.0") return self.top def getLowerRight_x(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getLowerRight_x", "right") + deprecation_with_replacement("getLowerRight_x", "right", "3.0.0") return self.right def getLowerRight_y(self) -> FloatObject: # pragma: no cover - deprecate_with_replacement("getLowerRight_y", "bottom") + deprecation_with_replacement("getLowerRight_y", "bottom", "3.0.0") return self.bottom @property @@ -163,41 +163,41 @@ def upper_right(self, value: List[Any]) -> None: def getLowerLeft( self, ) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("getLowerLeft", "lower_left") + deprecation_with_replacement("getLowerLeft", "lower_left", "3.0.0") return self.lower_left def getLowerRight( self, ) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("getLowerRight", "lower_right") + deprecation_with_replacement("getLowerRight", "lower_right", "3.0.0") return self.lower_right def getUpperLeft( self, ) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("getUpperLeft", "upper_left") + deprecation_with_replacement("getUpperLeft", "upper_left", "3.0.0") return self.upper_left def getUpperRight( self, ) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("getUpperRight", "upper_right") + deprecation_with_replacement("getUpperRight", "upper_right", "3.0.0") return self.upper_right def setLowerLeft(self, value: Tuple[float, float]) -> None: # pragma: no cover - deprecate_with_replacement("setLowerLeft", "lower_left") + deprecation_with_replacement("setLowerLeft", "lower_left", "3.0.0") self.lower_left = value # type: ignore def setLowerRight(self, value: Tuple[float, float]) -> None: # pragma: no cover - deprecate_with_replacement("setLowerRight", "lower_right") + deprecation_with_replacement("setLowerRight", "lower_right", "3.0.0") self[2], self[1] = (self._ensure_is_number(x) for x in value) def setUpperLeft(self, value: Tuple[float, float]) -> None: # pragma: no cover - deprecate_with_replacement("setUpperLeft", "upper_left") + deprecation_with_replacement("setUpperLeft", "upper_left", "3.0.0") self[0], self[3] = (self._ensure_is_number(x) for x in value) def setUpperRight(self, value: Tuple[float, float]) -> None: # pragma: no cover - deprecate_with_replacement("setUpperRight", "upper_right") + deprecation_with_replacement("setUpperRight", "upper_right", "3.0.0") self[2], self[3] = (self._ensure_is_number(x) for x in value) @property @@ -205,7 +205,7 @@ def width(self) -> decimal.Decimal: return self.right - self.left def getWidth(self) -> decimal.Decimal: # pragma: no cover - deprecate_with_replacement("getWidth", "width") + deprecation_with_replacement("getWidth", "width", "3.0.0") return self.width @property @@ -213,53 +213,53 @@ def height(self) -> decimal.Decimal: return self.top - self.bottom def getHeight(self) -> decimal.Decimal: # pragma: no cover - deprecate_with_replacement("getHeight", "height") + deprecation_with_replacement("getHeight", "height", "3.0.0") return self.height @property def lowerLeft(self) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("lowerLeft", "lower_left") + deprecation_with_replacement("lowerLeft", "lower_left", "3.0.0") return self.lower_left @lowerLeft.setter def lowerLeft( self, value: Tuple[decimal.Decimal, decimal.Decimal] ) -> None: # pragma: no cover - deprecate_with_replacement("lowerLeft", "lower_left") + deprecation_with_replacement("lowerLeft", "lower_left", "3.0.0") self.lower_left = value @property def lowerRight(self) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("lowerRight", "lower_right") + deprecation_with_replacement("lowerRight", "lower_right", "3.0.0") return self.lower_right @lowerRight.setter def lowerRight( self, value: Tuple[decimal.Decimal, decimal.Decimal] ) -> None: # pragma: no cover - deprecate_with_replacement("lowerRight", "lower_right") + deprecation_with_replacement("lowerRight", "lower_right", "3.0.0") self.lower_right = value @property def upperLeft(self) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("upperLeft", "upper_left") + deprecation_with_replacement("upperLeft", "upper_left", "3.0.0") return self.upper_left @upperLeft.setter def upperLeft( self, value: Tuple[decimal.Decimal, decimal.Decimal] ) -> None: # pragma: no cover - deprecate_with_replacement("upperLeft", "upper_left") + deprecation_with_replacement("upperLeft", "upper_left", "3.0.0") self.upper_left = value @property def upperRight(self) -> Tuple[decimal.Decimal, decimal.Decimal]: # pragma: no cover - deprecate_with_replacement("upperRight", "upper_right") + deprecation_with_replacement("upperRight", "upper_right", "3.0.0") return self.upper_right @upperRight.setter def upperRight( self, value: Tuple[decimal.Decimal, decimal.Decimal] ) -> None: # pragma: no cover - deprecate_with_replacement("upperRight", "upper_right") + deprecation_with_replacement("upperRight", "upper_right", "3.0.0") self.upper_right = value From 379eea90c535b9361187a5ebf36b5df46c7d3394 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 09:42:55 +0100 Subject: [PATCH 05/10] Balck --- PyPDF2/_reader.py | 10 +++++++--- PyPDF2/_writer.py | 22 ++++++++++++++++------ PyPDF2/xmp.py | 10 ++++++++-- tests/test_page.py | 2 +- tests/test_reader.py | 2 +- tests/test_writer.py | 12 +++++++----- 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/PyPDF2/_reader.py b/PyPDF2/_reader.py index f3cdcedda..0a9144766 100644 --- a/PyPDF2/_reader.py +++ b/PyPDF2/_reader.py @@ -53,8 +53,8 @@ StreamType, b_, deprecate_no_replacement, - deprecation_with_replacement, deprecation_no_replacement, + deprecation_with_replacement, logger_warning, read_non_whitespace, read_previous_line, @@ -665,7 +665,9 @@ def getFormTextFields(self) -> Dict[str, Any]: # pragma: no cover Use :meth:`get_form_text_fields` instead. """ - deprecation_with_replacement("getFormTextFields", "get_form_text_fields", "3.0.0") + deprecation_with_replacement( + "getFormTextFields", "get_form_text_fields", "3.0.0" + ) return self.get_form_text_fields() def _get_named_destinations( @@ -727,7 +729,9 @@ def getNamedDestinations( Use :py:attr:`named_destinations` instead. """ - deprecation_with_replacement("getNamedDestinations", "named_destinations", "3.0.0") + deprecation_with_replacement( + "getNamedDestinations", "named_destinations", "3.0.0" + ) return self._get_named_destinations(tree, retval) @property diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index 38cb06724..14133f5f2 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -66,8 +66,8 @@ _get_max_pdf_version_header, b_, deprecate_bookmark, - deprecation_with_replacement, deprecate_with_replacement, + deprecation_with_replacement, logger_warning, ) from .constants import AnnotationDictionaryAttributes @@ -707,7 +707,9 @@ def appendPagesFromReader( Use :meth:`append_pages_from_reader` instead. """ - deprecation_with_replacement("appendPagesFromReader", "append_pages_from_reader", "3.0.0") + deprecation_with_replacement( + "appendPagesFromReader", "append_pages_from_reader", "3.0.0" + ) self.append_pages_from_reader(reader, after_page_append) def update_page_form_field_values( @@ -1379,7 +1381,9 @@ def add_bookmark_dict( Use :meth:`add_outline_item_dict` instead. """ - deprecation_with_replacement("add_bookmark_dict", "add_outline_item_dict", "3.0.0") + deprecation_with_replacement( + "add_bookmark_dict", "add_outline_item_dict", "3.0.0" + ) return self.add_outline_item_dict(outline_item, parent) @deprecate_bookmark(bookmark="outline_item") @@ -1391,7 +1395,9 @@ def addBookmarkDict( Use :meth:`add_outline_item_dict` instead. """ - deprecation_with_replacement("addBookmarkDict", "add_outline_item_dict", "3.0.0") + deprecation_with_replacement( + "addBookmarkDict", "add_outline_item_dict", "3.0.0" + ) return self.add_outline_item_dict(outline_item, parent) def add_outline_item( @@ -1633,7 +1639,9 @@ def addNamedDestination( Use :meth:`add_named_destination` instead. """ - deprecation_with_replacement("addNamedDestination", "add_named_destination", "3.0.0") + deprecation_with_replacement( + "addNamedDestination", "add_named_destination", "3.0.0" + ) return self.add_named_destination(title, pagenum) def remove_links(self) -> None: @@ -2125,7 +2133,9 @@ def setPageMode(self, mode: PagemodeType) -> None: # pragma: no cover Use :py:attr:`page_mode` instead. """ - deprecation_with_replacement("writer.setPageMode(val)", "writer.page_mode = val", "3.0.0") + deprecation_with_replacement( + "writer.setPageMode(val)", "writer.page_mode = val", "3.0.0" + ) self.set_page_mode(mode) @property diff --git a/PyPDF2/xmp.py b/PyPDF2/xmp.py index ffbcb1886..de4328239 100644 --- a/PyPDF2/xmp.py +++ b/PyPDF2/xmp.py @@ -23,7 +23,11 @@ from xml.dom.minidom import parseString from xml.parsers.expat import ExpatError -from ._utils import StreamType, deprecate_with_replacement, deprecation_with_replacement +from ._utils import ( + StreamType, + deprecate_with_replacement, + deprecation_with_replacement, +) from .errors import PdfReadError from .generic import ContentStream, PdfObject @@ -283,7 +287,9 @@ def getNodesInNamespace( Use :meth:`get_nodes_in_namespace` instead. """ - deprecation_with_replacement("getNodesInNamespace", "get_nodes_in_namespace", "3.0.0") + deprecation_with_replacement( + "getNodesInNamespace", "get_nodes_in_namespace", "3.0.0" + ) return self.get_nodes_in_namespace(aboutUri, namespace) def _get_text(self, element: XmlElement) -> str: diff --git a/tests/test_page.py b/tests/test_page.py index 1674b0248..ee4af14a0 100644 --- a/tests/test_page.py +++ b/tests/test_page.py @@ -10,7 +10,7 @@ from PyPDF2 import PdfReader, PdfWriter, Transformation from PyPDF2._page import PageObject, set_custom_rtl from PyPDF2.constants import PageAttributes as PG -from PyPDF2.errors import PdfReadWarning, DeprecationError +from PyPDF2.errors import DeprecationError, PdfReadWarning from PyPDF2.generic import ( ArrayObject, DictionaryObject, diff --git a/tests/test_reader.py b/tests/test_reader.py index cb433ca7b..fda8f929f 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -11,8 +11,8 @@ from PyPDF2.constants import ImageAttributes as IA from PyPDF2.constants import PageAttributes as PG from PyPDF2.errors import ( - EmptyFileError, DeprecationError, + EmptyFileError, FileNotDecryptedError, PdfReadError, PdfReadWarning, diff --git a/tests/test_writer.py b/tests/test_writer.py index 544cc8c23..22a3d5b71 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -1,15 +1,15 @@ import os +import re from io import BytesIO from pathlib import Path import pytest -import re from PyPDF2 import PageObject, PdfMerger, PdfReader, PdfWriter -from PyPDF2.errors import PageSizeNotDefinedError, DeprecationError +from PyPDF2.errors import DeprecationError, PageSizeNotDefinedError from PyPDF2.generic import ( - Fit, ArrayObject, + Fit, IndirectObject, NameObject, NumberObject, @@ -586,8 +586,10 @@ def test_add_link(): with pytest.raises( DeprecationError, match=( - re.escape("add_link is deprecated and was removed in PyPDF2 3.0.0. " - "Use add_annotation(AnnotationBuilder.link(...)) instead.") + re.escape( + "add_link is deprecated and was removed in PyPDF2 3.0.0. " + "Use add_annotation(AnnotationBuilder.link(...)) instead." + ) ), ): writer.add_link( From e64770bf71657e4ce8e5c405ad519e9999ef0f20 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 10:05:14 +0100 Subject: [PATCH 06/10] Bookmarks decorator adjustment --- PyPDF2/_merger.py | 18 +++++++++--------- PyPDF2/_utils.py | 10 +++++++--- PyPDF2/_writer.py | 14 +++++++------- tests/test_merger.py | 31 +++++++++++++------------------ tests/test_utils.py | 15 ++++++--------- tests/test_writer.py | 6 +++--- 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/PyPDF2/_merger.py b/PyPDF2/_merger.py index 5803c398d..b09db3f6d 100644 --- a/PyPDF2/_merger.py +++ b/PyPDF2/_merger.py @@ -46,7 +46,7 @@ from ._reader import PdfReader from ._utils import ( StrByteType, - deprecate_bookmark, + deprecation_bookmark, deprecation_with_replacement, str_, ) @@ -102,7 +102,7 @@ class PdfMerger: file-like object. """ - @deprecate_bookmark(bookmarks="outline") + @deprecation_bookmark(bookmarks="outline") def __init__( self, strict: bool = False, fileobj: Union[Path, StrByteType] = "" ) -> None: @@ -130,7 +130,7 @@ def __exit__( self.write(self.fileobj) self.close() - @deprecate_bookmark(bookmark="outline_item", import_bookmarks="import_outline") + @deprecation_bookmark(bookmark="outline_item", import_bookmarks="import_outline") def merge( self, page_number: Optional[int] = None, @@ -281,7 +281,7 @@ def _create_stream( ) return stream, encryption_obj - @deprecate_bookmark(bookmark="outline_item", import_bookmarks="import_outline") + @deprecation_bookmark(bookmark="outline_item", import_bookmarks="import_outline") def append( self, fileobj: Union[StrByteType, PdfReader, Path], @@ -513,7 +513,7 @@ def _write_dests(self) -> None: if pageno is not None: self.output.add_named_destination_object(named_dest) - @deprecate_bookmark(bookmarks="outline") + @deprecation_bookmark(bookmarks="outline") def _write_outline( self, outline: Optional[Iterable[OutlineItem]] = None, @@ -541,7 +541,7 @@ def _write_outline( del outline_item["/Page"], outline_item["/Type"] last_added = self.output.add_outline_item_dict(outline_item, parent) - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def _write_outline_item_on_page( self, outline_item: Union[OutlineItem, Destination], page: _MergedPage ) -> None: @@ -594,7 +594,7 @@ def _associate_dests_to_pages(self, pages: List[_MergedPage]) -> None: ) named_dest[NameObject("/Page")] = NumberObject(pageno) - @deprecate_bookmark(bookmarks="outline") + @deprecation_bookmark(bookmarks="outline") def _associate_outline_items_to_pages( self, pages: List[_MergedPage], outline: Optional[Iterable[OutlineItem]] = None ) -> None: @@ -619,7 +619,7 @@ def _associate_outline_items_to_pages( if pageno is not None: outline_item[NameObject("/Page")] = NumberObject(pageno) - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def find_outline_item( self, outline_item: Dict[str, Any], @@ -644,7 +644,7 @@ def find_outline_item( return None - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def find_bookmark( self, outline_item: Dict[str, Any], diff --git a/PyPDF2/_utils.py b/PyPDF2/_utils.py index 5f5e73b5f..71478d71d 100644 --- a/PyPDF2/_utils.py +++ b/PyPDF2/_utils.py @@ -407,7 +407,7 @@ def logger_warning(msg: str, src: str) -> None: logging.getLogger(src).warning(msg) -def deprecate_bookmark(**aliases: str) -> Callable: +def deprecation_bookmark(**aliases: str) -> Callable: """ Decorator for deprecated term "bookmark" To be used for methods and function arguments @@ -418,7 +418,7 @@ def deprecate_bookmark(**aliases: str) -> Callable: def decoration(func: Callable): # type: ignore @functools.wraps(func) def wrapper(*args, **kwargs): # type: ignore - rename_kwargs(func.__name__, kwargs, aliases) + rename_kwargs(func.__name__, kwargs, aliases, fail=True) return func(*args, **kwargs) return wrapper @@ -427,7 +427,7 @@ def wrapper(*args, **kwargs): # type: ignore def rename_kwargs( # type: ignore - func_name: str, kwargs: Dict[str, Any], aliases: Dict[str, str] + func_name: str, kwargs: Dict[str, Any], aliases: Dict[str, str], fail: bool = False ): """ Helper function to deprecate arguments. @@ -435,6 +435,10 @@ def rename_kwargs( # type: ignore for old_term, new_term in aliases.items(): if old_term in kwargs: + if fail: + raise DeprecationError( + f"{old_term} is deprecated as an argument. Use {new_term} instead" + ) if new_term in kwargs: raise TypeError( f"{func_name} received both {old_term} and {new_term} as an argument. " diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index 14133f5f2..9874fbf0b 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -65,8 +65,8 @@ StreamType, _get_max_pdf_version_header, b_, - deprecate_bookmark, deprecate_with_replacement, + deprecation_bookmark, deprecation_with_replacement, logger_warning, ) @@ -1350,7 +1350,7 @@ def addBookmarkDestination( ) return self.add_outline_item_destination(dest, parent) - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def add_outline_item_dict( self, outline_item: OutlineItemType, @@ -1372,7 +1372,7 @@ def add_outline_item_dict( return self.add_outline_item_destination(outline_item_object, parent, before) - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def add_bookmark_dict( self, outline_item: OutlineItemType, parent: Optional[TreeObject] = None ) -> IndirectObject: # pragma: no cover @@ -1386,7 +1386,7 @@ def add_bookmark_dict( ) return self.add_outline_item_dict(outline_item, parent) - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def addBookmarkDict( self, outline_item: OutlineItemType, parent: Optional[TreeObject] = None ) -> IndirectObject: # pragma: no cover @@ -2318,7 +2318,7 @@ def append( None, fileobj, outline_item, pages, import_outline, excluded_fields ) - @deprecate_bookmark(bookmark="outline_item", import_bookmarks="import_outline") + @deprecation_bookmark(bookmark="outline_item", import_bookmarks="import_outline") def merge( self, position: Optional[int], @@ -2674,7 +2674,7 @@ def close(self) -> None: """To match the functions from Merger""" return - # @deprecate_bookmark(bookmark="outline_item") + # @deprecation_bookmark(bookmark="outline_item") def find_outline_item( self, outline_item: Dict[str, Any], @@ -2705,7 +2705,7 @@ def find_outline_item( else: return None - @deprecate_bookmark(bookmark="outline_item") + @deprecation_bookmark(bookmark="outline_item") def find_bookmark( self, outline_item: Dict[str, Any], diff --git a/tests/test_merger.py b/tests/test_merger.py index f33c29d7e..f5d078900 100644 --- a/tests/test_merger.py +++ b/tests/test_merger.py @@ -7,6 +7,7 @@ import PyPDF2 from PyPDF2 import PdfMerger, PdfReader, PdfWriter +from PyPDF2.errors import DeprecationError from PyPDF2.generic import Destination, Fit from . import get_pdf_from_url @@ -664,44 +665,38 @@ def test_iss1145_with_writer(): merger.close() -def test_deprecate_bookmark_decorator_warning(): +def test_deprecation_bookmark_decorator_deprecationexcp(): reader = PdfReader(RESOURCE_ROOT / "outlines-with-invalid-destinations.pdf") merger = PdfMerger() - with pytest.warns( - UserWarning, + with pytest.raises( + DeprecationError, match="import_bookmarks is deprecated as an argument. Use import_outline instead", ): merger.merge(0, reader, import_bookmarks=True) -def test_deprecate_bookmark_decorator_warning_with_writer(): +def test_deprecation_bookmark_decorator_deprecationexcp_with_writer(): reader = PdfReader(RESOURCE_ROOT / "outlines-with-invalid-destinations.pdf") merger = PdfWriter() - with pytest.warns( - UserWarning, + with pytest.raises( + DeprecationError, match="import_bookmarks is deprecated as an argument. Use import_outline instead", ): merger.merge(0, reader, import_bookmarks=True) -@pytest.mark.filterwarnings("ignore::UserWarning") -def test_deprecate_bookmark_decorator_output(): +def test_deprecation_bookmark_decorator_output(): reader = PdfReader(RESOURCE_ROOT / "outlines-with-invalid-destinations.pdf") merger = PdfMerger() - merger.merge(0, reader, import_bookmarks=True) - first_oi_title = 'Valid Destination: Action /GoTo Named Destination "section.1"' - assert merger.outline[0].title == first_oi_title + with pytest.raises(DeprecationError): + merger.merge(0, reader, import_bookmarks=True) -@pytest.mark.filterwarnings("ignore::UserWarning") -def test_deprecate_bookmark_decorator_output_with_writer(): +def test_deprecation_bookmark_decorator_output_with_writer(): reader = PdfReader(RESOURCE_ROOT / "outlines-with-invalid-destinations.pdf") merger = PdfWriter() - merger.merge(0, reader, import_bookmarks=True) - first_oi_title = 'Valid Destination: Action /GoTo Named Destination "section.1"' - # TODO? : add outline property ??? - # assert merger.outline[0].title == first_oi_title - assert merger.find_outline_item(first_oi_title) == [0] + with pytest.raises(DeprecationError): + merger.merge(0, reader, import_bookmarks=True) @pytest.mark.external diff --git a/tests/test_utils.py b/tests/test_utils.py index 4c64ce01b..1f67878db 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -10,7 +10,7 @@ File, _get_max_pdf_version_header, _human_readable_bytes, - deprecate_bookmark, + deprecation_bookmark, mark_location, matrix_multiply, read_block_backwards, @@ -20,7 +20,7 @@ skip_over_comment, skip_over_whitespace, ) -from PyPDF2.errors import PdfReadError, PdfStreamError +from PyPDF2.errors import DeprecationError, PdfReadError, PdfStreamError from . import get_pdf_from_url @@ -236,17 +236,14 @@ def test_read_block_backwards_exception(): assert exc.value.args[0] == "Could not read malformed PDF file" -def test_deprecate_bookmark(): - @deprecate_bookmark(old_param="new_param") +def test_deprecation_bookmark(): + @deprecation_bookmark(old_param="new_param") def foo(old_param=1, baz=2): return old_param * baz - with pytest.raises(TypeError) as exc: + with pytest.raises(DeprecationError) as exc: foo(old_param=12, new_param=13) - expected_msg = ( - "foo received both old_param and new_param as an argument. " - "old_param is deprecated. Use new_param instead." - ) + expected_msg = "old_param is deprecated as an argument. Use new_param instead" assert exc.value.args[0] == expected_msg diff --git a/tests/test_writer.py b/tests/test_writer.py index 22a3d5b71..617ffec50 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -800,14 +800,14 @@ def test_add_single_annotation(): os.remove(target) # remove for testing -def test_deprecate_bookmark_decorator(): +def test_deprecation_bookmark_decorator(): reader = PdfReader(RESOURCE_ROOT / "outlines-with-invalid-destinations.pdf") page = reader.pages[0] outline_item = reader.outline[0] writer = PdfWriter() writer.add_page(page) - with pytest.warns( - UserWarning, + with pytest.raises( + DeprecationError, match="bookmark is deprecated as an argument. Use outline_item instead", ): writer.add_outline_item_dict(bookmark=outline_item) From bcac8e26469e3da882b140029ace84984e3cf7ad Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 10:15:21 +0100 Subject: [PATCH 07/10] More deprecations / old code removal --- PyPDF2/_merger.py | 24 ++++++++----- PyPDF2/_page.py | 92 ++++++----------------------------------------- PyPDF2/_utils.py | 3 +- PyPDF2/_writer.py | 32 +++++++++++------ 4 files changed, 49 insertions(+), 102 deletions(-) diff --git a/PyPDF2/_merger.py b/PyPDF2/_merger.py index b09db3f6d..4d7a659d8 100644 --- a/PyPDF2/_merger.py +++ b/PyPDF2/_merger.py @@ -171,9 +171,11 @@ def merge( old_term = "position" new_term = "page_number" warnings.warn( - message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + ( + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2=4.0.0. Use {new_term} instead" + ), + DeprecationWarning, ) else: raise ValueError( @@ -688,9 +690,11 @@ def add_outline_item( old_term = "pagenum" new_term = "page_number" warnings.warn( - message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + ( + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + DeprecationWarning, ) page_number = pagenum if page_number is None: @@ -791,9 +795,11 @@ def add_named_destination( old_term = "pagenum" new_term = "page_number" warnings.warn( - message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + ( + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + DeprecationWarning, ) page_number = pagenum if page_number is None: diff --git a/PyPDF2/_page.py b/PyPDF2/_page.py index 3808fc481..a8c3e8180 100644 --- a/PyPDF2/_page.py +++ b/PyPDF2/_page.py @@ -302,7 +302,11 @@ def __init__( self.pdf: Optional[PdfReaderProtocol] = pdf if indirect_ref is not None: # deprecated warnings.warn( - "Use indirect_reference instead of indirect_ref.", DeprecationWarning + ( + f"indirect_ref is deprecated and will be removed in " + f"PyPDF2==4.0.0. Use indirect_reference instead of indirect_ref." + ), + DeprecationWarning, ) if indirect_reference is not None: raise ValueError("Use indirect_reference instead of indirect_ref.") @@ -312,7 +316,11 @@ def __init__( @property def indirect_ref(self) -> Optional[IndirectObject]: # deprecated warnings.warn( - "Use indirect_reference instead of indirect_ref.", DeprecationWarning + ( + "indirect_ref is deprecated and will be removed in PyPDF2==4.0.0" + f"Use indirect_reference instead of indirect_ref." + ), + DeprecationWarning, ) return self.indirect_reference @@ -1186,84 +1194,6 @@ def compressContentStreams(self) -> None: # pragma: no cover ) self.compress_content_streams() - def _extract_text_old( - self, Tj_sep: str = "", TJ_sep: str = "" - ) -> str: # pragma: no cover - """ - Locate all text drawing commands, in the order they are provided in the - content stream, and extract the text. This works well for some PDF - files, but poorly for others, depending on the generator used. This will - be refined in the future. Do not rely on the order of text coming out of - this function, as it will change if this function is made more - sophisticated. - - :return: a string object. - """ - text = "" - content = self[PG.CONTENTS].get_object() - if not isinstance(content, ContentStream): - content = ContentStream(content, self.pdf) - # Note: we check all strings are TextStringObjects. ByteStringObjects - # are strings where the byte->string encoding was unknown, so adding - # them to the text here would be gibberish. - - space_scale = 1.0 - - for operands, operator in content.operations: - # Missing operators: - # Tf: text font - # Tfs: text font size - # Tc: '5.2.1 Character Spacing' - # Th: '5.2.3 Horizontal Scaling' - # Tl: '5.2.4 Leading' - # Tmode: '5.2.5 Text Rendering Mode' - # Trise: '5.2.6 Text Rise' - - if operator in [b"Tf", b"Tfs", b"Tc", b"Th", b"Tl", b"Tmode"]: - pass - elif operator == b"Tw": # word spacing - # See '5.2.2 Word Spacing' - space_scale = 1.0 + float(operands[0]) - elif operator == b"Tj": - # See 'TABLE 5.6 Text-showing operators' - _text = operands[0] - if isinstance(_text, TextStringObject): - text += Tj_sep - text += _text - text += "\n" - elif operator == b"T*": - # See 'TABLE 5.5 Text-positioning operators' - text += "\n" - elif operator == b"'": - # See 'TABLE 5.6 Text-showing operators' - text += "\n" - _text = operands[0] - if isinstance(_text, TextStringObject): - text += operands[0] - elif operator == b'"': - # See 'TABLE 5.6 Text-showing operators' - _text = operands[2] - if isinstance(_text, TextStringObject): - text += "\n" - text += _text - elif operator == b"TJ": - # See 'TABLE 5.6 Text-showing operators' - for i in operands[0]: - if isinstance(i, TextStringObject): - text += TJ_sep - text += i - elif isinstance(i, (NumberObject, FloatObject)): - # a positive value decreases and the negative value increases - # space - if int(i) < -space_scale * 250: - if len(text) == 0 or text[-1] != " ": - text += " " - else: - if len(text) > 1 and text[-1] == " ": - text = text[:-1] - text += "\n" - return text - def _debug_for_extract(self) -> str: # pragma: no cover out = "" for ope, op in ContentStream( @@ -1839,7 +1769,7 @@ def extract_text( raise TypeError(f"Invalid positional parameter {args[0]}") if Tj_sep is not None or TJ_sep is not None: warnings.warn( - "parameters Tj_Sep, TJ_sep depreciated, and will be removed in PyPDF2 3.0.0.", + "parameters Tj_Sep, TJ_sep depreciated, and will be removed in PyPDF2 4.0.0.", DeprecationWarning, ) diff --git a/PyPDF2/_utils.py b/PyPDF2/_utils.py index 71478d71d..51db3ada9 100644 --- a/PyPDF2/_utils.py +++ b/PyPDF2/_utils.py @@ -448,7 +448,8 @@ def rename_kwargs( # type: ignore warnings.warn( message=( f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + ), + category=DeprecationWarning, ) diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index 9874fbf0b..8883a8b70 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -225,7 +225,7 @@ def get_object( else: indirect_reference = ido warnings.warn( - "The parameter 'ido' is depreciated and will be removed in PyPDF2 3.0.0.", + "The parameter 'ido' is depreciated and will be removed in PyPDF2 4.0.0.", DeprecationWarning, ) assert ( @@ -885,7 +885,7 @@ def encrypt( warnings.warn( "Please use 'user_password' instead of 'user_pwd'. " "The 'user_pwd' argument is deprecated and will be removed " - "in PyPDF2==3.0.0." + "in PyPDF2==4.0.0." ) user_password = user_pwd if user_password is None: # deprecated @@ -902,8 +902,10 @@ def encrypt( new_term = "owner_password" warnings.warn( message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + category=DeprecationWarning, ) owner_password = owner_pwd @@ -1303,8 +1305,10 @@ def add_outline_item_destination( new_term = "page_destination" warnings.warn( message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + category=DeprecationWarning, ) page_destination = dest if page_destination is None: # deprecated @@ -1565,8 +1569,10 @@ def add_named_destination_object( new_term = "page_destination" warnings.warn( message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + category=DeprecationWarning, ) page_destination = dest if page_destination is None: # deprecated @@ -1607,8 +1613,10 @@ def add_named_destination( new_term = "page_number" warnings.warn( message=( - f"{old_term} is deprecated as an argument. Use {new_term} instead" - ) + f"{old_term} is deprecated as an argument and will be " + f"removed in PyPDF2==4.0.0. Use {new_term} instead" + ), + category=DeprecationWarning, ) page_number = pagenum if page_number is None: @@ -1828,7 +1836,9 @@ def add_uri( """ if pagenum is not None: warnings.warn( - "The 'pagenum' argument of add_uri is deprecated. Use 'page_number' instead." + "The 'pagenum' argument of add_uri is deprecated and will be " + "removed in PyPDF2==4.0.0. Use 'page_number' instead.", + category=DeprecationWarning, ) page_number = pagenum page_link = self.get_object(self._pages)[PA.KIDS][page_number] # type: ignore From bf20fca4d0cda5a9254db045067dff01c804e050 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 10:25:12 +0100 Subject: [PATCH 08/10] Fix --- PyPDF2/_page.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/PyPDF2/_page.py b/PyPDF2/_page.py index a8c3e8180..080f6a227 100644 --- a/PyPDF2/_page.py +++ b/PyPDF2/_page.py @@ -73,7 +73,6 @@ NullObject, NumberObject, RectangleObject, - TextStringObject, encode_pdfdocencoding, ) @@ -303,8 +302,8 @@ def __init__( if indirect_ref is not None: # deprecated warnings.warn( ( - f"indirect_ref is deprecated and will be removed in " - f"PyPDF2==4.0.0. Use indirect_reference instead of indirect_ref." + "indirect_ref is deprecated and will be removed in " + "PyPDF2==4.0.0. Use indirect_reference instead of indirect_ref." ), DeprecationWarning, ) @@ -318,7 +317,7 @@ def indirect_ref(self) -> Optional[IndirectObject]: # deprecated warnings.warn( ( "indirect_ref is deprecated and will be removed in PyPDF2==4.0.0" - f"Use indirect_reference instead of indirect_ref." + "Use indirect_reference instead of indirect_ref." ), DeprecationWarning, ) From 09193e563d80a4c5d16ebf4b1f9c747b40ea0f06 Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 10:40:15 +0100 Subject: [PATCH 09/10] Last one --- PyPDF2/_page.py | 8 ++++---- PyPDF2/_writer.py | 14 +++++++------- PyPDF2/types.py | 8 ++------ tests/test_writer.py | 4 ++-- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/PyPDF2/_page.py b/PyPDF2/_page.py index 080f6a227..6799036a7 100644 --- a/PyPDF2/_page.py +++ b/PyPDF2/_page.py @@ -303,7 +303,7 @@ def __init__( warnings.warn( ( "indirect_ref is deprecated and will be removed in " - "PyPDF2==4.0.0. Use indirect_reference instead of indirect_ref." + "PyPDF2 4.0.0. Use indirect_reference instead of indirect_ref." ), DeprecationWarning, ) @@ -316,7 +316,7 @@ def __init__( def indirect_ref(self) -> Optional[IndirectObject]: # deprecated warnings.warn( ( - "indirect_ref is deprecated and will be removed in PyPDF2==4.0.0" + "indirect_ref is deprecated and will be removed in PyPDF2 4.0.0" "Use indirect_reference instead of indirect_ref." ), DeprecationWarning, @@ -1718,8 +1718,8 @@ def extract_text( Additionally you can provide visitor-methods to get informed on all operands and all text-objects. For example in some PDF files this can be useful to parse tables. - :param Tj_sep: Deprecated. Kept for compatibility until PyPDF2==4.0.0 - :param TJ_sep: Deprecated. Kept for compatibility until PyPDF2==4.0.0 + :param Tj_sep: Deprecated. Kept for compatibility until PyPDF2 4.0.0 + :param TJ_sep: Deprecated. Kept for compatibility until PyPDF2 4.0.0 :param Tuple[int, ...] orientations: list of orientations text_extraction will look for default = (0, 90, 180, 270) note: currently only 0(Up),90(turned Left), 180(upside Down), diff --git a/PyPDF2/_writer.py b/PyPDF2/_writer.py index 8883a8b70..acab80d20 100644 --- a/PyPDF2/_writer.py +++ b/PyPDF2/_writer.py @@ -884,8 +884,8 @@ def encrypt( else: warnings.warn( "Please use 'user_password' instead of 'user_pwd'. " - "The 'user_pwd' argument is deprecated and will be removed " - "in PyPDF2==4.0.0." + "The 'user_pwd' argument is deprecated and " + "will be removed in PyPDF2 4.0.0." ) user_password = user_pwd if user_password is None: # deprecated @@ -903,7 +903,7 @@ def encrypt( warnings.warn( message=( f"{old_term} is deprecated as an argument and will be " - f"removed in PyPDF2==4.0.0. Use {new_term} instead" + f"removed in PyPDF2 4.0.0. Use {new_term} instead" ), category=DeprecationWarning, ) @@ -1306,7 +1306,7 @@ def add_outline_item_destination( warnings.warn( message=( f"{old_term} is deprecated as an argument and will be " - f"removed in PyPDF2==4.0.0. Use {new_term} instead" + f"removed in PyPDF2 4.0.0. Use {new_term} instead" ), category=DeprecationWarning, ) @@ -1570,7 +1570,7 @@ def add_named_destination_object( warnings.warn( message=( f"{old_term} is deprecated as an argument and will be " - f"removed in PyPDF2==4.0.0. Use {new_term} instead" + f"removed in PyPDF2 4.0.0. Use {new_term} instead" ), category=DeprecationWarning, ) @@ -1614,7 +1614,7 @@ def add_named_destination( warnings.warn( message=( f"{old_term} is deprecated as an argument and will be " - f"removed in PyPDF2==4.0.0. Use {new_term} instead" + f"removed in PyPDF2 4.0.0. Use {new_term} instead" ), category=DeprecationWarning, ) @@ -1837,7 +1837,7 @@ def add_uri( if pagenum is not None: warnings.warn( "The 'pagenum' argument of add_uri is deprecated and will be " - "removed in PyPDF2==4.0.0. Use 'page_number' instead.", + "removed in PyPDF2 4.0.0. Use 'page_number' instead.", category=DeprecationWarning, ) page_number = pagenum diff --git a/PyPDF2/types.py b/PyPDF2/types.py index 9683c1edd..92cba6fe9 100644 --- a/PyPDF2/types.py +++ b/PyPDF2/types.py @@ -20,8 +20,6 @@ BorderArrayType: TypeAlias = List[Union[NameObject, NumberObject, ArrayObject]] OutlineItemType: TypeAlias = Union[OutlineItem, Destination] -# BookmarkTypes is deprecated. Use OutlineItemType instead -BookmarkTypes: TypeAlias = OutlineItemType # Remove with PyPDF2==3.0.0 FitType: TypeAlias = Literal[ "/Fit", "/XYZ", "/FitH", "/FitV", "/FitR", "/FitB", "/FitBH", "/FitBV" ] @@ -29,13 +27,11 @@ ZoomArgType: TypeAlias = Union[NumberObject, NullObject, float] ZoomArgsType: TypeAlias = List[ZoomArgType] -# Recursive types are not yet supported by mypy: -# OutlinesType = List[Union[Destination, "OutlinesType"]] +# Recursive types like the following are not yet supported by mypy: +# OutlineType = List[Union[Destination, "OutlineType"]] # See https://github.com/python/mypy/issues/731 # Hence use this for the moment: OutlineType = List[Union[Destination, List[Union[Destination, List[Destination]]]]] -# OutlinesType is deprecated. Use OutlineType instead -OutlinesType: TypeAlias = OutlineType # Remove with PyPDF2==3.0.0 LayoutType: TypeAlias = Literal[ "/NoLayout", diff --git a/tests/test_writer.py b/tests/test_writer.py index 617ffec50..cf3a46380 100644 --- a/tests/test_writer.py +++ b/tests/test_writer.py @@ -797,7 +797,7 @@ def test_add_single_annotation(): writer.write(fp) # Cleanup - os.remove(target) # remove for testing + os.remove(target) # comment out for testing def test_deprecation_bookmark_decorator(): @@ -833,7 +833,7 @@ def test_colors_in_outline_item(): assert [str(c) for c in outline_item.color] == [str(p) for p in purple_rgb] # Cleanup - os.remove(target) # remove for testing + os.remove(target) # comment out for testing @pytest.mark.samples From b8d8cb503fcd571d5c12622e529bc015685ca52c Mon Sep 17 00:00:00 2001 From: Martin Thoma Date: Sun, 11 Dec 2022 11:31:06 +0100 Subject: [PATCH 10/10] Mark as deprecated --- PyPDF2/_page.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyPDF2/_page.py b/PyPDF2/_page.py index 6799036a7..b725910f9 100644 --- a/PyPDF2/_page.py +++ b/PyPDF2/_page.py @@ -294,7 +294,7 @@ def __init__( self, pdf: Optional[PdfReaderProtocol] = None, indirect_reference: Optional[IndirectObject] = None, - indirect_ref: Optional[IndirectObject] = None, + indirect_ref: Optional[IndirectObject] = None, # deprecated ) -> None: DictionaryObject.__init__(self)