Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pypdfium2-team/pypdfium2
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2.7.2
Choose a base ref
...
head repository: pypdfium2-team/pypdfium2
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Loading
Showing with 15,370 additions and 5,106 deletions.
  1. +43 −0 .github/ISSUE_TEMPLATE/1_pypa.yml
  2. +52 −0 .github/ISSUE_TEMPLATE/2_conda.yml
  3. +32 −0 .github/ISSUE_TEMPLATE/3_other.yml
  4. +11 −0 .github/ISSUE_TEMPLATE/config.yml
  5. +41 −0 .github/PULL_REQUEST_TEMPLATE.md
  6. +17 −0 .github/dependabot.yml
  7. +171 −0 .github/workflows/conda.yaml
  8. +76 −0 .github/workflows/gh_pages.yaml
  9. +282 −0 .github/workflows/main.yaml
  10. +0 −77 .github/workflows/release.yaml
  11. +25 −13 .github/workflows/test_release.yaml
  12. +62 −0 .github/workflows/test_setup.yaml
  13. +67 −0 .github/workflows/test_sourcebuild.yaml
  14. +30 −0 .github/workflows/trigger_conda_raw.yaml
  15. +35 −0 .github/workflows/trigger_main.yaml
  16. +14 −13 .gitignore
  17. +9 −7 .readthedocs.yaml
  18. +0 −88 .reuse/dep5
  19. +0 −43 LICENSES/OFL-1.1.txt
  20. +27 −0 MANIFEST.in
  21. +0 −34 Makefile
  22. +832 −197 README.md
  23. +44 −0 REUSE-wheel.toml
  24. +131 −0 REUSE.toml
  25. +0 −1 autorelease/.gitkeep
  26. +3,864 −0 autorelease/bindings.py
  27. +5 −0 autorelease/config.json
  28. +4 −0 autorelease/record.json
  29. +177 −0 conda/craft_conda_pkgs.py
  30. +65 −0 conda/helpers/recipe/meta.yaml
  31. +15 −0 conda/prepare_script.py
  32. +22 −0 conda/raw/minitest.py
  33. +67 −0 conda/raw/recipe/meta.yaml
  34. +0 −1 data/.gitkeep
  35. +0 −1 docs/devel/.about_wheel_license.md
  36. +324 −0 docs/devel/changelog.md
  37. +52 −1 docs/devel/changelog_staging.md
  38. +0 −31 docs/devel/tasks.md
  39. +0 −351 docs/source/changelog.md
  40. +21 −0 docs/source/changelog.rst
  41. +45 −2 docs/source/conf.py
  42. +4 −8 docs/source/index.rst
  43. +0 −9 docs/source/planned_changes.md
  44. +95 −21 docs/source/python_api.rst
  45. +11 −0 docs/source/readme.md
  46. +39 −31 docs/source/shell_api.rst
  47. +4 −5 pyproject.toml
  48. +3 −0 req/converters.txt
  49. +6 −0 req/docs.txt
  50. +6 −0 req/setup.txt
  51. +2 −0 req/test.txt
  52. +5 −0 req/utilities.txt
  53. +86 −0 run
  54. +15 −61 setup.cfg
  55. +150 −96 setup.py
  56. +0 −2 setupsrc/pl_setup/__init__.py
  57. +0 −186 setupsrc/pl_setup/autorelease.py
  58. +0 −310 setupsrc/pl_setup/build_pdfium.py
  59. +0 −64 setupsrc/pl_setup/check_deps.py
  60. +0 −49 setupsrc/pl_setup/craft_packages.py
  61. +0 −137 setupsrc/pl_setup/packaging_base.py
  62. +0 −120 setupsrc/pl_setup/setup_base.py
  63. +0 −197 setupsrc/pl_setup/update_pdfium.py
  64. +2 −0 setupsrc/pypdfium2_setup/__init__.py
  65. +211 −0 setupsrc/pypdfium2_setup/autorelease.py
  66. +750 −0 setupsrc/pypdfium2_setup/base.py
  67. +131 −0 setupsrc/pypdfium2_setup/craft.py
  68. +105 −0 setupsrc/pypdfium2_setup/emplace.py
  69. +304 −0 setupsrc/pypdfium2_setup/sourcebuild.py
  70. +152 −0 setupsrc/pypdfium2_setup/update.py
  71. +0 −12 sourcebuild/patches/pdfium/win/pdfium.patch
  72. 0 sourcebuild/patches/{pdfium → }/public_headers.patch
  73. +4 −4 sourcebuild/patches/{pdfium → }/shared_library.patch
  74. +4 −4 sourcebuild/patches/{pdfium → }/win/build.patch
  75. 0 sourcebuild/patches/{pdfium → }/win/resources.rc
  76. +5 −9 src/pypdfium2/__init__.py
  77. +66 −4 src/pypdfium2/__main__.py
  78. +1 −1 src/pypdfium2/_cli/__init__.py
  79. +121 −21 src/pypdfium2/_cli/_parsers.py
  80. +48 −0 src/pypdfium2/_cli/arrange.py
  81. +87 −0 src/pypdfium2/_cli/attachments.py
  82. +89 −0 src/pypdfium2/_cli/extract_images.py
  83. +22 −31 src/pypdfium2/_cli/extract_text.py
  84. +0 −56 src/pypdfium2/_cli/find_pageobjects.py
  85. +62 −0 src/pypdfium2/_cli/imgtopdf.py
  86. +0 −77 src/pypdfium2/_cli/main.py
  87. +0 −56 src/pypdfium2/_cli/merge.py
  88. +119 −0 src/pypdfium2/_cli/pageobjects.py
  89. +58 −0 src/pypdfium2/_cli/pdfinfo.py
  90. +463 −105 src/pypdfium2/_cli/render.py
  91. +20 −32 src/pypdfium2/_cli/tile.py
  92. +33 −18 src/pypdfium2/_cli/toc.py
  93. +48 −0 src/pypdfium2/_deferred.py
  94. +6 −3 src/pypdfium2/_helpers/__init__.py
  95. +0 −84 src/pypdfium2/_helpers/_opener.py
  96. +0 −105 src/pypdfium2/_helpers/_utils.py
  97. +143 −0 src/pypdfium2/_helpers/attachment.py
  98. +390 −0 src/pypdfium2/_helpers/bitmap.py
  99. +540 −351 src/pypdfium2/_helpers/document.py
  100. +180 −0 src/pypdfium2/_helpers/matrix.py
  101. +8 −92 src/pypdfium2/_helpers/misc.py
  102. +413 −281 src/pypdfium2/_helpers/page.py
  103. +494 −0 src/pypdfium2/_helpers/pageobjects.py
  104. +194 −148 src/pypdfium2/_helpers/textpage.py
  105. +59 −0 src/pypdfium2/_helpers/unsupported.py
  106. +44 −0 src/pypdfium2/_library_scope.py
  107. +0 −8 src/pypdfium2/_namespace.py
  108. +6 −0 src/pypdfium2/internal/__init__.py
  109. +138 −0 src/pypdfium2/internal/bases.py
  110. +153 −0 src/pypdfium2/internal/consts.py
  111. +91 −0 src/pypdfium2/internal/utils.py
  112. +5 −0 src/pypdfium2/raw.py
  113. +150 −14 src/pypdfium2/version.py
  114. +5 −0 src/pypdfium2_raw/__init__.py
  115. +3 −1 tests/__init__.py
  116. +57 −38 tests/conftest.py
  117. +3 −0 tests/expectations/attachments_list.txt
  118. +40 −0 tests/expectations/pageobjects_images.txt
  119. +22 −0 tests/expectations/pdfinfo_attachments.txt
  120. +13 −0 tests/expectations/pdfinfo_forms.txt
  121. +41 −0 tests/expectations/pdfinfo_multipage.txt
  122. +17 −0 tests/expectations/text_extract.txt
  123. +9 −0 tests/expectations/toc.txt
  124. +3 −0 tests/expectations/toc_circular.txt
  125. +21 −0 tests/expectations/toc_maxdepth.txt
  126. +8 −0 tests/expectations/toc_viewmodes.txt
  127. +0 −2 tests/helpers/__init__.py
  128. +0 −248 tests/helpers/test_opener.py
  129. +0 −67 tests/helpers/test_page.py
  130. +0 −333 tests/helpers/test_renderer.py
  131. +0 −53 tests/helpers/test_saver.py
  132. +0 −205 tests/helpers/test_text.py
  133. +0 −152 tests/helpers/test_toc.py
  134. +0 −67 tests/helpers/test_utils.py
  135. BIN tests/resources/NotoSans-Regular.ttf
  136. BIN tests/resources/attachments.pdf
  137. BIN tests/resources/forms.pdf
  138. BIN tests/resources/mona_lisa.jpg
  139. +95 −0 tests/test_attachments.py
  140. +165 −1 tests/test_cli.py
  141. +253 −0 tests/test_document.py
  142. +167 −0 tests/test_misc.py
  143. +108 −0 tests/test_nup.py
  144. +238 −0 tests/test_opener.py
  145. +80 −0 tests/test_page.py
  146. +262 −0 tests/test_pageobjects.py
  147. +384 −0 tests/test_rendering.py
  148. +138 −0 tests/test_saving.py
  149. +0 −109 tests/test_setup.py
  150. +153 −0 tests/test_textpage.py
  151. +78 −0 tests/test_toc.py
  152. +0 −102 tests/test_version.py
  153. +0 −9 utilities/build.sh
  154. +0 −9 utilities/check.sh
  155. +0 −10 utilities/clean.sh
  156. +0 −11 utilities/install.sh
  157. +0 −17 utilities/packaging.sh
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE/1_pypa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: CC-BY-4.0

