# v2

## v2.16.1

- `unparse_content_stream` is now less strict about whether elements are lists or tuples, matching its v2.15.1 behavior.

## v2.16.0

- Performance improvement for `unparse_content_stream`.

- Fixed some linter warnings.

- Tightened pybind11 dependencies so we don’t accept new minor revisions automatically.

- Updated docs on FreeBSD.

## v2.15.1

- Fixed compatibility with pybind11 2.7.0 - some tests fail when previous versions of pikepdf are compiled with that version.

- Fixed a coverage code exclusion.

- Added a note missing “version added” comment to documentation.

- Fixed license string not appearing in metadata - thanks @mara004.

## v2.15.0

- Improved our `pdfdoc` codec to raise `UnicodeEncodeError` identifying the problem, instead of a less specific `ValueError`. Thanks to @regebro. #218

- We now implement stream reader/writer and incremental encoder/decoder for our `pdfdoc` codec, making it useful in more places.

- Fixed an issue with extracting JBIG2 images on Windows, due to Windows temporary file behavior. Thanks to @kraptor. #219

## v2.14.2

- Fixed a syntax error in type hints.

## v2.14.1

- Fixed the ReadTheDocs documentation build, which had broken after the `setup.cfg` changes in v2.13.0.

- Amended the Makefile with steps for building Apple Silicon wheels.

- No manual Apple Silicon release since there are no functional changes.

## v2.14.0

- Implemented a major new feature: overlays (watermarks, page composition). This makes it easier to solve many common tasks that involve copying content from pages to other pages, applying watermarks, headers/footers, etc. #42

- Added `pikepdf.Object.with_same_owner_as()` to simplify creating objects that have the same owner as another object.

- Many improvements to type hints for classes implemented in C++. #213, #214

## v2.13.0

- Build system modernized to use `setup.cfg` instead of `setup.py` as much as reasonable.

- The `requirements/*.txt` files are now deprecated. Instead use `pip install pikepdf[test,docs]` to install optional extras.

- Extended test coverage for a few tests that affect global state, using `pytest-forked` to isolate them.

- All C++ autoformatted with clang-format.

- We now imbue all C++ stringstreams with the C locale, to avoid formatting output incorrectly if another Python extension written in C++ happens to change the global `std::locale`.

## v2.12.2

- Rebuild wheels against libqpdf 10.3.2.

- Enabled building Linux PyPy x86_64 wheels.

- Fixed a minor issue where the inline images would have their abbreviations expanded when unparsed. While unlikely to be problematic, inline images usually use abbreviations in their metadata and should be kept that way.

- Added notes to documentation about loading PDFs through Python file streams and cases that can lead to poor performance.

## v2.12.1

- Fixed documentation typo and updated precommit settings.

- Ongoing improvements to code coverage: now related to image handling.

## v2.12.0

- Complete bindings for `pikepdf.Annotation` (useful for interpreting PDF form widgets, comments, etc.)

- Ongoing improvements to code coverage: minor bug fixes, unreachable code removal, more coverage.

## v2.11.4

- Fix #160, ‘Tried to call pure virtual function “TokenFilter::handle_token”’; this was a Python/C++ reference counting problem.

## v2.11.3

- Check for versions of jbig2dec that are too old to be supported (lacking the necessary command line arguments to extract an image from a PDF).

- Fix setup.py typo: cmd_class changed to cmdclass.

## v2.11.2

- Added missing documentation for `Pdf.is_encrypted`.

- Added some documentation annotations about when certain APIs were added or changed, going back to 2.0.

## v2.11.1

- Fixed an issue with `Object.emplace()` not retaining the original object’s /Parent.

- Code coverage improvements.

## v2.11.0

- Add new functions: `Pdf.generate_appearance_streams` and `Pdf.flatten_annotations`, to support common work with PDF forms.

- Fixed an issue with `pip install` on platforms that lack proper multiprocessing support.

- Additional documentation improvements from @m-holger - thanks again!

## v2.10.0

