Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ Session.vim

# -- built documentation site --
site/

# -- Playwright MCP session artifacts --
.playwright-mcp/
217 changes: 0 additions & 217 deletions .playwright-mcp/page-2026-08-05T09-21-55-291Z.yml

This file was deleted.

9 changes: 4 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ open an issue here too if you want it tracked.

**Anything upstream has declined, or has not adopted, belongs here.** That is the whole
reason this fork exists — tracked changes, fields, watermarks, floating images and the
rest. See the [2.0.0 milestone](https://github.com/toxicphreAK/python-docx-ng/milestone/1)
for what is planned and what is deliberately not started yet.
rest. See the [open issues](https://github.com/toxicphreAK/python-docx-ng/issues) for what
is planned and what is deliberately not started yet.

If you are unsure, open an issue and ask before writing code.

## Branches

- **`main`** is the 2.0.0 line and the only branch that takes work. It was restarted
from upstream v1.2.0 in August 2026; the fork's own features are being re-applied on
top one at a time.
- **`main`** is the 2.x line and the only branch that takes work. It was restarted from
upstream v1.2.0 in August 2026; the fork's own features have been re-applied on top.
- **`master`** is the 0.9.x record, kept for historical reference. Never target it, and
never port work back onto it.
- The **`upstream`** remote is read-only.
Expand Down
34 changes: 32 additions & 2 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
Release History
---------------

Unreleased
++++++++++
2.1.0 (2026-08-05)
++++++++++++++++++

Twenty-six issues from the 2.0.0 milestone. The theme, endnotes, OMML equations, the
custom XML data store, the VBA project and embedded OLE objects were all parts a
document could carry that nothing here could reach; they are reachable now. Styles grew
a usage closure and the cleanup built on it, numbering became writable, and content
gained a ``copy_to()`` that repairs what a deep copy breaks.

Behaviour changes
~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -142,6 +148,30 @@ New features
``Run.add_picture()``, plus ``.svg_image`` for the vector source of an SVG picture and
``Document.images`` for the package-level view. ``.image`` is ``None`` rather than an
error for a chart, a SmartArt diagram or a linked picture.
- ``Document.add_custom_xml_part()`` accepts an ``item_id``. The GUID it otherwise
generates was the one thing in this library's output that was not a function of its
input, which quietly cost byte-reproducibility for any document carrying a data store.

Fixes
~~~~~

- Every entry point that takes a path now accepts an ``os.PathLike`` as well as a ``str``.
``add_picture()``, ``add_float_picture()``, ``add_image_watermark()``,
``add_alt_chunk()``, ``add_embedded_object()`` and ``Image.from_file()`` tested
``isinstance(x, str)`` and fell through to the stream branch, so a ``pathlib.Path``
failed with ``AttributeError: 'PosixPath' object has no attribute 'seek'`` — a message
that says nothing about what was wrong. The README claimed this worked; now it does.
- ``python -m docx`` reports a document it cannot open rather than ending in a traceback.
``PackageNotFoundError`` — what a missing file or a non-package raises, and the most
common failure there is — is neither a ``FileNotFoundError`` nor a ``BadZipFile``, so it
went uncaught. A password-protected file now says so, and a ``--names`` or ``--keep``
naming a style the document does not define is reported rather than raised.
- ``styles list --used`` and ``--unused`` are mutually exclusive. Passing both matched
nothing and printed an empty list, which reads as an answer rather than as the
contradiction it is.
- ``copy_to()`` keeps a copied drawing's ``wp:docPr/@name``. Only ``@id`` has to be
unique; the name is the shape's own — the source file name for a picture — and
overwriting it discarded information and labelled a copied chart "Picture 3".

2.0.0 (2026-08-05)
++++++++++++++++++
Expand Down
Loading
Loading