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

Different behavior of "briefcase run" compared to launching .exe #1999

Open
MosGeo opened this issue Sep 19, 2024 · 4 comments
Open

Different behavior of "briefcase run" compared to launching .exe #1999

MosGeo opened this issue Sep 19, 2024 · 4 comments
Labels
bug A crash or error in behavior.

Comments

@MosGeo
Copy link

MosGeo commented Sep 19, 2024

Describe the bug

I've noticing a very peculiar issue.

I am packaging napari (www.napari.org) using briefcase. napari include When running the application using briefcase run, everything is fine. But, when launching the app from the generated exectable, the integrated console (which can be launched from window -> console does not work with the error below.

What is the difference between between briefcase run and launching the .exe that might cause this difference?

image

app.py

import sys
import napari

def main():
    viewer = napari.Viewer()
    sys.exit(napari.run())

pyproject.toml is the default one expect with the addition:

requires=["napari[all]"]

Steps to reproduce

Attached is the project for simplicity. In both cases, the app runs, however selecting Window menu - - > Console produces an error when launching from EXE case.
test_project.zip

Expected behavior

Briefcase run and launching the executable would produce exactly the same result.

Screenshots

No response

Environment

  • Operating System: Windows 11 and 10
  • Python version: 3.10
  • Software versions:
    • Briefcase: 0.3.19

Logs

No response

Additional context

No response

@MosGeo MosGeo added the bug A crash or error in behavior. label Sep 19, 2024
@rmartin16
Copy link
Member

rmartin16 commented Sep 19, 2024

I cannot replicate this on Windows. Whether I use briefcase run, run the exe from the console, or double-click the exe in the build directory, the app launches. You may need to elaborate on exactly how you're creating this error.

That said, a BeeWare app on Windows may not always have an attached console for the process; if Qt is relying on the underlying Python to always have an attached console, this may be an incompatibility currently.

@MosGeo
Copy link
Author

MosGeo commented Sep 20, 2024

To replicate the error: run the app (which lunches correctly in both cases) and select Windows menu - - > Console.

The console that the app is showing is a module in the app itself (an instance of qtconsole I believe). But you may be right. I am not familiar of the inner working of ipython and qtconsol

Any workaround?

P.s. I just tested the issue with an old version of briefcase (before stub files were introduced) and it seems in the past, it was worse. dev works, run doesn't even work.

@rmartin16
Copy link
Member

Ahh, sorry; I missed that you said this occurs when opening Window->Console. When I do that, I can replicate the issue.

Nonetheless, I'm pretty sure the issue is the same root cause; the Windows stub app doesn't always have a console attached...and when it doesn't, this Qt module seemingly cannot load properly. Ensuring that the stub app runs with a console may fix the issue....but this isn't currently supported. If you want to explore changing the stub app, you can use briefcase run windows visualstudio; this will use a stub app built from source that you can change within the build directory to do whatever you'd like.

@MosGeo
Copy link
Author

MosGeo commented Sep 20, 2024

Thanks @rmartin16. So, I created extra cases for testing and I was able to find a simple workaround.

It seems that qtconsole (https://github.com/jupyter/qtconsole) assumes the existance of standard input and output. I made an example without napari (just plain qtconsole) and I was able to see the actual error that is masked by napari.

The example that I made

import sys
import napari
from PyQt5.QtWidgets import QMainWindow, QApplication
from qtconsole.inprocess import QtInProcessKernelManager
from qtconsole.rich_ipython_widget import RichIPythonWidget


def main():

    app = QApplication(sys.argv)
    window = QMainWindow()

    # Create an in-process kernel
    kernel_manager = QtInProcessKernelManager()
    kernel_manager.start_kernel()
    kernel = kernel_manager.kernel
    kernel.gui = "qt4"

    kernel_client = kernel_manager.client()
    kernel_client.start_channels()

    def stop():
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel()
        app.exit()

    control = RichIPythonWidget()
    control.kernel_manager = kernel_manager
    control.kernel_client = kernel_client
    control.exit_requested.connect(stop)

    window.setCentralWidget(control)
    window.show()
    app.exec()

The error that you get when launching the application from the EXE is related to the flush function which is part of the standard output class.

image

To solve this, I just hooked up a pseodo standard output class on the initialization

class StandardIO:

    def write(self, string):
        pass

    def flush(self):
        pass

and in the main function

def main():
    std_io = StandardIO()
    sys.stdout = std_io
    sys.stderr = std_io
    ...

Doing the same thing for napari also solved the issue and the console showed using the executable.

It is not the most elegent solution but it works. For me, it is better than to modify the stub to use python.exe instead of pythonw.exe. I don't want a floating console showing up whenever the application is launched.

Specifically for napari, it might be worth it to hookup the standard output for console they are using to something real (e.g., debug output window). But that is a discussion for napari developers, not briefcase.

From my side, I consider this resolved for the time being and you can close the issue (unless you want it open o mitigate it from briefcase side in the future).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A crash or error in behavior.
Projects
None yet
Development

No branches or pull requests

2 participants