- Fixed a XML External Entity (XXE) processing vulnerability in PDF XMP metadata parsing. (Reported by Eric Therond of Sonarsource.) All users should upgrade to get this security update. CVE-2021-29421 was assigned to this issue.

- Bind new functions to check, when a PDF is opened, whether the password used to open the PDF matched the owner password, user password, or both: `Pdf.user_password_matched` and `Pdf.owner_password_matched`.

## v2.9.2

- Further expansion of test coverage of several functions, and minor bug fixes along the way.

- Improve parameter validation for some outline-related functions.

- Fixed overloaded `__repr__` functions in `_methods.py` not being applied.

- Some proofreading of the documentation by @m-holger - thanks!

## v2.9.1

- Further expansion of test coverage.

- Fixed function signatures for `_repr_mimebundle_` functions to match IPython’s spec.

- Fixed some error messages regarding attempts to do strange things with `pikepdf.Name`, like `pikepdf.Name.Foo = 3`.

- Eliminated code to handle an exception that provably does not occur.

- Test suite is now better at closing open file handles.

- Ensure that any demo code in README.md is valid and works.

- Embedded QPDF version in pikepdf Python wheels increased to 10.3.1.

## v2.9.0

- We now issue a warning when attempting to use `pikepdf.open` on a `bytes` object where it could be either a PDF loaded into memory or a filename.

- `pikepdf.Page.label` will now return the “ordinary” page number if no special rules for pages are defined.

- Many improvements to tests and test coverage. Code coverage for both Python and C++ is now automatically published to codecov.io; previously coverage was only checked on the developer’s machine.

- An obsolete private function `Object._roundtrip` was removed.

## v2.8.0

- Fixed an issue with extracting data from images that had their DecodeParms structured as a list of dictionaries.

- Fixed an issue where a dangling stream object is created if we fail to create the requested stream dictionary.

- Calling `Dictionary()` and `Array()` on objects which are already of that type returns a shallow copy rather than throwing an exception, in keeping with Python semantics.

- v2.8.0.post1: The CI system was changed from Azure Pipelines to GitHub Actions, a transition we made to support generating binary wheels for more platforms. This post-release was the first release made with GitHub Actions. It ought to be functionally identical, but could different in some subtle way, for example because parts of it may have been built with different compiler versions.

- v2.8.0.post2: The previous .post1 release caused binary wheels for Linux to grow much larger, causing problems for AWS Lambda who require small file sizes. This change strips the binaries of debug symbols, also mitigates a rare PyPy test failure.

- Unfortunately, it appears that the transition from Azure Pipelines to GitHub Actions broke compatibility with macOS 10.13 and older. macOS 10.13 and older are considered end of life by Apple. No version of pikepdf v2.x ever promised support for macOS 10.13 – 10.14+ has always been an explicit requirement. It just so happens that for some time, pikepdf did actually work on 10.13.

## v2.7.0

- Added an option to tell `Pdf.save` to recompress flate streams, and a global option to set the flate compression level. This option can be use to force the recompression of flate streams if they are not well compressed.

- Fixed “TypeError: only pages can be inserted” when attempting to an insert an unowned page using QPDF 10.2.0 or later.

## v2.6.0

- Rebuild wheels against QPDF 10.2.0.

## v2.5.2

- Fixed support for PyPy 3.7 on macOS.

## v2.5.1

- Rebuild wheels against recently released pybind11 v2.6.2.

- Improved support for building against PyPy 3.6/7.3.1.

## v2.5.0

- PyPy3 is now supported.

- Improved test coverage for some metadata issues.

## v2.4.0

- The DocumentInfo dictionary can now be deleted with `del pdf.docinfo`.

- Fixed issues with updating the `dc:creator` XMP metadata entry.

- Improved error messages on attempting to encode strings containing Unicode surrogates.

- Fixed a rare random test failure related to strings containing Unicode surrogates.

## v2.3.0

- Fixed two tests that failed with libqpdf 10.1.0.

