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
2 changes: 1 addition & 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.27.2.2**
**Changes in version 1.27.2.2** (2026-03-20)

* Fixed issues:

Expand Down
18 changes: 18 additions & 0 deletions docs/faq/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,24 @@ FAQ
<div class="tip"><strong>Note:</strong> Threading with GIL release was tested but found to have intolerable overhead. Multiprocessing is the better approach for parallelism.</div>
</div>
</div>

<div class="faq">
<div class="faq-q"><span class="marker">Q</span><span class="question">Can I use multithreading with PyMuPDF, perhaps with <a href="https://docs.python.org/3/howto/free-threading-python.html">free-threading Python</a>?</span><span class="toggle">+</span></div>
<div class="faq-a">
<p>No, PyMuPDF does not support multithreaded use,
even with newer free-thread Python.

<p>Making PyMuPDF work with threads is a tricky problem.
The underlying MuPDF library only provides partial thread safety so the results would not be as performant as might be naively assumed,
and the implementation would inevitably introduce and expose subtle bugs.

<p>Any thread-safe implementation of PyMuPDF would also necessarily impose a single-threaded overhead.

<p>The preferred approach is to <a href="../recipes-multiprocessing.html">use multiple processes instead of multiple threads</a>.
This gives most of what is generally required,
with simplicity and guaranteed correctness.
</div>
</div>

</div>

Expand Down
28 changes: 18 additions & 10 deletions tests/test_codespell.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,28 @@ def test_codespell():
import pipcl
finally:
del sys.path[0]

git_files = pipcl.git_items(root)

for p in git_files:
_, ext = os.path.splitext(p)
if ext in ('.png', '.pdf', '.jpg', '.svg'):
pass
else:
command += f' {p}\n'
command_args_path = os.path.normpath(f'{__file__}/../test_codespell_args.txt')
command += f' @{command_args_path}'

with open(command_args_path, 'w') as f:

for p in git_files:
_, ext = os.path.splitext(p)
if ext in ('.png', '.pdf', '.jpg', '.svg'):
pass
else:
#command += f' {p}\n'
print(p, file=f)

if platform.system() != 'Windows':
command = command.replace('\n', ' \\\n')
# Don't print entire command because very long, and will be displayed
# anyway if there is an error.
#print(f'test_codespell(): Running: {command}')
print(f'Running codespell.')
if 0:
with open(command_args_path) as f:
command_args_path_contents = f.read()
print(f'command_args_path:{command_args_path_contents}')
print(f'Running codespell: {command}')
subprocess.run(command, shell=1, check=1)
print('test_codespell(): codespell succeeded.')
Loading