Closed suhren closed 4 weeks ago
Hi Adam,
thanks for you well described issue, and PR! Excited to see you use solara with pyinstaller! Could you elaborate on why you are using it, and for what kinda of project?
However, I don't fully understand the issue.
We can see here that the call
inspect.getfile(func)
is expected to provide the full absolute path to the file.
Why is that the case you think? If I look at the code path at https://github.com/widgetti/ipyvue/blob/9490c7b694414207cbb1ce8b15d993d80dda72bb/ipyvue/VueTemplateWidget.py#L140 this shouldn't be a problem.
Btw, did you see https://github.com/widgetti/solara/pull/724 ? It would be nice to include the issue you have in this PR as a test. I hope to work on it this week.
Also, I am surprised this is a problem, because this is being used in https://github.com/spacetelescope/jdaviz/ without having these issues.
Regards,
Maarten
Hi @maartenbreddels and thanks for replying. Let me elaborate on the behavior I am seeing with how inspect.getfile
works on Windows together with PyInstaller. Consider the following simple test program I have put in a file as app/main.py
:
import os
from inspect import getfile
def my_function():
pass
print(getfile(my_function))
print(os.path.abspath(getfile(my_function)))
input("Press any key to exit")
If I simply run this with Python as normal, I get the following output:
$ python app/main.py
> C:\Users\suhren\test-template-vue-file-path\app\main.py
> C:\Users\suhren\test-template-vue-file-path\app\main.py
> Press any key to exit
I.e., inspect.getfile
corretly gives the full path to the python file (and using os.path.abspath
doesn't change the path). However, if I try building this to an executable with pyinstaller, it behaves as follows:
# Build .exe using pyinstaller
$ pyinstaller app/main.py
# Launch the built .exe
$ ./dist/main/main.exe
> main.py
> C:\Users\suhren\test-template-vue-file-path\main.py
> Press any key to exit
Now, note that the raw output from inspect.getfile
now only gives the string "main.py", as opposed to the full path. Adding os.path.abspath
here, fixes it and produces the full path.
I have not yet had time to look at the other "jdaviz" project, or #724, but I can get back to you on that when I have time. But I hope the example I provided in this comment explains the issue. And as mentioned, my PR in #826 fixes this issue using PyInstaller (on my Windows system at least) and makes the vue components work as expected.
Making the path absolute seems like a good idea, which will also make it more robust again changing current directory. See:
Thanks for the details!
I have been using PyInstaller to create an executable .exe file for my solara application, and that has, in general, worked very well. However, recently I started using the Menu component and that caused the following issue when I was building the application to an executable using PyInstaller:
On the other hand, the solara application was working completely fine if I ran it as a normal python program from the terminal.
I belive I have traced the problem to the component_vue decorator which in turn calls a wrapper function that uses
inspect.getfile
to get the path to the file where the decorated function is defined. It looks like follows:We can see here that the call
inspect.getfile(func)
is expected to provide the full absolute path to the file. When not using a frozen executable on Windows (or using some other platform like Mac), this works as expected, but when using the frozen executable on Windows, theinspect.getfile(func)
will return a relative path, leading the the vue file not being found.A simple solution (which I have tested already) is to surround the
inspect.getfile(func)
withos.path.abspath
, as this will correctly resolve the path, no matter if the inspect module returns a relative path, or not.