# TODO add separate template for source install issues?

# NOTE we'd like a slightly longer description, but GH seems to impose some length limit (undocumented?, feels like 200 chars or something)
name: PyPA install
description: If you installed via pip (or other PyPA format tool), and encountered an issue with the library. Use even if you believe it is not a package problem. Default template.

body:

- type: checkboxes
attributes:
label: Checklist
description: |
There might be unofficial PyPA packages of pypdfium2 in the wild.
**We do not support third-party builds, and they are not eligible for a bug report.** Please make sure to use our official packages.
options:
- label: I confirm to be using an **official package** of `pypdfium2` from `PyPI` or `GitHub/pypdfium2-team`.
required: true

- type: textarea
attributes:
label: Description
description: Please explain your problem.
validations:
required: true

- type: textarea
attributes:
label: Install Info
render: shell
description: |
To provide information about your install, please run the following commands and paste the output into the field below.
If the install failed, the last 2 commands may be skipped.
```shell
python -VV
python -c "import platform as p; print(p.platform())"
python -m pypdfium2 -v
python -m pip show pypdfium2
```
validations:
required: true
52 changes: 52 additions & 0 deletions .github/ISSUE_TEMPLATE/2_conda.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: CC-BY-4.0

name: Conda install
description: If you installed via conda, and encountered an issue with the library. Use even if you believe it is not a package problem.

