Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
9 changes: 2 additions & 7 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ body:
attributes:
label: PyMuPDF version
options:
- 1.26.1
- 1.26.0
- 1.25.5
- 1.25.4
- 1.25.3
- 1.25.2
- 1.25.1
- 1.25.0
- 1.24.x or earlier
- 1.25.x or earlier
- Built from source
description: |
* For example from `pymupdf.VersionBind`.
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,7 @@ jobs:
#
- uses: actions/upload-artifact@v4
with:
path: ./wheelhouse/pymupdf*.whl
path: |
wheelhouse/pymupdf*.whl
wheelhouse/pymupdf*.tar.gz
name: artifact-${{ matrix.os }}
5 changes: 4 additions & 1 deletion changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Change Log
==========


**Changes in version 1.26.1 ()**
**Changes in version 1.26.1**

* Use MuPDF-1.26.2.

Expand All @@ -18,6 +18,9 @@ Change Log
* New method `Document.rewrite_images()`, useful for reducing file size, changing image formats, or converting color spaces.
* `Page.get_text()`: restrict positional args to match docs.
* Removed bogus definition of class `Shape`.
* Removed release date from module, docs and changelog.
* `pymupdf.pymupdf_date` and `pymupdf.VersionDate` are now both None.
* They will be removed in a future release.


**Changes in version 1.26.0 (2025-05-22)**
Expand Down
8 changes: 3 additions & 5 deletions docs/vars.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ Constants

.. py:data:: pymupdf_date

ISO timestamp *YYYY-MM-DD HH:MM:SS* when these bindings were built.

:type: string

Disabled (set to None) in 1.26.1.

.. py:data:: version

(pymupdf_version, mupdf_version, timestamp) -- combined version information where `timestamp` is the generation point in time formatted as "YYYYMMDDhhmmss".
Expand All @@ -97,7 +95,7 @@ Constants

.. py:data:: VersionDate

Legacy equivalent to `mupdf_version`.
Disabled (set to None) in 1.26.1.


.. _PermissionCodes:
Expand Down
2 changes: 1 addition & 1 deletion docs/version.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
----

This documentation covers **PyMuPDF v1.26.0** features as of **2025-05-22 00:00:01**.
This documentation covers **PyMuPDF v1.26.1**.

The major and minor versions of |PyMuPDF| and |MuPDF| will always be the same. Only the third qualifier (patch level) may deviate from that of |MuPDF|.

Expand Down
83 changes: 56 additions & 27 deletions scripts/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
its own new venv to build PyMuPDF. Otherwise we force pip to use the
current venv.

--cibw-archs-linux <archs>
Set CIBW_ARCHS_LINUX, e.g. to `auto64 aarch64`. Default is `auto64` so
this allows control over whether to build linux-aarch64 wheels.

