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
59 changes: 51 additions & 8 deletions pipcl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3348,14 +3348,6 @@ def swig_get(swig, quick, swig_local='pipcl-swig-git'):
if quick and os.path.isfile(swig_binary):
log1(f'{quick=} and {swig_binary=} already exists, so not downloading/building.')
else:
# Clone swig.
swig_env_extra = None
swig_local = git_get(
swig_local,
text=swig,
remote='https://github.com/swig/swig.git',
branch='master',
)
if darwin():
run(f'brew install automake')
run(f'brew install pcre2')
Expand All @@ -3373,6 +3365,57 @@ def swig_get(swig, quick, swig_local='pipcl-swig-git'):
macos_add_brew_path('bison', swig_env_extra)
run(f'which bison')
run(f'which bison', env_extra=swig_env_extra)

# Building swig requires bison>=3.5.
bison_ok = 0
e, text = run(f'bison --version', capture=1, check=0, env_extra=swig_env_extra)
if not e:
log(textwrap.indent(text, ' '))
m = re.search('bison (GNU Bison) ([0-9]+)[.]([0-9]+)', text)
if m:
assert m, f'Unexpected output from `bison --version`: {text!r}'
version_tuple = int(m.group(1)), int(m.group2())
if version_tuple >= (3, 5):
bison_ok = 1
if not bison_ok:
if 0:
# Use git checkout. Fails to find scan-code.c. Presumably
# something wrong with ./bootstrap?
log(f'Cloning/fetching/build/installing bison.')
bison_git = git_get(
'pipcl-bison-git',
remote='https://git.savannah.gnu.org/git/bison.git',
#branch='master',
tag='v3.5.4',
submodules=0, # recursive update fails.
)
run(f'cd {bison_git} && git submodule update --init', prefix='bison git submodule update --init: ')
run(f'cd {bison_git} && ./bootstrap', prefix='bison bootstrap: ')
run(f'cd {bison_git} && ./configure', prefix='bison configure: ')
run(f'cd {bison_git} && make', prefix='bison make: ')
run(f'cd {bison_git} && sudo make install', prefix='bison make install: ')
else:
bison_version = 'bison-3.5.4'
if not os.path.exists(f'{bison_version}.tar.gz'):
run(
f'wget -O {bison_version}.tar.gz-0 http://www.mirrorservice.org/sites/ftp.gnu.org/gnu/bison/{bison_version}.tar.gz',
prefix='bison wget: ',
)
os.rename(f'{bison_version}.tar.gz-0', f'{bison_version}.tar.gz')
if not os.path.exists(f'{bison_version}'):
run(f'tar -xzf {bison_version}.tar.gz', prefix='bison extract: ')
run(f'cd {bison_version} && ./configure', prefix='bison configure: ')
run(f'cd {bison_version} && make', prefix='bison make: ')
run(f'cd {bison_version} && sudo make install', prefix='bison make install: ')

# Clone swig.
swig_env_extra = None
swig_local = git_get(
swig_local,
text=swig,
remote='https://github.com/swig/swig.git',
branch='master',
)
# Build swig.
run(f'cd {swig_local} && ./autogen.sh', env_extra=swig_env_extra)
run(f'cd {swig_local} && ./configure --prefix={swig_local}/install-dir', env_extra=swig_env_extra)
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ def add(flavour, from_, to_):
add('p', f'{g_root}/src/_wxcolors.py', to_dir)
add('p', f'{g_root}/src/_apply_pages.py', to_dir)
add('p', f'{g_root}/src/build/extra.py', to_dir)
add('p', b'', f'{to_dir}/py.typed')
if path_so_leaf:
add('p', f'{g_root}/src/build/{path_so_leaf}', to_dir)

Expand Down
Empty file removed src/py.typed
Empty file.
33 changes: 33 additions & 0 deletions tests/test_typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
import subprocess

import pymupdf


def run(command, check=1):
print(f'Running: {command}')
subprocess.run(command, shell=1, check=check)

def test_py_typed():
print(f'test_py_typed(): {pymupdf.__path__=}')
run('pip uninstall -y mypy')
run('pip install mypy')
root = os.path.abspath(f'{__file__}/../..')

# Run mypy on this .py file; it will fail at `import pymypdf` if the
# pymupdf install does not have a py.typed file.
#
# This doesn't actually check pymupdf's typing. It looks like
# we can do that with `mypy -m pymupdf`, but as of 2026-1-18 this
# gives many errors such as:
#
# ...site-packages/pymupdf/__init__.py:15346: error: point_like? has no attribute "y" [attr-defined]
#
# It's important to use `--no-incremental`, otherwise if one has
# experimented with `mypy -m pymupdf`, this test will get the
# same failures, via `.mypy_cache/` directories.
#
# We run in sub-directory to avoid spurious mypy errors
# if there is a local mupdf/ directory.
#
run(f'cd {root}/tests && mypy --no-incremental {os.path.abspath(__file__)}')