Hello community,

here is the log from the commit of package python-pikepdf for openSUSE:Factory 
checked in at 2020-03-24 22:36:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pikepdf (Old)
 and      /work/SRC/openSUSE:Factory/.python-pikepdf.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pikepdf"

Tue Mar 24 22:36:31 2020 rev:3 rq:787784 version:1.10.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pikepdf/python-pikepdf.changes    
2020-03-17 13:09:08.157752463 +0100
+++ /work/SRC/openSUSE:Factory/.python-pikepdf.new.3160/python-pikepdf.changes  
2020-03-24 22:38:30.037268982 +0100
@@ -1,0 +2,7 @@
+Tue Mar 24 11:58:35 UTC 2020 - [email protected]
+
+- version update to 1.10.3
+  * Fixed ``isinstance(obj, pikepdf.Operator)`` not working. (#86)
+  * Documentation updates.  
+
+-------------------------------------------------------------------

Old:
----
  pikepdf-1.10.2.tar.gz

New:
----
  pikepdf-1.10.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pikepdf.spec ++++++
--- /var/tmp/diff_new_pack.0cNQ4N/_old  2020-03-24 22:38:30.569269241 +0100
+++ /var/tmp/diff_new_pack.0cNQ4N/_new  2020-03-24 22:38:30.573269243 +0100
@@ -20,31 +20,35 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-pikepdf
-Version:        1.10.2
+Version:        1.10.3
 Release:        0
 Summary:        Read and write PDFs with Python, powered by qpdf
 License:        MPL-2.0
 URL:            https://github.com/pikepdf/pikepdf
 Source:         
https://files.pythonhosted.org/packages/source/p/pikepdf/pikepdf-%{version}.tar.gz
+## SECTION test requirements
+BuildRequires:  %{python_module Pillow >= 5.0.0}
+BuildRequires:  %{python_module attrs >= 19.1.0}
 BuildRequires:  %{python_module devel}
+BuildRequires:  %{python_module hypothesis >= 4.24}
+BuildRequires:  %{python_module lxml >= 4.0}
 BuildRequires:  %{python_module pybind11 >= 2.4.3}
+BuildRequires:  %{python_module pytest >= 4.4.0}
+BuildRequires:  %{python_module pytest-helpers-namespace >= 2019.1.8}
+BuildRequires:  %{python_module pytest-timeout >= 1.3.3}
+BuildRequires:  %{python_module pytest-xdist}
 BuildRequires:  %{python_module setuptools_scm_git_archive}
 BuildRequires:  %{python_module setuptools_scm}
 BuildRequires:  %{python_module setuptools}
+## /SECTION
+BuildRequires:  fdupes
 BuildRequires:  gcc-c++
+BuildRequires:  pkgconfig
 BuildRequires:  python-pybind11-devel
 BuildRequires:  python-rpm-macros
 BuildRequires:  pkgconfig(libqpdf)
-## SECTION test requirements
-BuildRequires:  %{python_module Pillow >= 5.0.0}
-BuildRequires:  %{python_module hypothesis >= 4.24}
-BuildRequires:  %{python_module lxml >= 4.0}
-BuildRequires:  %{python_module pytest}
-## /SECTION
-BuildRequires:  fdupes
 Requires:       python-Pillow >= 5.0.0
 Requires:       python-lxml >= 4.0
-
 %python_subpackages
 
 %description
@@ -62,6 +66,10 @@
 %python_expand %fdupes %{buildroot}%{$python_sitearch}
 
 %check
+# /usr/lib/python3.8/site-packages/_pytest/python.py:1170: in _idval
+#     elif hasattr(val, "__name__") and isinstance(val.__name__, str):
+#     ValueError: object is not a dictionary or a stream
+rm tests/test_object.py
 %pytest_arch
 
 %files %{python_files}

++++++ pikepdf-1.10.2.tar.gz -> pikepdf-1.10.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/PKG-INFO new/pikepdf-1.10.3/PKG-INFO
--- old/pikepdf-1.10.2/PKG-INFO 2020-02-25 02:05:57.822245600 +0100
+++ new/pikepdf-1.10.3/PKG-INFO 2020-03-17 07:56:20.230840000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pikepdf
-Version: 1.10.2
+Version: 1.10.3
 Summary: Read and write PDFs with Python, powered by qpdf
 Home-page: https://github.com/pikepdf/pikepdf
 Author: James R. Barlow
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/debian/copyright 
new/pikepdf-1.10.3/debian/copyright
--- old/pikepdf-1.10.2/debian/copyright 2020-02-25 02:03:58.000000000 +0100
+++ new/pikepdf-1.10.3/debian/copyright 2020-03-17 07:53:39.000000000 +0100
@@ -43,6 +43,11 @@
 License: CC-BY-SA 2.0
  See: https://commons.wikimedia.org/wiki/File:Pike_square_img_3653.jpg
 
+Files: docs/images/28fish.jpg
+Copyright: (C) 2009 Fae
+License: CC-BY-4.0
+ See: 
https://upload.wikimedia.org/wikipedia/commons/0/0c/Twenty_eight_types_of_fish._Engraving_by_R._Scott_after_T._B_Wellcome_V0022737EL.jpg
+
 Files: tests/*.py
 Copyright: (C) 2017 James R. Barlow
 License: CC0-1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/conf.py 
new/pikepdf-1.10.3/docs/conf.py
--- old/pikepdf-1.10.2/docs/conf.py     2020-02-25 02:03:58.000000000 +0100
+++ new/pikepdf-1.10.3/docs/conf.py     2020-03-17 07:53:39.000000000 +0100
@@ -12,12 +12,15 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys
 import os
-from pkg_resources import get_distribution
 import subprocess
+import sys
 from unittest.mock import MagicMock
 
+from pkg_resources import get_distribution
+
+import pikepdf
+
 on_rtd = os.environ.get('READTHEDOCS') == 'True'
 if on_rtd:
     # Borrowed from 
https://github.com/YannickJadoul/Parselmouth/blob/master/docs/conf.py
@@ -76,7 +79,6 @@
 sys.path.insert(0, os.path.join(os.path.abspath('.'), './_ext'))
 sys.path.insert(0, os.path.join(os.path.abspath('.'), '..'))
 
-import pikepdf
 
 # -- General configuration ------------------------------------------------
 
@@ -116,7 +118,7 @@
 
 # General information about the project.
 project = u'pikepdf'
-copyright = u'2018, James R. Barlow'
+copyright = u'2020, James R. Barlow'
 author = u'James R. Barlow'
 
 # The version info for the project you're documenting, acts as replacement for
Binary files old/pikepdf-1.10.2/docs/images/28fish.jpg and 
new/pikepdf-1.10.3/docs/images/28fish.jpg differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/index.rst 
new/pikepdf-1.10.3/docs/index.rst
--- old/pikepdf-1.10.2/docs/index.rst   2020-02-25 02:03:58.000000000 +0100
+++ new/pikepdf-1.10.3/docs/index.rst   2020-03-17 07:53:39.000000000 +0100
@@ -101,9 +101,9 @@
 
 pikepdf is used by the same author's `OCRmyPDF
 <https://github.com/jbarlow83/OCRmyPDF>`_ to inspect input PDFs, graft the
-generated OCR layers on to page content, and output PDFs. Its code contains 
main
-practical examples, particular in ``pdfinfo.py``, ``_weave.py``, and
-``optimize.py``. pikepdf is also used in the test suite.
+generated OCR layers on to page content, and output PDFs. Its code contains 
several
+practical examples, particular in ``pdfinfo.py``, ``graft.py``, and
+``optimize.py``. pikepdf is also used in its test suite.
 
 .. toctree::
     :maxdepth: 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/installation.rst 
new/pikepdf-1.10.3/docs/installation.rst
--- old/pikepdf-1.10.2/docs/installation.rst    2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/installation.rst    2020-03-17 07:53:39.000000000 
+0100
@@ -24,7 +24,6 @@
 
     pip install pikepdf
 
-
 Use ``pip install --user pikepdf`` to install the package for the current user
 only. Use ``pip install pikepdf`` to install to a virtual environment.
 
@@ -46,7 +45,6 @@
 distributed with PyPI, but may be convenient for users that cannot use binary
 wheels.
 
-
 .. |pikepdf| image:: https://repology.org/badge/vertical-allrepos/pikepdf.svg
     :alt: Package status
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/release_notes.rst 
new/pikepdf-1.10.3/docs/release_notes.rst
--- old/pikepdf-1.10.2/docs/release_notes.rst   2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/release_notes.rst   2020-03-17 07:53:39.000000000 
+0100
@@ -18,6 +18,12 @@
 ``pikepdf._qpdf`` is a private interface within pikepdf that applications
 should not access directly, along with any modules with a prefixed underscore.
 
+v1.10.3
+=======
+
+-  Fixed ``isinstance(obj, pikepdf.Operator)`` not working. (#86)
+-  Documentation updates.
+
 v1.10.2
 =======
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/topics/content_streams.rst 
new/pikepdf-1.10.3/docs/topics/content_streams.rst
--- old/pikepdf-1.10.2/docs/topics/content_streams.rst  2020-02-25 
02:03:58.000000000 +0100
+++ new/pikepdf-1.10.3/docs/topics/content_streams.rst  2020-03-17 
07:53:39.000000000 +0100
@@ -6,8 +6,10 @@
 
 Content streams are binary data that can be thought of as a list of operators
 and zero or more operands. Operands are given first, followed by the operator.
-It is a stack-based language based loosely on PostScript (not actually 
PostScript!)
-but without any programmable features. There are no variables, loops or 
conditionals.
+It is a stack-based language, loosely based on PostScript. (It's not actually
+PostScript, but sometimes well-meaning people mistakenly say that it is!)
+Like HTML, it has a precise grammar, and also like (pure) HTML, it has no 
loops,
+conditionals or variables.
 
 A typical example is as follows (with additional whitespace and 
PostScript-style
 ``%``-comments):
@@ -106,18 +108,25 @@
 
 .. note::
 
-  You need to translate the image so that it is centered at the bottom left
-  corner of the page, rotate, and then reverse the translation.
+  To rotate an image, first translate it so that the image is centered at 
``(0, 0)``,
+  rotate then apply the rotate, then translate it to its new center position.
+  This is because rotations occur around ``(0, 0)``.
+
+.. note::
+
+  While the coordinate system is pinned to ``(0, 0)`` and **up is positive**,
+  the page's MediaBox does not have to be.
 
 Editing content streams robustly
 --------------------------------
 
 The stateful nature of PDF content streams makes editing them complicated. 
Edits
-like this will work when the input file is known to have a fixed structure
-(that is, the state at the time of editing is known). You can always prepend
-content to the top of the content stream, since the initial state is known.
-And you can often append content to the end the stream, since the final state 
is
-predictable if every ``q`` (push state) has a matching ``Q`` (pop state).
+like the example above will work when the input file is known to have a fixed
+structure (that is, the state at the time of editing is known). You can always
+prepend content to the top of the content stream, since the initial state is
+known. And you can often append content to the end the stream, since the final
+state is predictable if every ``q`` (push state) has a matching ``Q`` (pop
+state).
 
 Otherwise, you must track the graphics state and maintain a stack of states.
 
@@ -126,21 +135,17 @@
 rewriting the content stream. Content streams should be thought of as an
 output format.
 
-Some manipulations are more manageable. You can often prepend content to the
-top of the content stream or append to the end, or both, if the internal
-content stream is well-formed on each end.
-
 Extracting text from PDFs
 -------------------------
 
-If you guessed that the content streams were the place to look for text inside 
a PDF
-– you'd be correct. Unfortunately, extracting the text is fairly difficult 
because
-content stream actually specifies as a font and glyph numbers to use. 
Sometimes, there
-is a 1:1 transparent mapping between Unicode numbers and glyph numbers, and 
dump of the
-content stream will show the text. In general, you cannot rely on there being a
-transparent mapping; in fact, it is perfectly legal for a font to specify no 
Unicode
-mapping at all, or to use an unconventional mapping (when a PDF contains a 
subsetted
-font for example).
+If you guessed that the content streams were the place to look for text inside 
a
+PDF – you'd be correct. Unfortunately, extracting the text is fairly difficult
+because content stream actually specifies as a font and glyph numbers to use.
+Sometimes, there is a 1:1 transparent mapping between Unicode numbers and glyph
+numbers, and dump of the content stream will show the text. In general, you
+cannot rely on there being a transparent mapping; in fact, it is perfectly 
legal
+for a font to specify no Unicode mapping at all, or to use an unconventional
+mapping (when a PDF contains a subsetted font for example).
 
 **We strongly recommend against trying to scrape text from the content 
stream.**
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/topics/images.rst 
new/pikepdf-1.10.3/docs/topics/images.rst
--- old/pikepdf-1.10.2/docs/topics/images.rst   2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/topics/images.rst   2020-03-17 07:53:39.000000000 
+0100
@@ -69,7 +69,8 @@
 Extracting images is straightforward. :meth:`~pikepdf.PdfImage.extract_to` will
 extract images to a specified file prefix. The extension is determined while
 extracting and appended to the filename. Where possible, ``extract_to``
-writes compressed data directly to the stream without transcoding.
+writes compressed data directly to the stream without transcoding. (Transcoding
+lossy formats like JPEG can reduce their quality.)
 
 .. ipython::
     :verbatim:
@@ -80,7 +81,7 @@
 It also possible to extract to a writable Python stream using
 ``.extract_to(stream=...`)``.
 
-You can also retrieve the image as a Pillow image:
+You can also retrieve the image as a Pillow image (this will transcode):
 
 .. ipython::
 
@@ -88,9 +89,9 @@
 
 Another way to view the image is using Pillow's ``Image.show()`` method.
 
-Not all images can be extracted. Also, some PDFs describe an image with a
+Not all image types can be extracted. Also, some PDFs describe an image with a
 mask, with transparency effects. pikepdf can only extract the images
-themselves, not rasterize them exactly as they appear in a PDF viewer. In
+themselves, not rasterize them exactly as they would appear in a PDF viewer. In
 the vast majority of cases, however, the image can be extracted as it appears.
 
 .. note::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/topics/pages.rst 
new/pikepdf-1.10.3/docs/topics/pages.rst
--- old/pikepdf-1.10.2/docs/topics/pages.rst    2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/topics/pages.rst    2020-03-17 07:53:39.000000000 
+0100
@@ -163,6 +163,8 @@
 To preserve indirect references, use :meth:`pikepdf.Object.emplace`,
 which will (conceptually) delete all of the content of target and replace it
 with the content of source, thus preserving indirect references to the page.
+(Think of this as demolishing the interior of a house, but keeping it at the
+same address.)
 
 .. ipython::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/topics/streams.rst 
new/pikepdf-1.10.3/docs/topics/streams.rst
--- old/pikepdf-1.10.2/docs/topics/streams.rst  2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/topics/streams.rst  2020-03-17 07:53:39.000000000 
+0100
@@ -8,15 +8,22 @@
 object.
 
 Most of the interesting content in a PDF (images and content streams) are
-inside page objects.
+inside stream objects.
 
 Because the PDF specification unfortunately defines several terms involve the
 word stream, let's attempt to clarify:
 
+.. figure:: /images/28fish.jpg
+  :figwidth: 30%
+  :align: right
+  :alt: Image of many species of fish
+
+  When it comes to taxonomy, software developers have it easy.
+
 stream object
   A PDF object that contains binary data and a metadata dictionary to describes
   it, represented as :class:`pikepdf.Stream`. In HTML this is equivalent to
-  a ``<img>`` with inline image data.
+  a ``<object>`` tag with attributes and data.
 
 object stream
   A stream object (not a typo, an object stream really is a type of stream
@@ -34,6 +41,8 @@
   A group of images, text and drawing commands that can be rendered elsewhere
   in a PDF as a group. This is often used when a group of objects are needed
   at different scales or multiple pages. In HTML this is like an ``<svg>``.
+  It is not a fillable PDF form (although a fillable PDF form could involve
+  Form XObjects).
 
 Reading stream objects
 ----------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/docs/tutorial.rst 
new/pikepdf-1.10.3/docs/tutorial.rst
--- old/pikepdf-1.10.2/docs/tutorial.rst        2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/docs/tutorial.rst        2020-03-17 07:53:39.000000000 
+0100
@@ -33,8 +33,11 @@
 The PDF class API follows the example of the widely-used
 `Pillow image library <https://pillow.readthedocs.io/en/latest/>`_. For clarity
 there is no default constructor since the arguments used for creation and
-opening are different. ``Pdf.open()`` also accepts seekable streams as input,
-and ``Pdf.save()`` accepts streams as output.
+opening are different. To make a new empty PDF, use ``Pdf.new()`` not 
``Pdf()``.
+
+``Pdf.open()`` also accepts seekable streams as input, and ``Pdf.save()`` 
accepts
+streams as output. :class:`pathlib.Path` objects are fully supported anywhere
+pikepdf accepts a filename.
 
 Inspecting pages
 ----------------
@@ -59,7 +62,7 @@
 
 pikepdf integrates with IPython and Jupyter's rich object APIs so that you can
 view PDFs, PDF pages, or images within PDF in a IPython window or Jupyter
-notebook. This makes it to test visual changes.
+notebook. This makes easier it to test visual changes.
 
 .. ipython::
     :verbatim:
@@ -93,12 +96,12 @@
 
 In PDFs, the main data structure is the **dictionary**, a key-value data
 structure much like a Python ``dict`` or ``attrdict``. The major difference is
-that the keys can only be **names**, and can only be PDF types, including
+that the keys can only be **names**, and the values can only be PDF types, 
including
 other dictionaries.
 
 PDF dictionaries are represented as :class:`pikepdf.Dictionary`, and names
-are of type :class:`pikepdf.Name`. A page is just a dictionary with a few
-required files and a reference from the document's "page tree". (pikepdf 
manages
+are of type :class:`pikepdf.Name`. A page is just a dictionary with a certain
+required keys and a reference from the document's "page tree". (pikepdf manages
 the page tree for you.)
 
 .. ipython::
@@ -116,18 +119,15 @@
 
 .. ipython::
 
-    In [1]: page1
+    In [1]: repr(page1)
 
 The angle brackets in the output indicate that this object cannot be 
constructed
 with a Python expression because it contains a reference. When angle brackets
 are omitted from the ``repr()`` of a pikepdf object, then the object can be
 replicated with a Python expression, such as ``eval(repr(x)) == x``. Pages
-typically concern indirect references to themselves and other pages, so they
+typically have indirect references to themselves and other pages, so they
 cannot be represented as an expression.
 
-In Jupyter and IPython, pikepdf will instead attempt to display a preview of 
the PDF
-page, assuming a PDF rendering backend is available.
-
 Item and attribute notation
 ---------------------------
 
@@ -136,14 +136,16 @@
 
 .. ipython::
 
-    In [1]: page1.MediaBox      # preferred notation for required names
+    In [1]: page1.MediaBox      # preferred notation for standard PDF names
 
     In [1]: page1['/MediaBox']  # also works
 
-By convention, pikepdf uses attribute notation for standard names, and item
-notation for names that are set by PDF developers. For example, the images
+By convention, pikepdf uses attribute notation for standard names (the names
+that are normally part of a dictionary, according to the PDF Reference Manual),
+and item notation for names that may not always appear. For example, the images
 belong to a page always appear at ``page.Resources.XObject`` but the name
-of images is set by the PDF creator:
+of images is arbitrarily chosen by whatever software generates the PDF 
(``/Im0``,
+in this case). (Whenever expressed as strings, names begin with ``/``.)
 
 .. ipython::
     :verbatim:
@@ -179,8 +181,7 @@
 --------------
 
 Naturally, you can save your changes with :meth:`pikepdf.Pdf.save`.
-``filename`` can be a :class:`pathlib.Path`, which we accept everywhere. 
(Saving
-is commented out to avoid upsetting the documentation generator.)
+``filename`` can be a :class:`pathlib.Path`, which we accept everywhere.
 
 .. ipython::
     :verbatim:
@@ -188,12 +189,24 @@
     In [1]: pdf.save('output.pdf')
 
 You may save a file multiple times, and you may continue modifying it after
-saving.
+saving. For example, you could create an unencrypted version of document, then
+apply a watermark, and create an encrypted version.
+
+.. note::
+
+    You may not overwrite the input file (or whatever Python object provides 
the
+    data) when saving or at any other time. pikepdf assumes it will have
+    exclusive access to the input file or input data you give it to, until
+    ``pdf.close()`` is called.
+
+Saving secure PDFs
+^^^^^^^^^^^^^^^^^^
 
 To save an encrypted (password protected) PDF, use a 
:class:`pikepdf.Encryption`
-object to specify the encryption settings. By default, pikepdf selects the 
strongest
-security handler and algorithm (AES-256), but allows full access to modify 
file contents.
-A :class:`pikepdf.Permissions` object can be used to specify restrictions.
+object to specify the encryption settings. By default, pikepdf selects the
+strongest security handler and algorithm (AES-256), but allows full access to
+modify file contents. A :class:`pikepdf.Permissions` object can be used to
+specify restrictions.
 
 .. ipython::
     :verbatim:
@@ -204,6 +217,23 @@
        ...:      user="user password", owner="owner password", 
allow=no_extracting
        ...: ))
 
+As in all PDFs, if a user password is set, it will not be possible to
+open the PDF without the password. If the owner password is set, changes will
+not be permitted with the owner password. If the user password is an empty
+string and an owner password is set, the PDF can be viewed by anyone with the
+user (or owner) password. PDF viewers only enforce ``pikepdf.Permissions``
+restrictions when a PDF is opened with the user password, since the owner may
+change anything.
+
+pikepdf does not and cannot enforce the restrictions in ``pikepdf.Permissions``
+if you open a file with the user password. Someone with either the user or
+owner password can access all the contents of PDF. If you are developing an
+application, however, you should consider enforcing the restrictions.
+
+For widest compatibility, passwords should be ASCII, since the PDF reference
+manual is unclear about how non-ASCII passwords are supposed to be encoded.
+See the documentation on ``Pdf.save()`` for more details.
+
 Next steps
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/pikepdf/__init__.py 
new/pikepdf-1.10.3/src/pikepdf/__init__.py
--- old/pikepdf-1.10.2/src/pikepdf/__init__.py  2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/src/pikepdf/__init__.py  2020-03-17 07:53:39.000000000 
+0100
@@ -17,7 +17,7 @@
     msg = "pikepdf's extension library failed to import"
     if os.name == 'nt':
         msg += (
-            "\nYou may install Microsoft Visual C++ 2015-2019 "
+            "\nYou may need to install Microsoft Visual C++ 2015-2019 "
             "Redistributable (x64) 14.24.28127 or newer."
         )
     raise ImportError(msg) from _e
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/pikepdf/objects.py 
new/pikepdf-1.10.3/src/pikepdf/objects.py
--- old/pikepdf-1.10.2/src/pikepdf/objects.py   2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/src/pikepdf/objects.py   2020-03-17 07:53:39.000000000 
+0100
@@ -19,18 +19,16 @@
 class definition is present as an aide for code introspection.
 """
 
-from . import _qpdf
-
 # pylint: disable=unused-import, abstract-method
-from ._qpdf import Object, ObjectType, Operator
 
+from . import _qpdf
+from ._qpdf import Object, ObjectType
 
 # 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__
-Operator.__module__ = __name__
 
 
 # type(Object) is the metaclass that pybind11 defines; we wish to extend that
@@ -93,6 +91,14 @@
         return _qpdf._new_name(name)
 
 
+class Operator(Object, metaclass=_ObjectMeta):
+
+    object_type = ObjectType.operator
+
+    def __new__(cls, name):
+        return _qpdf.Operator(name)
+
+
 class String(Object, metaclass=_ObjectMeta):
     """Constructs a PDF String object"""
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/pikepdf.egg-info/PKG-INFO 
new/pikepdf-1.10.3/src/pikepdf.egg-info/PKG-INFO
--- old/pikepdf-1.10.2/src/pikepdf.egg-info/PKG-INFO    2020-02-25 
02:05:55.000000000 +0100
+++ new/pikepdf-1.10.3/src/pikepdf.egg-info/PKG-INFO    2020-03-17 
07:56:14.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pikepdf
-Version: 1.10.2
+Version: 1.10.3
 Summary: Read and write PDFs with Python, powered by qpdf
 Home-page: https://github.com/pikepdf/pikepdf
 Author: James R. Barlow
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/pikepdf.egg-info/SOURCES.txt 
new/pikepdf-1.10.3/src/pikepdf.egg-info/SOURCES.txt
--- old/pikepdf-1.10.2/src/pikepdf.egg-info/SOURCES.txt 2020-02-25 
02:05:57.000000000 +0100
+++ new/pikepdf-1.10.3/src/pikepdf.egg-info/SOURCES.txt 2020-03-17 
07:56:20.000000000 +0100
@@ -29,6 +29,7 @@
 docs/api/filters.rst
 docs/api/main.rst
 docs/api/models.rst
+docs/images/28fish.jpg
 docs/images/congress_im0.jpg
 docs/images/pdfcoords.svg
 docs/images/pike-cartoon.png
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/qpdf/object.cpp 
new/pikepdf-1.10.3/src/qpdf/object.cpp
--- old/pikepdf-1.10.2/src/qpdf/object.cpp      2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/src/qpdf/object.cpp      2020-03-17 07:53:39.000000000 
+0100
@@ -624,7 +624,7 @@
         .def_property_readonly("objgen",
             &object_get_objgen,
             R"~~~(
-            Return the object-generation number pair for this object
+            Return the object-generation number pair for this object.
 
             If this is a direct object, then the returned value is ``(0, 0)``.
             By definition, if this is an indirect object, it has a "objgen",
@@ -632,7 +632,10 @@
             Direct objects cannot necessarily be looked up.
 
             The generation number is usually 0, except for PDFs that have been
-            incrementally updated.
+            incrementally updated. Incrementally updated PDFs are now uncommon,
+            since it does not take too long for modern CPUs to reconstruct an
+            entire PDF. pikepdf will consolidate all incremental updates
+            when saving.
 
             )~~~"
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/src/qpdf/qpdf.cpp 
new/pikepdf-1.10.3/src/qpdf/qpdf.cpp
--- old/pikepdf-1.10.2/src/qpdf/qpdf.cpp        2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/src/qpdf/qpdf.cpp        2020-03-17 07:53:39.000000000 
+0100
@@ -502,8 +502,11 @@
             Args:
                 filename_or_stream (os.PathLike): Filename of PDF to open
                 password (str or bytes): User or owner password to open an
-                    encrypted PDF. If a str is given it will be converted to
-                    UTF-8.
+                    encrypted PDF. If the type of this parameter is ``str``
+                    it will be encoded as UTF-8. If the type is ``bytes`` it 
will
+                    be saved verbatim. Passwords are always padded or
+                    truncated to 32 bytes internally. Use ASCII passwords for
+                    maximum compatibility.
                 hex_password (bool): If True, interpret the password as a
                     hex-encoded version of the exact encryption key to use, 
without
                     performing the normal key computation. Useful in forensics.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pikepdf-1.10.2/tests/test_object.py 
new/pikepdf-1.10.3/tests/test_object.py
--- old/pikepdf-1.10.2/tests/test_object.py     2020-02-25 02:03:58.000000000 
+0100
+++ new/pikepdf-1.10.3/tests/test_object.py     2020-03-17 07:53:39.000000000 
+0100
@@ -24,10 +24,10 @@
     Name,
     Object,
     Operator,
+    Pdf,
     PdfError,
-    String,
     Stream,
-    Pdf,
+    String,
 )
 from pikepdf import _qpdf as qpdf
 
@@ -80,7 +80,7 @@
     assert lessthan == encoded_lessthan
 
 
-@given(integers(-10 ** 12, 10 ** 12), integers(0, 12))
+@given(integers(-(10 ** 12), 10 ** 12), integers(0, 12))
 def test_decimal_involution(num, radix):
     strnum = str(num)
     if radix > len(strnum):
@@ -491,3 +491,31 @@
         if isinstance(obj, Dictionary):
             assert len(obj.keys()) >= 1
     assert n + 1 == expected
+
+
[email protected](
+    'obj', [Array([1]), Dictionary({'/A': 'b'}), Operator('q'), String('s')]
+)
+def test_object_isinstance(obj):
+    assert isinstance(obj, (Array, Dictionary, Operator, String, Stream))
+    assert isinstance(obj, type(obj))
+    assert isinstance(obj, Object)
+
+
+def test_stream_isinstance():
+    pdf = pikepdf.new()
+    stream = Stream(pdf, b'xyz')
+    assert isinstance(stream, Stream)
+    assert isinstance(stream, Object)
+
+
+def test_object_classes():
+    classes = [Array, Dictionary, Operator, String, Stream]
+    for cls in classes:
+        assert issubclass(cls, Object)
+
+
+def test_operator_create():
+    Operator('q')
+    assert Operator('q') == Operator('q')
+    assert Operator('q') != Operator('Q')


Reply via email to