body:

# use a separate md section instead of a checklist description for better visibility since it's rather likely to come across an unofficial build with conda
- type: markdown
attributes:
value: |
#### Package origin
There may be unofficial conda packages of pypdfium2/pdfium-binaries in other channels, including anaconda or conda-forge defaults. **We do not support third-party builds, and they are not eligible for a bug report.** Please use our official packages instead.
- type: checkboxes
attributes:
label: Checklist
options:
- label: I have verified to be using the **official packages** from the `pypdfium2-team` and `bblanchon` channels.
required: true
- label: I confirm **requirements are satisfied** and **no conflicting builds** of pypdfium2/pdfium-binaries installed at the same time.
required: true
- label: I confirm to be working with the **conda env in question, and its proper python executable** (not system python).
required: true

- type: textarea
attributes:
label: Description
description: Please explain your problem.
validations:
required: true

- type: textarea
attributes:
label: Install Info
render: shell
description: |
To provide information about your install, please run the following commands **with the right conda env and python executable**, and paste the output into the field below.
If the install failed, the last 3 commands may be skipped.
```shell
which python
python -VV
python -c "import platform as p; print(p.platform())"
conda list --show-channel-urls "pypdfium2|pdfium-binaries"
conda config --show-sources
python -m pypdfium2 -v
python -m pip show pypdfium2_raw
python -m pip show pypdfium2_helpers
```
validations:
required: true
32 changes: 32 additions & 0 deletions .github/ISSUE_TEMPLATE/3_other.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: CC-BY-4.0

name: Other issue
description: Generic issue template (e.g. for docs, setup). Do not use for issues with the core library.

body:

- type: checkboxes
attributes:
label: Checklist
options:
- label: I confirm this is **not a question or feature request**. *Otherwise, use the Discussions page.*
required: true
- label: I confirm this is **not an issue encountered with an installed build of pypdfium2, but about some other aspect of the project** (specify below). *Otherwise, use one of the package templates (PyPA/conda), even if you believe this is not a package-specific issue.*
required: true
- label: I confirm this is **not about an unofficial build of pypdfium2**. *We do not support third-party builds, and they are not eligible for a bug report.*
required: true

- type: input
attributes:
label: Reason for Generic issue (keyword/topic)
description: Briefly **justify** why you are using the Generic issue form.
validations:
required: true

- type: textarea
attributes:
label: Description
description: Please explain your problem.
validations:
required: true
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: CC-BY-4.0

blank_issues_enabled: false
contact_links:
- name: pypdfium2 discussions
url: https://github.com/pypdfium2-team/pypdfium2/discussions
about: pypdfium2 community support
- name: PDFium mailing list
url: https://groups.google.com/g/pdfium/
about: PDFium community support
41 changes: 41 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
**Important:** External contributors are required to comply with the template.

## Description

*Explain your changes here*

## Checklist

<!--
- Answer the questions below, choosing the section(s) relevant to your PR. Non-applying sections shall be set to `closed`.
- Place an `x` in the [ ] for yes, leave it empty for no. If a question is not applicable, remove the [ ], but keep the message in place.
- Use the Preview tab to confirm the PR will render correctly.
-->

<details open><summary>Helpers</summary>

- [ ] This PR changes helpers code.
- [ ] The change comes with sufficient test cases to confirm correct functionality.
- [ ] Any new test files are under a suitable license and have been registered in `REUSE.toml`.

</details>
<details open><summary>Setup</summary>

- [ ] This PR changes setup code (`setupsrc/`, `setup.py` etc.).
- [ ] I have read through relevant doc sections [Installation -> From source][1] and [Setup Magic][2].
- [ ] I have tested the change does not break internal callers.
- [ ] I believe the change is maintainable and does not cause unreasonable complexity or code fragmentation.
- [ ] The change does not shift a maintenance burden or upstream downstream tasks. *Keep handlers generic, avoid overly downstream-specific or (for us) effectively dead code passages.*
- [ ] I have assessed that the targeted use case cannot reasonably be satisfied by existing means, such as [Caller-provided data files][3], or the change forms a notable improvement over possible alternatives.
- [ ] I believe the targeted use case is supported by pypdfium2-team. *Note that we may not want to support esoteric or artificially restricted setup envs.*

[1]: https://github.com/pypdfium2-team/pypdfium2?tab=readme-ov-file#install-source
[2]: https://github.com/pypdfium2-team/pypdfium2?tab=readme-ov-file#setup-magic
[3]: https://github.com/pypdfium2-team/pypdfium2?tab=readme-ov-file#install-source-caller

</details>
<details open><summary>Other</summary>

- [ ] This PR changes other things, namely: ... <!-- sum up change (keyword/topic) -->

</details>
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2024 GitHub
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: LicenseRef-FairUse OR CC-BY-4.0

# Set update schedule for GitHub Actions

version: 2
updates:

- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
ignore:
- dependency-name: "benc-uk/workflow-dispatch"
versions: ["121"] # presumably an upstream accident
171 changes: 171 additions & 0 deletions .github/workflows/conda.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# SPDX-FileCopyrightText: 2025 geisserml <geisserml@gmail.com>
# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

