My application works fine but I would like to understand why

57 views
Skip to first unread message

Sylvain Berger

unread,
Jan 12, 2021, 11:57:28 AM1/12/21
to PyInstaller

I am packaging a Qt window application using pyinstaller on windows 10; The application is working fine but I don't understand why it work (I hate when something looks like it shouldn't work but does work)

My application requires a few external module I wrote.

They are imported normally and are not hidden imports.

When using the --onedir method, I get a package with all the Qt dll and some standard library python module but not my external module. Yet the application is working fine, importing all the required modules and everything.

In my application if I import those modules and print them to see the path of the module, it points to the packaged folder, but the modules are not there, yet it works.

I feel really dumb asking this. It feels like I am simply missing something really obvious. what is going on? 

Thanks

Igor Riđanović

unread,
Jan 12, 2021, 2:00:03 PM1/12/21
to pyins...@googlegroups.com

Perhaps the packaged app is importing the modules from their expected paths on your system. Test it on a machine that has no Python.

--
You received this message because you are subscribed to the Google Groups "PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyinstaller/c21468b2-039a-42c7-844b-9a43767c4a03n%40googlegroups.com.
--
Igor Riđanović

www.metafide.com


Eric Fahlgren

unread,
Jan 12, 2021, 2:00:32 PM1/12/21
to pyins...@googlegroups.com
Have you tried installing and running on another machine, which does not have your module installed?  Could be leaking in through system path or something if you're testing on your development machine.

--

Sylvain Berger

unread,
Jan 13, 2021, 3:16:10 AM1/13/21
to PyInstaller
Yes and it works. I am using the single file option and running on a machine that doesn't have the library still works. It looks like that libs are hidden in the executable somehow. not sure if it is the case or not.

Eric Fahlgren

unread,
Jan 13, 2021, 10:19:44 AM1/13/21
to pyins...@googlegroups.com
My old standby for debugging this sort of thing is the venerable https://dependencywalker.com/ (which still works fine, if a little slow, on Win 10).  Try popping it up on your .exe and see if you can find your module there.  Right click on the file list and you can toggle "Full Paths" and see where the DLL is being found.

bwoodsend

unread,
Jan 18, 2021, 4:12:38 AM1/18/21
to PyInstaller

In my application if I import those modules and print them to see the path of the module, it points to the packaged folder, but the modules are not there, yet it works.

I’m assuming your modules are pure Python (.py suffix - no C extensions or DLLs)? Python code doesn’t just get copied into your build folder. It is precompiled to .pyc, collected into a big zip archive which then is embedded directly into the .exe file. You won’t be able to see it but if you build in --onedir mode then navigate inside the output, you’ll find a file called base-library.zip. This is also a zip archive of precompiled Python code except this one only contains some of the standard library (don’t ask me why this one’s separate).

Precompiling and zipping reduces the program size and speeds up initialisation just because there are less disk operations involved (Windows in particular is slow at handling lots of tiny files). But not everything can be lumped into a big zip archive. DLLs, including Python extension modules (.pyd) don’t work zipped and have to be copied in as is, which is why you will likely see parts of libraries inside your programs but nothing ending in .py. Data files, whilst they could sometimes be compressed in theory, are also just copied in as is. PyInstaller sets the __file__ attribute for Python files to point to where the .py file would have gone if it wasn’t put in the fancy zip archive. This way, even though __file__ itself doesn’t exist, the path to a data file derived from __file__ should, so it’s still possible for most libraries to locate their data files using __file__.

Sylvain Berger

unread,
Jan 18, 2021, 1:26:18 PM1/18/21
to pyins...@googlegroups.com
Wow thanks bwoodswnd for the amazing explanations. This explains everything perfectly. 
Now I can finally understand why it works. 

« PyInstaller sets the __file__ attribute for Python files to point to where the .py file would have gone if it wasn’t put in the fancy zip archive »
This explains everything and it makes sense now. Thanks for this

Sent from my iPhone

On Jan 18, 2021, at 4:12 AM, bwoodsend <bwoo...@gmail.com> wrote:



In my application if I import those modules and print them to see the path of the module, it points to the packaged folder, but the modules are not there, yet it works.

I’m assuming your modules are pure Python (.py suffix - no C extensions or DLLs)? Python code doesn’t just get copied into your build folder. It is precompiled to .pyc, collected into a big zip archive which then is embedded directly into the .exe file. You won’t be able to see it but if you build in --onedir mode then navigate inside the output, you’ll find a file called base-library.zip. This is also a zip archive of precompiled Python code except this one only contains some of the standard library (don’t ask me why this one’s separate).

Precompiling and zipping reduces the program size and speeds up initialisation just because there are less disk operations involved (Windows in particular is slow at handling lots of tiny files). But not everything can be lumped into a big zip archive. DLLs, including Python extension modules (.pyd) don’t work zipped and have to be copied in as is, which is why you will likely see parts of libraries inside your programs but nothing ending in .py. Data files, whilst they could sometimes be compressed in theory, are also just copied in as is. PyInstaller sets the __file__ attribute for Python files to point to where the .py file would have gone if it wasn’t put in the fancy zip archive. This way, even though __file__ itself doesn’t exist, the path to a data file derived from __file__ should, so it’s still possible for most libraries to locate their data files using __file__.

--
You received this message because you are subscribed to a topic in the Google Groups "PyInstaller" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyinstaller/9pqW0OP41RA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pyinstaller...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyinstaller/7d2d9ce1-e003-4df6-baeb-7ea0be29f13an%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages