Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyMuPDF 1.24.12 with pyinstaller throws error. #3981

Open
wz93672 opened this issue Oct 22, 2024 · 6 comments
Open

PyMuPDF 1.24.12 with pyinstaller throws error. #3981

wz93672 opened this issue Oct 22, 2024 · 6 comments

Comments

@wz93672
Copy link

wz93672 commented Oct 22, 2024

Description of the bug

Lastest pymupdf with pyinstaller and console option set to false, throws on import AssertionError: No output specified.
Happen with last and older pyinstaller versions, dosen't happen with pythonw.exe.

Traceback (most recent call last):
  File "pymupdf_test.pyw", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "PyInstaller\loader\pyimod02_importers.py", line 384, in exec_module
  File "pymupdf\__init__.py", line 164, in <module>
  File "pymupdf\__init__.py", line 160, in _make_output
AssertionError: No output specified.

How to reproduce the bug

pymupdf_test.pyw:

import pymupdf
print(pymupdf.version)

pyinstaller command:

pyinstaller --noconsole pymupdf_test.pyw

PyMuPDF version

1.24.12

Operating system

Windows

Python version

3.12

@julian-smith-artifex-com
Copy link
Collaborator

It looks like sys.stdout is None. PyMuPDF might try to write to sys.stdout later, so this is probably a useful startup error until we've figured out a solution.

A workaround might be to set PYMUPDF_MESSAGE before importing pymupdf - see: https://pymupdf.readthedocs.io/en/latest/functions.html#PYMUPDF_MESSAGE

@jesuslop
Copy link

I have a similar issue, also in Windows.

The following code, run with pythonw (the recommended way to launch console-less apps), fails:

import pymupdf
import ctypes

ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

But If I comment the pymupdf import then it works.

I tried setting PYMUPDF_MESSAGE=path:kk.log in cmd to no avail, also set_messages()

So I'd say one cannot use pymupdf in console-less windows apps for the moment.

It looks like sys.stdout is None.

I'd say this is pythonw standard behaviour because it launches a console-less app.

@wz93672
Copy link
Author

wz93672 commented Oct 26, 2024

You can assign os.devnull to stdout and stderr:

if getattr(sys, 'frozen', None):
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = sys.stdout

I tried to use PYMUPDF_MESSAGE:

devnullfd = open(os.devnull, 'w').fileno()
os.environ['PYMUPDF_MESSAGE'] = f'fd:{devnullfd}'

import pymupdf

but it gives: OSError: [WinError 6]

@jesuslop
Copy link

I tried

import sys

if getattr(sys, 'frozen', None):
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = sys.stdout

import pymupdf
import ctypes

ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

but is the same, works launched by python but fails launched by pythonw (python 3.10 BTW).

Agreed that it has to do with std... streams because running pythonw xxx > nul works OK.

Can confirm that some earlier versions of pymupdf didn't have this problem, but can't pinpoint which.

@julian-smith-artifex-com
Copy link
Collaborator

It would be useful to see the full output when things fail.

I'm particularly interested in what's failing with PYMUPDF_MESSAGE=path:kk.log. (We have a test for this which has always passed.)

I have a fairly trivial patch to my tree which should fix the problem in the next release, but i don't have pythonw so i'm not 100% sure if will fix all scenarios.

@jesuslop
Copy link

Ok, as it happens redirecting stderr to file one recovers pythonw diagnostics.

So I run

import pymupdf
import ctypes

ctypes.windll.user32.MessageBoxW(0, "Your text", "Your title", 1)

with an environment with PYMUPDF_MESSAGE=path:C:\Users\jesus\log\kk.log
and it gives new empty log file.

But launching with pythonw message-box.pyw 2> error_file the file generated is

Traceback (most recent call last):
  File "C:\Users\jesus\backed-up\plain\scripts\ebook\old-3-way-merge\message-box.pyw", line 1, in <module>
    import pymupdf
  File "C:\Users\jesus\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\pymupdf\__init__.py", line 167, in <module>
    _g_out_log = _make_output(text=os.environ.get('PYMUPDF_LOG'), default=sys.stdout)
  File "C:\Users\jesus\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\pymupdf\__init__.py", line 160, in _make_output
    assert 0, f'No output specified.'
AssertionError: No output specified.

I don't seem to find documentation for PYMUPDF_LOG in google.

I defined both PYMUPDF_MESSAGE and PYMUPDF_LOG (with value a file path) and then stderr is

Traceback (most recent call last):
  File "C:\Users\jesus\backed-up\plain\scripts\ebook\old-3-way-merge\message-box.pyw", line 1, in <module>
    import pymupdf
  File "C:\Users\jesus\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\pymupdf\__init__.py", line 167, in <module>
    _g_out_log = _make_output(text=os.environ.get('PYMUPDF_LOG'), default=sys.stdout)
  File "C:\Users\jesus\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\pymupdf\__init__.py", line 120, in _make_output
    assert 0, f'Unrecognised {text=}.'
AssertionError: Unrecognised text='c:\\Users\\jesus\\log\\kk2.log'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@jesuslop @julian-smith-artifex-com @wz93672 and others