Skip to content

Commit

Permalink
DEV: Use relative imports (py-pdf#875)
Browse files Browse the repository at this point in the history
This is important for some PyPDF2 developers development workflows.
It allows them to compare changes more easily.

Additionally, some imports were moved from function-level to module-level.

See py-pdf#865 (comment)

Co-authored-by: pubpub-zz <[email protected]>
  • Loading branch information
MartinThoma and pubpub-zz authored May 14, 2022
1 parent 98f72e4 commit 4429066
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 133 deletions.
12 changes: 6 additions & 6 deletions PyPDF2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from PyPDF2._merger import PdfFileMerger
from PyPDF2._reader import PdfFileReader
from PyPDF2._version import __version__
from PyPDF2._writer import PdfFileWriter
from PyPDF2.pagerange import PageRange, parse_filename_page_ranges
from PyPDF2.papersizes import PaperSize
from ._merger import PdfFileMerger
from ._reader import PdfFileReader
from ._version import __version__
from ._writer import PdfFileWriter
from .pagerange import PageRange, parse_filename_page_ranges
from .papersizes import PaperSize

__all__ = [
"__version__",
Expand Down
16 changes: 8 additions & 8 deletions PyPDF2/_merger.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
from io import BytesIO, FileIO, IOBase
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union, cast

from PyPDF2._page import PageObject
from PyPDF2._reader import PdfFileReader
from PyPDF2._writer import PdfFileWriter
from PyPDF2.constants import PagesAttributes as PA
from PyPDF2.generic import (
from ._page import PageObject
from ._reader import PdfFileReader
from ._writer import PdfFileWriter
from .constants import PagesAttributes as PA
from .generic import (
ArrayObject,
Bookmark,
Destination,
Expand All @@ -46,16 +46,16 @@
TreeObject,
createStringObject,
)
from PyPDF2.pagerange import PageRange, PageRangeSpec
from PyPDF2.types import (
from .pagerange import PageRange, PageRangeSpec
from .types import (
BookmarkTypes,
LayoutType,
OutlinesType,
PagemodeType,
ZoomArgsType,
ZoomArgType,
)
from PyPDF2.utils import StrByteType, str_
from .utils import StrByteType, str_

ERR_CLOSED_WRITER = "close() was called and thus the writer cannot be used anymore"

Expand Down
25 changes: 12 additions & 13 deletions PyPDF2/_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@
cast,
)

from PyPDF2 import utils
from PyPDF2.constants import PageAttributes as PG
from PyPDF2.constants import Ressources as RES
from PyPDF2.errors import PageSizeNotDefinedError
from PyPDF2.generic import (
from .constants import PageAttributes as PG
from .constants import Ressources as RES
from .errors import PageSizeNotDefinedError
from .generic import (
ArrayObject,
ContentStream,
DictionaryObject,
Expand All @@ -58,7 +57,7 @@
RectangleObject,
TextStringObject,
)
from PyPDF2.utils import b_
from .utils import b_, matrixMultiply


def getRectangle(self: Any, name: str, defaults: Iterable[str]) -> RectangleObject:
Expand Down Expand Up @@ -115,7 +114,7 @@ def __init__(
pdf: Optional[Any] = None, # PdfFileReader
indirectRef: Optional[IndirectObject] = None,
) -> None:
from PyPDF2._reader import PdfFileReader
from ._reader import PdfFileReader

DictionaryObject.__init__(self)
self.pdf: Optional[PdfFileReader] = pdf
Expand Down Expand Up @@ -535,8 +534,8 @@ def mergeRotatedTranslatedPage(
[0, 0, 1],
]
rtranslation: List[List[float]] = [[1, 0, 0], [0, 1, 0], [tx, ty, 1]]
ctm = utils.matrixMultiply(translation, rotating)
ctm = utils.matrixMultiply(ctm, rtranslation)
ctm = matrixMultiply(translation, rotating)
ctm = matrixMultiply(ctm, rtranslation)

return self.mergeTransformedPage(
page2,
Expand Down Expand Up @@ -565,7 +564,7 @@ def mergeRotatedScaledPage(
[0, 0, 1],
]
scaling: List[List[float]] = [[scale, 0, 0], [0, scale, 0], [0, 0, 1]]
ctm = utils.matrixMultiply(rotating, scaling)
ctm = matrixMultiply(rotating, scaling)

self.mergeTransformedPage(
page2,
Expand Down Expand Up @@ -596,7 +595,7 @@ def mergeScaledTranslatedPage(

translation: List[List[float]] = [[1, 0, 0], [0, 1, 0], [tx, ty, 1]]
scaling: List[List[float]] = [[scale, 0, 0], [0, scale, 0], [0, 0, 1]]
ctm = utils.matrixMultiply(scaling, translation)
ctm = matrixMultiply(scaling, translation)

return self.mergeTransformedPage(
page2,
Expand Down Expand Up @@ -635,8 +634,8 @@ def mergeRotatedScaledTranslatedPage(
[0, 0, 1],
]
scaling: List[List[float]] = [[scale, 0, 0], [0, scale, 0], [0, 0, 1]]
ctm = utils.matrixMultiply(rotating, scaling)
ctm = utils.matrixMultiply(ctm, translation)
ctm = matrixMultiply(rotating, scaling)
ctm = matrixMultiply(ctm, translation)

self.mergeTransformedPage(
page2,
Expand Down
57 changes: 30 additions & 27 deletions PyPDF2/_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# POSSIBILITY OF SUCH DAMAGE.

import struct
import re
import warnings
from hashlib import md5
from io import BytesIO
Expand All @@ -44,20 +45,19 @@
cast,
)

from PyPDF2 import utils
from PyPDF2._page import PageObject
from PyPDF2._security import _alg33_1, _alg34, _alg35
from PyPDF2.constants import CatalogAttributes as CA
from PyPDF2.constants import CatalogDictionary as CD
from PyPDF2.constants import Core as CO
from PyPDF2.constants import DocumentInformationAttributes as DI
from PyPDF2.constants import EncryptionDictAttributes as ED
from PyPDF2.constants import PageAttributes as PG
from PyPDF2.constants import PagesAttributes as PA
from PyPDF2.constants import StreamAttributes as SA
from PyPDF2.constants import TrailerKeys as TK
from PyPDF2.errors import PdfReadError, PdfReadWarning, PdfStreamError
from PyPDF2.generic import (
from ._page import PageObject
from ._security import _alg33_1, _alg34, _alg35
from .constants import CatalogAttributes as CA
from .constants import CatalogDictionary as CD
from .constants import Core as CO
from .constants import DocumentInformationAttributes as DI
from .constants import EncryptionDictAttributes as ED
from .constants import PageAttributes as PG
from .constants import PagesAttributes as PA
from .constants import StreamAttributes as SA
from .constants import TrailerKeys as TK
from .errors import PdfReadError, PdfReadWarning, PdfStreamError
from .generic import (
ArrayObject,
BooleanObject,
ByteStringObject,
Expand All @@ -79,15 +79,19 @@
createStringObject,
readObject,
)
from PyPDF2.types import OutlinesType
from PyPDF2.utils import (
from .types import OutlinesType
from .utils import (
RC4_encrypt,
StrByteType,
StreamType,
b_,
ord_,
readNonWhitespace,
readUntilWhitespace,
skipOverComment,
skipOverWhitespace,
)
from PyPDF2.xmp import XmpInformation
from .xmp import XmpInformation


def convertToInt(d: bytes, size: int) -> Union[int, Tuple[Any, ...]]:
Expand Down Expand Up @@ -923,9 +927,9 @@ def _decryptObject(
key: Union[str, bytes],
) -> PdfObject:
if isinstance(obj, (ByteStringObject, TextStringObject)):
obj = createStringObject(utils.RC4_encrypt(key, obj.original_bytes))
obj = createStringObject(RC4_encrypt(key, obj.original_bytes))
elif isinstance(obj, StreamObject):
obj._data = utils.RC4_encrypt(key, obj._data)
obj._data = RC4_encrypt(key, obj._data)
elif isinstance(obj, DictionaryObject):
for dictkey, value in list(obj.items()):
obj[dictkey] = self._decryptObject(value, key)
Expand All @@ -940,14 +944,14 @@ def readObjectHeader(self, stream: StreamType) -> Tuple[int, int]:
# object header. In reality... some files have stupid cross reference
# tables that are off by whitespace bytes.
extra = False
utils.skipOverComment(stream)
extra |= utils.skipOverWhitespace(stream)
skipOverComment(stream)
extra |= skipOverWhitespace(stream)
stream.seek(-1, 1)
idnum = readUntilWhitespace(stream)
extra |= utils.skipOverWhitespace(stream)
extra |= skipOverWhitespace(stream)
stream.seek(-1, 1)
generation = readUntilWhitespace(stream)
extra |= utils.skipOverWhitespace(stream)
extra |= skipOverWhitespace(stream)
stream.seek(-1, 1)

# although it's not used, it might still be necessary to read
Expand Down Expand Up @@ -1263,7 +1267,6 @@ def _rebuild_xref_table(self, stream: StreamType) -> None:
self.xref = {}
stream.seek(0, 0)
f_ = stream.read(-1)
import re

for m in re.finditer(b_(r"[\r\n \t][ \t]*(\d+)[ \t]+(\d+)[ \t]+obj"), f_):
idnum = int(m.group(1))
Expand Down Expand Up @@ -1442,14 +1445,14 @@ def _decrypt(self, password: Union[str, bytes]) -> int:
key = _alg33_1(password, rev, keylen)
real_O = cast(bytes, encrypt["/O"].getObject())
if rev == 2:
userpass = utils.RC4_encrypt(key, real_O)
userpass = RC4_encrypt(key, real_O)
else:
val = real_O
for i in range(19, -1, -1):
new_key = b_("")
for l in range(len(key)):
new_key += b_(chr(utils.ord_(key[l]) ^ i))
val = utils.RC4_encrypt(new_key, val)
new_key += b_(chr(ord_(key[l]) ^ i))
val = RC4_encrypt(new_key, val)
userpass = val
owner_password, key = self._authenticateUserPassword(userpass)
if owner_password:
Expand Down
15 changes: 7 additions & 8 deletions PyPDF2/_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@
from hashlib import md5
from typing import Any, Tuple, Union

from PyPDF2 import utils
from PyPDF2.generic import BooleanObject, ByteStringObject
from PyPDF2.utils import b_, ord_, str_
from .generic import BooleanObject, ByteStringObject
from .utils import RC4_encrypt, b_, ord_, str_

# ref: pdf1.8 spec section 3.5.2 algorithm 3.2
_encryption_padding = (
Expand Down Expand Up @@ -106,7 +105,7 @@ def _alg33(owner_pwd: str, user_pwd: str, rev: int, keylen: int) -> bytes:
user_pwd_bytes = b_((user_pwd + str_(_encryption_padding))[:32])
# 6. Encrypt the result of step 5, using an RC4 encryption function with
# the encryption key obtained in step 4.
val = utils.RC4_encrypt(key, user_pwd_bytes)
val = RC4_encrypt(key, user_pwd_bytes)
# 7. (Revision 3 or greater) Do the following 19 times: Take the output
# from the previous invocation of the RC4 function and pass it as input to
# a new invocation of the function; use an encryption key generated by
Expand All @@ -118,7 +117,7 @@ def _alg33(owner_pwd: str, user_pwd: str, rev: int, keylen: int) -> bytes:
new_key = ""
for l in range(len(key)):
new_key += chr(ord_(key[l]) ^ i)
val = utils.RC4_encrypt(new_key, val)
val = RC4_encrypt(new_key, val)
# 8. Store the output from the final invocation of the RC4 as the value of
# the /O entry in the encryption dictionary.
return val
Expand Down Expand Up @@ -163,7 +162,7 @@ def _alg34(
# 2. Encrypt the 32-byte padding string shown in step 1 of algorithm 3.2,
# using an RC4 encryption function with the encryption key from the
# preceding step.
U = utils.RC4_encrypt(key, _encryption_padding)
U = RC4_encrypt(key, _encryption_padding)
# 3. Store the result of step 2 as the value of the /U entry in the
# encryption dictionary.
return U, key
Expand Down Expand Up @@ -195,7 +194,7 @@ def _alg35(
md5_hash = m.digest()
# 4. Encrypt the 16-byte result of the hash, using an RC4 encryption
# function with the encryption key from step 1.
val = utils.RC4_encrypt(key, md5_hash)
val = RC4_encrypt(key, md5_hash)
# 5. Do the following 19 times: Take the output from the previous
# invocation of the RC4 function and pass it as input to a new invocation
# of the function; use an encryption key generated by taking each byte of
Expand All @@ -206,7 +205,7 @@ def _alg35(
new_key = b_("")
for k in key:
new_key += b_(chr(ord_(k) ^ i))
val = utils.RC4_encrypt(new_key, val)
val = RC4_encrypt(new_key, val)
# 6. Append 16 bytes of arbitrary padding to the output from the final
# invocation of the RC4 function and store the 32-byte result as the value
# of the U entry in the encryption dictionary.
Expand Down
32 changes: 16 additions & 16 deletions PyPDF2/_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,23 @@
import struct
import uuid
import warnings
import random
import time

from hashlib import md5
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, cast

from PyPDF2._page import PageObject
from PyPDF2._reader import PdfFileReader
from PyPDF2._security import _alg33, _alg34, _alg35
from PyPDF2.constants import CatalogAttributes as CA
from PyPDF2.constants import Core as CO
from PyPDF2.constants import EncryptionDictAttributes as ED
from PyPDF2.constants import PageAttributes as PG
from PyPDF2.constants import PagesAttributes as PA
from PyPDF2.constants import StreamAttributes as SA
from PyPDF2.constants import TrailerKeys as TK
from PyPDF2.generic import (
from ._page import PageObject
from ._reader import PdfFileReader
from ._security import _alg33, _alg34, _alg35
from .constants import CatalogAttributes as CA
from .constants import Core as CO
from .constants import EncryptionDictAttributes as ED
from .constants import PageAttributes as PG
from .constants import PagesAttributes as PA
from .constants import StreamAttributes as SA
from .constants import TrailerKeys as TK
from .generic import (
ArrayObject,
BooleanObject,
ByteStringObject,
Expand All @@ -65,7 +68,7 @@
TreeObject,
createStringObject,
)
from PyPDF2.types import (
from .types import (
BookmarkTypes,
BorderArrayType,
FitType,
Expand All @@ -74,7 +77,7 @@
ZoomArgsType,
ZoomArgType,
)
from PyPDF2.utils import StreamType, b_
from .utils import StreamType, b_

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -496,9 +499,6 @@ def encrypt(
control annotations, 9 for form fields, 10 for extraction of
text and graphics.
"""
import random
import time

if owner_pwd is None:
owner_pwd = user_pwd
if use_128bit:
Expand Down
Loading

0 comments on commit 4429066

Please sign in to comment.