--cibw-name <cibw_name>
Name to use when installing cibuildwheel, e.g.:
--cibw-name cibuildwheel==3.0.0b1
Expand All @@ -75,9 +79,20 @@
...` fails with:
emcc: error: binary: No such file or directory ("binary" was expected to be an input file, based on the commandline arguments provided)

--cibw-release-1
Set up so that `cibw` builds all wheels except linux-aarch64, and sdist
if on Linux.

--cibw-release-2
Set up so that `cibw` builds only linux-aarch64 wheel.

-d
Equivalent to `-b debug`.

--dummy
Sets PYMUPDF_SETUP_DUMMY=1 which makes setup.py build a dummy wheel
with no content. For internal testing only.

-e <name>=<value>
Add to environment used in build and test commands. Can be specified
multiple times.
Expand Down Expand Up @@ -201,11 +216,6 @@

If CIBW_ARCHS is unset we set $CIBW_ARCHS_WINDOWS, $CIBW_ARCHS_MACOS
and $CIBW_ARCHS_LINUX to auto64 if they are unset.

Additionally, if running on Github ($GITHUB_ACTIONS=true) and
$CIBW_ARCHS_LINUX is unset, we set $CIBW_ARCHS_LINUX to 'auto64
aarch64' so that we build for aarch64 using emulation. This is required
as of 2025-05-23 because there is no native aarch64 host available.

install <pymupdf>
Install with `pip install --force-reinstall <pymupdf>`.
Expand Down Expand Up @@ -269,10 +279,6 @@ def main(argv):
if github_workflow_unimportant():
return

if len(argv) == 1:
show_help()
return

build_isolation = None
cibw_name = 'cibuildwheel'
cibw_pyodide = None
Expand All @@ -286,6 +292,7 @@ def main(argv):
pyodide_build_version = None
pytest_options = ''
pytest_prefix = None
cibw_sdist = None
show_args = False
show_help = False
sync_paths = False
Expand Down Expand Up @@ -330,6 +337,20 @@ def main(argv):
elif arg == '--build-isolation':
build_isolation = int(next(args))

elif arg == '--cibw-release-1':
cibw_sdist = True
env_extra['CIBW_ARCHS_LINUX'] = 'auto64'
env_extra['CIBW_ARCHS_MACOS'] = 'auto64'
env_extra['CIBW_ARCHS_WINDOWS'] = 'auto' # win32 and win64.
env_extra['CIBW_SKIP'] = 'pp* *i686 cp36* cp37* *musllinux*aarch64*'

elif arg == '--cibw-release-2':
env_extra['CIBW_ARCHS_LINUX'] = 'aarch64'
os_names = ['linux']

elif arg == '--cibw-archs-linux':
env_extra['CIBW_ARCHS_LINUX'] = next(args)

elif arg == '--cibw-name':
cibw_name = next(args)

Expand All @@ -339,6 +360,10 @@ def main(argv):
elif arg == '-d':
env_extra['PYMUPDF_SETUP_MUPDF_BUILD_TYPE'] = 'debug'

elif arg == '--dummy':
env_extra['PYMUPDF_SETUP_DUMMY'] = '1'
env_extra['CIBW_TEST_COMMAND'] = ''

elif arg == '-e':
_nv = next(args)
assert '=' in _nv, f'-e <name>=<value> does not contain "=": {_nv!r}'
Expand Down Expand Up @@ -493,7 +518,7 @@ def main(argv):

elif command == 'cibw':
# Build wheel(s) with cibuildwheel.
cibuildwheel(env_extra, cibw_name, cibw_pyodide)
cibuildwheel(env_extra, cibw_name, cibw_pyodide, cibw_sdist)

elif command.startswith('install.'):
name = command[len('install.'):]
Expand Down Expand Up @@ -629,27 +654,33 @@ def build(
run(f'pip install{build_isolation_text} -v --force-reinstall {pymupdf_dir_abs}', env_extra=env_extra)


def cibuildwheel(env_extra, cibw_name, cibw_pyodide):
def cibuildwheel(env_extra, cibw_name, cibw_pyodide, cibw_sdist):

if cibw_sdist and platform.system() == 'Linux':
log(f'Building sdist.')
run(f'cd {pymupdf_dir_abs} && {sys.executable} setup.py -d wheelhouse sdist', env_extra=env_extra)
sdists = glob.glob(f'{pymupdf_dir_abs}/wheelhouse/pymupdf-*.tar.gz')
log(f'{sdists=}')
assert sdists

run(f'pip install --upgrade {cibw_name}')

# Some general flags.
env_extra['CIBW_BUILD_VERBOSITY'] = '1'
env_extra['CIBW_SKIP'] = 'pp* *i686 cp36* cp37* *musllinux* *-win32 *-aarch64'
if 'CIBW_BUILD_VERBOSITY' not in env_extra:
env_extra['CIBW_BUILD_VERBOSITY'] = '1'
if 'CIBW_SKIP' not in env_extra:
env_extra['CIBW_SKIP'] = 'pp* *i686 cp36* cp37* *musllinux* *-win32 *-aarch64'

# Set what wheels to build, if not already specified.
if os.environ.get('CIBW_ARCHS') is None:
if os.environ.get('CIBW_ARCHS_WINDOWS') is None:
if 'CIBW_ARCHS' not in env_extra:
if 'CIBW_ARCHS_WINDOWS' not in env_extra:
env_extra['CIBW_ARCHS_WINDOWS'] = 'auto64'

if os.environ.get('CIBW_ARCHS_MACOS') is None:
if 'CIBW_ARCHS_MACOS' not in env_extra:
env_extra['CIBW_ARCHS_MACOS'] = 'auto64'

if os.environ.get('CIBW_ARCHS_LINUX') is None:
if 'CIBW_ARCHS_LINUX' not in env_extra:
env_extra['CIBW_ARCHS_LINUX'] = 'auto64'
if os.environ.get('GITHUB_ACTIONS') == 'true':
# Special case to use emulation/cross-compilation of
# aarch64 on Linux.
env_extra['CIBW_ARCHS_LINUX'] += ' aarch64'

# Tell cibuildwheel not to use `auditwheel` on Linux and MacOS,
# because it cannot cope with us deliberately having required
Expand All @@ -664,7 +695,8 @@ def cibuildwheel(env_extra, cibw_name, cibw_pyodide):
env_extra['CIBW_REPAIR_WHEEL_COMMAND_MACOS'] = ''

# Tell cibuildwheel how to test PyMuPDF.
env_extra['CIBW_TEST_COMMAND'] = f'python {{project}}/scripts/test.py test'
if 'CIBW_TEST_COMMAND' not in env_extra:
env_extra['CIBW_TEST_COMMAND'] = f'python {{project}}/scripts/test.py test'

# Specify python versions.
CIBW_BUILD = env_extra.get('CIBW_BUILD')
Expand Down Expand Up @@ -910,11 +942,8 @@ def getmtime(path):
return

pymupdf_dir_rel = gh_release.relpath(pymupdf_dir)
if pytest_options is None:
if valgrind:
pytest_options = '-s -vv'
else:
pytest_options = ''
if not pytest_options and pytest_prefix == 'valgrind':
pytest_options = '-sv'
if pytest_k:
pytest_options += f' -k {shlex.quote(pytest_k)}'
pytest_arg = ''
Expand Down
13 changes: 13 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
Location of devenv.com on Windows. If unset we search for it - see
wdev.py. if that fails we use just 'devenv.com'.

PYMUPDF_SETUP_DUMMY
If 1, we build dummy sdist and wheel with no files.

PYMUPDF_SETUP_FLAVOUR
Control building of separate wheels for PyMuPDF.

Expand Down Expand Up @@ -248,6 +251,10 @@ def run(command, check=1):
PYMUPDF_SETUP_URL_WHEEL = os.environ.get('PYMUPDF_SETUP_URL_WHEEL')
log(f'{PYMUPDF_SETUP_URL_WHEEL=}')

PYMUPDF_SETUP_DUMMY = os.environ.get('PYMUPDF_SETUP_DUMMY')
log(f'{PYMUPDF_SETUP_DUMMY=}')


def _fs_remove(path):
'''
Removes file or directory, without raising exception if it doesn't exist.
Expand Down Expand Up @@ -588,6 +595,10 @@ def build():
'''
pipcl.py `build_fn()` callback.
'''
if PYMUPDF_SETUP_DUMMY == '1':
log(f'{PYMUPDF_SETUP_DUMMY=} Building dummy wheel with no files.')
return list()

# Download MuPDF.
#
mupdf_local, mupdf_location = get_mupdf()
Expand Down Expand Up @@ -1175,6 +1186,8 @@ def _extension_flags( mupdf_local, mupdf_build_dir, build_type):

def sdist():
ret = list()
if PYMUPDF_SETUP_DUMMY == '1':
return ret

if PYMUPDF_SETUP_FLAVOUR == 'b':
# Create a minimal sdist that will build/install a dummy PyMuPDFb.
Expand Down
9 changes: 4 additions & 5 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ def _int_rc(text):

# Basic version information.
#
pymupdf_version = "1.26.0"
pymupdf_version = "1.26.1"
mupdf_version = mupdf.FZ_VERSION
pymupdf_date = "2025-05-22 00:00:01"
pymupdf_date = None

# Versions as tuples; useful when comparing versions.
#
Expand All @@ -389,11 +389,10 @@ def _int_rc(text):

# Legacy version information.
#
pymupdf_date2 = pymupdf_date.replace('-', '').replace(' ', '').replace(':', '')
version = (pymupdf_version, mupdf_version, pymupdf_date2)
version = (pymupdf_version, mupdf_version, None)
VersionFitz = mupdf_version
VersionBind = pymupdf_version
VersionDate = pymupdf_date
VersionDate = None


# String formatting.
Expand Down
14 changes: 14 additions & 0 deletions tests/run_compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ def main():

for i in implementations:
log(f'run_compound.py: {i=}')

cpu_bits = int.bit_length(sys.maxsize+1)
log(f'{os.getcwd()=}')
log(f'{platform.machine()=}')
log(f'{platform.platform()=}')
log(f'{platform.python_version()=}')
log(f'{platform.system()=}')
log(f'{platform.uname()=}')
log(f'{sys.executable=}')
log(f'{sys.version=}')
log(f'{sys.version_info=}')
log(f'{list(sys.version_info)=}')
log(f'{cpu_bits=}')

timeout = None
if endtime:
timeout = max(0, endtime - time.time())
Expand Down
Loading