- Add new function `pikepdf.Page.add_resource` which helps with adding a new object to the /Resources dictionary.

- Binary wheels now provide libqpdf 10.1.0.

## v2.2.5

- Changed how one C++ function is called to support libqpdf 10.1.0.

## v2.2.4

- Fixed another case where pikepdf should not be warning about metadata updates.

## v2.2.3

- Fixed a warning that was incorrectly issued in v2.2.2 when pikepdf updates XMP metadata on the user’s behalf.

- Fixed a rare test suite failure that occurred if two test files were generated with a different timestamp, due to timing of the tests.

- Hopefully fixed build on Cygwin (not tested, based on user report).

## v2.2.2

- Fixed #150, adding author metadata breaks PDF/A conformance. We now log an error when this metadata is set incorrectly.

- Improve type checking in ocrmypdf.models.metadata module.

- Improve documentation for custom builds.

## v2.2.1

- Fixed #143, PDF/A validation with veraPDF failing due to missing prefix on DocumentInfo dates.

## v2.2.0

- Added features to look up the index of an page in the document and page labels

- Enable parallel compiling (again)

- Make it easier to create a `pikepdf.Stream` with a dictionary or from an existing dictionary.

- Converted most `.format()` strings to f-strings.

- Fixed incorrect behavior when assigning `Object.stream_dict`; this use to create a dictionary in the wrong place instead of overriding a stream’s dictionary.

## v2.1.2

- Fixed an issue the XMP metadata would not have a timezone set when updated. According to the XMP specification, the timezone should be included. Note that pikepdf will include the local machine timezone, unless explicitly directed otherwise.

## v2.1.1

- The previous release inadvertently changed the type of exception in certain situations, notably throwing `ForeignObjectError` when this was not the correct error to throw. This release fixes that.

## v2.1.0

- Improved error messages and documentation around `Pdf.copy_foreign`.

- Opt-in to mypy typing.

## v2.0.0

This description includes changes in v2.0 beta releases.

Breaking changes

- We now require at least these versions or newer: - Python 3.6 - pybind11 2.6.0 - QPDF 10.0.3 - For macOS users, macOS 10.14 (Mojave)

- Attempting to modifying `Stream.Length` will raise an exception instead of a warning. pikepdf automatically calculates the length of the stream when a PDF is saved, so there is never a reason to modify this.

- `pikepdf.Stream()` can no longer parse content streams. That never made sense, since this class supports streams in general, and many streams are not content streams. Use `pikepdf.parse_content_stream` to a parse a content stream.

- `pikepdf.Permissions` is now represented as a `NamedTuple`. Probably not a concern unless some user made strong assumptions about this class and its superclass.

- Fixed the behavior of the `__eq__` on several classes to return `NotImplemented` for uncomparable objects, instead of `False`.

- The instance variable `PdfJpxImage.pil` is now a private variable.

New features

- Python 3.9 is supported.

- Significantly improved type hinting, including hints for functions written in C++.

- Documentation updates

Deprecations - `Pdf.root` is deprecated. Use `Pdf.Root`.

### v2.0.0b2

- We now require QPDF 10.0.3.

### v2.0.0b1

Breaking changes

- We now require at least these versions or newer: - Python 3.6 - pybind11 2.6.0 - QPDF 10.0.1 - For macOS users, macOS 10.14 (Mojave)

- Attempting to modifying `Stream.Length` will raise an exception instead of a warning.

- `pikepdf.Stream()` can no longer parse content streams. That never made sense, since this class supports streams in general, and many streams are not content streams. Use `pikepdf.parse_content_stream` to a parse a content stream.

- `pikepdf.Permissions` is now represented as a `NamedTuple`. Probably not a concern unless some user made strong assumptions about this class and its superclass.

- Fixed the behavior of the `__eq__` on several classes to return `NotImplemented` for uncomparable objects, instead of `False`.

New features

- Python 3.9 is supported.

- Significantly improved type hinting, including hints for functions written in C++.