name: Conda packaging
on:
workflow_dispatch:
inputs:
package:
type: choice
default: raw
options:
- raw
- helpers
pdfium_ver:
default: 'latest'
type: string
new_only:
# only with package == "raw", ignored otherwise (actually the default should be false in that case, but I don't know if GH supports dynamic defaults depending on other inputs)
default: true
type: boolean
test:
default: true
type: boolean
publish:
default: false
type: boolean
py_version:
default: '3.12'
type: string

# This is required for setup-miniconda / conda init
# see https://github.com/conda-incubator/setup-miniconda#important
defaults:
run:
shell: bash -el {0}

# TODO it might be nice to support building both packages in one run and testing the helpers package with the newly-built raw package, but this may be fairly complicated
# TODO add ability to rebuild helpers with different pdfium version bounds

jobs:

build:

runs-on: ubuntu-latest
steps:

- name: Check out repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}
fetch-depth: 0

- name: Miniconda setup
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: ${{ inputs.py_version }}
channels: pypdfium2-team,bblanchon
channel-priority: strict

- name: Prepare
run: |
python -VV
conda install -y conda-build conda-verify
git config --global user.email "geisserml@gmail.com"
git config --global user.name "geisserml"
python -m pip install -U -r req/setup.txt
# TODO might be able to unify with ${{ inputs.package == 'raw' && inputs.new_only && '--new-only' || '' }} or something

- name: Build package
if: ${{ inputs.package == 'helpers' || !inputs.new_only }}
run: ./run craft-conda ${{ inputs.package }} --pdfium-ver ${{ inputs.pdfium_ver }}

- name: Build package (new only)
if: ${{ inputs.package == 'raw' && inputs.new_only }}
run: ./run craft-conda ${{ inputs.package }} --pdfium-ver ${{ inputs.pdfium_ver }} --new-only

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: conda_package
path: conda/${{ inputs.package }}/out/

test:

if: ${{ inputs.test }}
needs: build

strategy:
fail-fast: false
matrix:
# NOTE On GH actions, macOS <=13 is Intel, whereas macOS >=14 will be ARM64
os: ['ubuntu-latest', 'ubuntu-24.04-arm', 'macos-13', 'macos-14', 'windows-latest']
py: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']

runs-on: ${{ matrix.os }}

steps:

- name: Check out repository
uses: actions/checkout@v4
with:
repository: ${{ github.repository }}

- name: Miniconda setup
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: ${{ matrix.py }}

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: conda_package
path: conda_dist/

- name: Show debug info
run: |
python -VV
ls -l conda_dist/
# according to the docs, --override-channels disables searching config file channels, and -c options priority decreases from left to right
- name: Install/Test raw package
if: inputs.package == 'raw'
run: |
conda install -y pypdfium2_${{ inputs.package }} --override-channels -c ./conda_dist/ -c bblanchon -c defaults
python conda/raw/minitest.py
- name: Install/Test helpers package
if: inputs.package == 'helpers'
run: |
conda install -y pytest pillow numpy
conda install -y pypdfium2_${{ inputs.package }} --override-channels -c ./conda_dist/ -c pypdfium2-team -c bblanchon -c defaults
pytest tests/
publish:

if: ${{ inputs.publish }}
needs: [build, test]
runs-on: ubuntu-latest

# TODO upload as GH release as well

steps:

# FIXME custom channels probably not necessary here
- name: Miniconda setup
uses: conda-incubator/setup-miniconda@v3
with:
auto-update-conda: true
python-version: ${{ matrix.py }}
channels: pypdfium2-team,bblanchon
channel-priority: strict

- name: Install deps
run: conda install -y anaconda-client

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: conda_package
path: conda_dist/

- name: Upload to Anaconda
env:
ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }}
run: |
ARTIFACT_PATH=conda_dist/noarch/pypdfium2_${{ inputs.package }}-*.conda
file $ARTIFACT_PATH
anaconda upload $ARTIFACT_PATH
Loading