aboutsummaryrefslogtreecommitdiffstats
path: root/env/lib/python3.10/site-packages/pikepdf/objects.py
diff options
context:
space:
mode:
Diffstat (limited to 'env/lib/python3.10/site-packages/pikepdf/objects.py')
-rw-r--r--env/lib/python3.10/site-packages/pikepdf/objects.py300
1 files changed, 0 insertions, 300 deletions
diff --git a/env/lib/python3.10/site-packages/pikepdf/objects.py b/env/lib/python3.10/site-packages/pikepdf/objects.py
deleted file mode 100644
index 338d9f0..0000000
--- a/env/lib/python3.10/site-packages/pikepdf/objects.py
+++ /dev/null
@@ -1,300 +0,0 @@
-# SPDX-FileCopyrightText: 2022 James R. Barlow
-# SPDX-License-Identifier: MPL-2.0
-
-"""Provide classes to stand in for PDF objects.
-
-The purpose of these is to provide nice-looking classes to allow explicit
-construction of PDF objects and more pythonic idioms and facilitate discovery
-by documentation generators and linters.
-
-It's also a place to narrow the scope of input types to those more easily
-converted to C++.
-
-There is some deliberate "smoke and mirrors" here: all of the objects are truly
-instances of ``pikepdf.Object``, which is a variant container object. The
-``__new__`` constructs a ``pikepdf.Object`` in each case, and the rest of the
-class definition is present as an aide for code introspection.
-"""
-
-from __future__ import annotations
-
-# pylint: disable=unused-import, abstract-method
-from secrets import token_urlsafe
-from typing import TYPE_CHECKING, Any, Iterable, Mapping, cast
-from warnings import warn
-
-from . import _qpdf
-from ._qpdf import Object, ObjectType, Rectangle
-
-if TYPE_CHECKING: # pragma: no cover
- from pikepdf import Pdf
-
-# By default pikepdf.Object will identify itself as pikepdf._qpdf.Object
-# Here we change the module to discourage people from using that internal name
-# Instead it will become pikepdf.objects.Object
-Object.__module__ = __name__
-ObjectType.__module__ = __name__
-
-
-# type(Object) is the metaclass that pybind11 defines; we wish to extend that
-# pylint cannot see the C++ metaclass definition and is thoroughly confused.
-# pylint: disable=invalid-metaclass
-
-
-class _ObjectMeta(type(Object)): # type: ignore
- """Support instance checking."""
-
- def __instancecheck__(self, instance: Any) -> bool:
- # Note: since this class is a metaclass, self is a class object
- if type(instance) != Object:
- return False
- return self.object_type == instance._type_code
-
-
-class _NameObjectMeta(_ObjectMeta):
- """Support usage pikepdf.Name.Whatever -> Name('/Whatever')."""
-
- def __getattr__(self, attr: str) -> Any:
- if attr.startswith('_') or attr == 'object_type':
- return getattr(_ObjectMeta, attr)
- return Name('/' + attr)
-
- def __setattr__(self, attr: str, value: Any) -> None:
- # No need for a symmetric .startswith('_'). To prevent user error, we
- # simply don't allow mucking with the pikepdf.Name class's attributes.
- # There is no reason to ever assign to them.
- raise AttributeError(
- "Attributes may not be set on pikepdf.Name. Perhaps you meant to "
- "modify a Dictionary rather than a Name?"
- )
-
- def __getitem__(self, item: str) -> Name:
- if item.startswith('/'):
- item = item[1:]
- raise TypeError(
- "pikepdf.Name is not subscriptable. You probably meant:\n"
- f" pikepdf.Name.{item}\n"
- "or\n"
- f" pikepdf.Name('/{item}')\n"
- )
-
-
-class Name(Object, metaclass=_NameObjectMeta):
- """Construct a PDF Name object.
-
- Names can be constructed with two notations:
-
- 1. ``Name.Resources``
-
- 2. ``Name('/Resources')``
-
- The two are semantically equivalent. The former is preferred for names
- that are normally expected to be in a PDF. The latter is preferred for
- dynamic names and attributes.
- """
-
- object_type = ObjectType.name_
-
- def __new__(cls, name: str | Name) -> Name:
- """Construct a PDF Name."""
- # QPDF_Name::unparse ensures that names are always saved in a UTF-8
- # compatible way, so we only need to guard the input.
- if isinstance(name, bytes):
- raise TypeError("Name should be str")
- if isinstance(name, Name):
- return name # Names are immutable so we can return a reference
- return _qpdf._new_name(name)
-
- @classmethod
- def random(cls, len_: int = 16, prefix: str = '') -> Name:
- """Generate a cryptographically strong random, valid PDF Name.
-
- This function uses Python's secrets.token_urlsafe, which returns a
- URL-safe encoded random number of the desired length. An optional
- *prefix* may be prepended. (The encoding is ultimately done with
- :func:`base64.urlsafe_b64encode`.) Serendipitously, URL-safe is also
- PDF-safe.
-
- When the length parameter is 16 (16 random bytes or 128 bits), the result
- is probably globally unique and can be treated as never colliding with
- other names.
-
- The length of the string may vary because it is encoded.
- """
- random_string = token_urlsafe(len_)
- return _qpdf._new_name(f"/{prefix}{random_string}")
-
-
-class Operator(Object, metaclass=_ObjectMeta):
- """Construct an operator for use in a content stream.
-
- An Operator is one of a limited set of commands that can appear in PDF content
- streams (roughly the mini-language that draws objects, lines and text on a
- virtual PDF canvas). The commands :func:`parse_content_stream` and
- :func:`unparse_content_stream` create and expect Operators respectively, along
- with their operands.
-
- pikepdf uses the special Operator "INLINE IMAGE" to denote an inline image
- in a content stream.
- """
-
- object_type = ObjectType.operator
-
- def __new__(cls, name: str) -> Operator:
- """Construct an operator."""
- return cast('Operator', _qpdf._new_operator(name))
-
-
-class String(Object, metaclass=_ObjectMeta):
- """Construct a PDF String object."""
-
- object_type = ObjectType.string
-
- def __new__(cls, s: str | bytes) -> String:
- """
- Construct a PDF String.
-
- Args:
- s: The string to use. String will be encoded for
- PDF, bytes will be constructed without encoding.
-
- Return type:
- pikepdf.Object
- """
- if isinstance(s, bytes):
- return _qpdf._new_string(s)
- return _qpdf._new_string_utf8(s)
-
-
-class Array(Object, metaclass=_ObjectMeta):
- """Construct a PDF Array object."""
-
- object_type = ObjectType.array
-
- def __new__(cls, a: Iterable | Rectangle | None = None) -> Array:
- """
- Construct a PDF Array.
-
- Args:
- a: An iterable of objects. All objects must be either
- `pikepdf.Object` or convertible to `pikepdf.Object`.
-
- Return type:
- pikepdf.Array
- """
- if isinstance(a, (str, bytes)):
- raise TypeError('Strings cannot be converted to arrays of chars')
-
- if a is None:
- a = []
- elif isinstance(a, Rectangle):
- return a.as_array()
- elif isinstance(a, Array):
- return cast(Array, a.__copy__())
- return _qpdf._new_array(a)
-
-
-class Dictionary(Object, metaclass=_ObjectMeta):
- """Construct a PDF Dictionary object."""
-
- object_type = ObjectType.dictionary
-
- def __new__(cls, d: Mapping | None = None, **kwargs) -> Dictionary:
- """
- Construct a PDF Dictionary.
-
- Works from either a Python ``dict`` or keyword arguments.
-
- These two examples are equivalent:
-
- .. code-block:: python
-
- pikepdf.Dictionary({'/NameOne': 1, '/NameTwo': 'Two'})
-
- pikepdf.Dictionary(NameOne=1, NameTwo='Two')
-
- In either case, the keys must be strings, and the strings
- correspond to the desired Names in the PDF Dictionary. The values
- must all be convertible to `pikepdf.Object`.
-
- Return type:
- pikepdf.Dictionary
- """
- if kwargs and d is not None:
- raise ValueError('Cannot use both a mapping object and keyword args')
- if kwargs:
- # Add leading slash
- # Allows Dictionary(MediaBox=(0,0,1,1), Type=Name('/Page')...
- return _qpdf._new_dictionary({('/' + k): v for k, v in kwargs.items()})
- if isinstance(d, Dictionary):
- # Already a dictionary
- return d.__copy__()
- if not d:
- d = {}
- if d and any(key == '/' or not key.startswith('/') for key in d.keys()):
- raise KeyError("Dictionary created from strings must begin with '/'")
- return _qpdf._new_dictionary(d)
-
-
-class Stream(Object, metaclass=_ObjectMeta):
- """Construct a PDF Stream object."""
-
- object_type = ObjectType.stream
-
- def __new__(cls, owner: Pdf, data: bytes | None = None, d=None, **kwargs) -> Stream:
- """
- Create a new stream object.
-
- Streams stores arbitrary binary data and may or may not be compressed.
- It also may or may not be a page or Form XObject's content stream.
-
- A stream dictionary is like a pikepdf.Dictionary or Python dict, except
- it has a binary payload of data attached. The dictionary describes
- how the data is compressed or encoded.
-
- The dictionary may be initialized just like pikepdf.Dictionary is initialized,
- using a mapping object or keyword arguments.
-
- Args:
- owner: The Pdf to which this stream shall be attached.
- data: The data bytes for the stream.
- d: An optional mapping object that will be used to construct the stream's
- dictionary.
- kwargs: Keyword arguments that will define the stream dictionary. Do not set
- /Length here as pikepdf will manage this value. Set /Filter
- if the data is already encoded in some format.
-
- Examples:
- Using kwargs:
- >>> s1 = pikepdf.Stream(
- pdf,
- b"uncompressed image data",
- BitsPerComponent=8,
- ColorSpace=Name.DeviceRGB,
- ...
- )
- Using dict:
- >>> d = pikepdf.Dictionary(...)
- >>> s2 = pikepdf.Stream(
- pdf,
- b"data",
- d
- )
-
- .. versionchanged:: 2.2
- Support creation of ``pikepdf.Stream`` from existing dictionary.
-
- .. versionchanged:: 3.0
- Deprecated ``obj`` argument was removed; use ``data``.
- """
- if data is None:
- raise TypeError("Must make Stream from binary data")
-
- stream_dict = None
- if d or kwargs:
- stream_dict = Dictionary(d, **kwargs)
-
- stream = _qpdf._new_stream(owner, data)
- if stream_dict:
- stream.stream_dict = stream_dict
- return stream