AttributeError: After converting python script to EXE by Pyinstaller - python-2.7

I have made a python script for calculations purposes, importing libraries, Tkinter, Pmw, sympy, math, tkfiledialog, webbrowser.
Now, by using Pyinstaller I convert it into an EXE application.
When I run it, it gives the error:
WindowsError: [Error 3] The system cannot find the path specified: 'C:\\Python27\\Earthing\\dist\\Earthing\\Pmw/*.*'
So, I copy and paste the entire Pmw directory on this location. However, after doing this, I get the error:
AttributeError: 'module' object has no attribute 'OptionMenu'
Now, how do I resolve this error? Please do help me sort this out.

I ran into the same problem. It is due to what I would call 'dynamic imports', made mostly in PmwLoader.py (placed in lib subfolder): PmwLoader loads all the files, and the they become attributes of Pmw global library.
The solution I found was to manually delete the line 'import Pmw' in all the wanted Pmw files (I only used PmwComboBox and PmwScrolledFrame). PmwCombobox and PmwScrolledFrame notably need to import other Pmw files, so I had to replace
import Pmw
by
import PmwBase
import PmwScrolledListBox
import PmwEntryField
import PmwTimeFuncs
and then do the same in PmwScrolledListBox and PmwEntryFiled.
The the fun is to solve the bugs --notably replace a lot of the MegaWidget by PmwBase.MegaWidget, and so on.
In the end, it does not take more than one hour.
Good luck!
t.

Related

PyInstaller runs fine but exe file errors: No module named, Failed to Execute Script

I am running the following code:
pyinstaller --onefile main.py
main.py looks like:
import sys
import os
sys.path.append(r'C:\Model\Utilities')
from import_pythonpkg import *
......
import_pythonpkg.py looks like:
from astroML.density_estimation import EmpiricalDistribution
import calendar
import collections
from collections import Counter, OrderedDict, defaultdict
import csv
....
By running the pyinstaller on main.py, main.exe file is created successfully.
But when I run main.exe it gives error with astroML. If I move astroML to main.py from import_pythonpkg.py, there is no error with astroML. Now I get error with csv.
i.e. if I change my main.py to look as:
import sys
from astroML.density_estimation import EmpiricalDistribution
import os
sys.path.append(r'C:\Model\Utilities')
from import_pythonpkg import *
......
The astroML error is no longer present when I run main.exe.
There is no error with import calendar line in import_pythonpkg.py at all.
I am not sure how to handle this random error with packages when running main.exe after pyinstaller run.
import_pythonpkg is located at r'C:\Model\Utilities'
Edit:
Error with main.exe looks as following even though the original main.py runs fine. Pyinstaller was even able to let me create the main.exe without error.
Traceback (most recent call last):
File "main.py", line 8, in <module>
File "C:\Model\Utilities\import_pythonpkg.py", line 1, in <module>
from astroML.density_estimation import EmpiricalDistribution
ImportError: No module named astroML.density_estimation
[29180] Failed to execute script main
I believe PyInstaller is not seeing import_pythonpkg. In my experience, when adding to the path or dealing with external modules and dlls, PyInstaller will not go searching for that, you have to explicitly tell it to do so. It will compile down to an .exe properly because it just ignores it, but then won't run. Check to see if there are any warnings about missing packages or modules when you run your PyInstaller command.
But how to fix it...If indeed this is the issue (which I am not sure that it is) you can try 3 things:
1) move that package into your working directory and avoid using sys.path.append. Then compile with PyInstaller to so see if this works, then you know the issue is that pyinstaller is failing to find import_pythonpkg. You can stop there if this works.
2) explicitly tell PyInstaller to look there. You can use the hidden-import tag when compiling with PyInstaller to let it know (give it the full pathname).
--hidden-import=modulename
for more info, check here: How to properly create a pyinstaller hook, or maybe hidden import?
3) If you use the spec file that PyInstaller creates, you can try adding a variable call pathex to tell PyInstaller to search there for things:
block_cipher = None
a = Analysis(['minimal.py'],
pathex=['C:\\Program Files (x86)\\Windows Kits\\10\\example_directory'],
binaries=None,
datas=None,
hiddenimports=['path_to_import', 'path_to_second_import'],
hookspath=None,
runtime_hooks=None,
excludes=None,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,... )
coll = COLLECT(...)
for more information on spec files: https://pyinstaller.readthedocs.io/en/stable/spec-files.html
(notice you can also add hiddenimports here)
This answer may also prove helpful: PyInstaller - no module named
It is about to module which loaeded on your computer. If your IDE is different from your environment, you have to load same modules on your device via pip. Check the modules on CMD screen and complete the missing modules.
Sometimes you must load the modules all IDEs on your device. In my case, there were two IDEs (pycharm and anaconda). I used pycharm but pyinstaller used anaconda's modules so i unistalled anaconda and tried again. now it works..

py2exe fails to resolve ibm_db dependency (DLL)

I am trying to create an EXE using py2exe for a desktop app I wrote with python 2.7.
The app utilizes ibm_db (v2.0.7), which installs to site-packages as an .egg folder.
The contents of the ibm_db.py file are very short, as the logic itself is implemented in the DLL:
import os
if 'clidriver' not in os.environ['PATH']:
os.environ['PATH'] = os.environ['PATH'] + ";" + os.path.join(os.path.abspath(os.path.dirname(__file__)), 'clidriver', 'bin')
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__,'ibm_db_dlls\ibm_db.dll')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()
When I ran py2exe on the project, the dependency on ibm_db wasn’t properly handled (the DLL wasn’t taken into the dist), so running the exe file stumbles upon the following error:
...
File "ibm_db.pyc", line 10, in <module>
File "ibm_db.pyc", line 6, in __bootstrap__
ImportError: No module named pkg_resources
I tried to copy the DLL manually into the dist folder (both directly and under ibm_db_dlls subfolder), but it’s of no use.
I found this page, and realized that py2exe has an issue with eggs:
http://www.py2exe.org/index.cgi/ExeWithEggs
As far as I understand, unzipping the egg is not the way to go in my case, because my program does use pkg_resources (through ibm_db.py). Still, I tried installing ibm_db via easy_setup with the --always-unzip option, but the installation gave me this error:
Not a URL, existing file, or requirement spec: '--always-unzip'
and it was still installed as an .egg.
So I’m looking at the “Including .egg files in your dist directory” option, and wondering whether it can help. And if so – where to start?
I’m using this simple setup.py for running py2exe:
from distutils.core import setup
import py2exe
setup(console=['MyApp.py'])
What is this “TurboGears” mentioned there? It doesn’t look like something I’m using in my app.
Any advice will be appreciated.
Thanks.

redirecting python import to another module

I'm working on a large open source Python project, which has modules used by both the project and other projects. The goal is to move some of these modules out to a new "library" project that can then be imported by the original project and other projects.
To make this transition smooth, the thought was to copy the modules over to the new project, and have the original project then use the new import. However, to allow other project to have time to migrate later, the thought was to have the original module redirect the import.
For example, the usage is like this in repo 'neutron' (other projects could do the same):
cat neutron/consumer.py
from neutron.redirected import X
print(X)
The in the new 'neutron_lib' project created, the module looks like this (the same as what the original was in project 'neutron'):
cat ../neutron-lib/neutron_lib/redirected.py
X = 5
In the 'neutron' project, I'm trying to do this as the redirect module:
cat neutron/redirected.py
import neutron_lib.redirected
import sys
sys.modules['neutron.redirected'] = neutron_lib.redirected
When I run pylint, it gives these errors:
************* Module neutron.redirected
E: 1, 0: No name 'redirected' in module 'neutron_lib' (no-name-in-module)
************* Module neutron.consumer
E: 1, 0: No name 'X' in module 'neutron.redirected' (no-name-in-module)
If I run this, it runs fine, and consumer.py prints '5'. If I use ipython and load consumer.py, I can see 'X' in dir() output.
Any idea why I'm getting this pylint error? Is it a false error? Is there a way to override it?
Looks like, when running under tox, I can add the following to .pylintrc to hide the errors/warnings
no-name-in-module
nonstandard-exception
When I run pylint it passes now, as does running the Unit tests. Just wish I understood why I'm getting these errors/warnings though.

No module named os.path : wrong Python being called by bash

OS: CentOS 6.6
Python 2.7
So, I've (re)installed Canopy after it suddenly stopped working after an abrupt shutdown. It worked fine immediately after the install (I installed as my default Python). But after one reboot, when I try to open it with /root/Canopy/canopy (the icon under applications no longer works, either), I get the following error:
(Canopy 64bit) [xxuser#xxlinux ~]$ /root/Canopy/canopy Traceback (most recent call last): File "/home/xxuser/qiime_software/sphinx-1.0.4-release/lib/python2.7/site-packages/site.py", line 73, in <module>
__boot() File "/home/xxuser/qiime_software/sphinx-1.0.4-release/lib/python2.7/site-packages/site.py", line 2, in __boot
import sys, imp, os, os.path ImportError: No module named path
I found this link: Python - os.path doesn't exist: AttributeError: 'module' object has no attribute 'path', but both of my os.py and os.pyc were 250 and 700 bytes, respectively. There was another file called site.py which was 0 bytes and site.pyc was about 100 bytes. What are these files? And would deleting them hurt anything (which is what they did)? And why is this happening after reboot? (using reboot command).
I also found this: https://groups.google.com/forum/#!topic/spyderlib/hKB15JYyLqM , which could be relevant. I've updated my python path before with sys.path.append('/..')
My guess is that for some reason os.path isn't in sys.path? and __boot can't find it? But I'm new to Python and Linux and want to know what I'm doing before I go modifying any boot files, paths, etc.
Thanks in advance.
More information (saw that I'm supposed to update new info in an edit to original question. New to this.)
From one of the comments:
This is what I got:
import os.path
import posixpath
os.path
module 'posixpath' from '/home/xxuser/qiime_software/python-2.7.3-release/lib/python2.7/posixpath.pyc'
posixpath
module 'posixpath' from '/home/xxuser/qiime_software/python-2.7.3-release/lib/python2.7/posixpath.pyc'
Looks like os.path is there.
Could this have to do with a permissions error? I have it installed to /root/Canopy/canopy and I found this: docs.python.org/2/library/os.html#module-os (section 15.1.4). Does that make sense?
I'm also not sure if the following is related, but it might possibly. I can no longer seem to update my path with sys.path.append('/file/path/here'). It works until I close the terminal, then I have to re-append the next time I want to call a module from the new directory. Are sys.path and os.path related in any way?
Just fixed this on OSX with:
brew uninstall python
brew install python
No idea why, never seen it in 5 years of working with Python :S
It turns out that I was onto something with my last comment.
I'd downloaded a bunch of biology modules that depend on python, and so many of them came with their own install. When I added the modules to ~/.bashrc, my bash began calling them in advance of my original CentOS install. Resetting ~/.bashrc and restarting (for some reason source ~/.bashrc didn't work) eliminated all of the extra stuff I'd added to my $PATH and Canopy began working again. I'm going to go through and remove the extra installations of python and hopefully the issue will be behind me. Thanks to everyone who posted answers, especially A.J., because that's what got me thinking about .bashrc .
Edit: With some better understanding, this was all because of using python in a virtual environment. Canopy was resetting my path every time I opened it. I'm using a self-installed virtual environment now and have configured my path.
Try seeing if you have posixpath by typing import posixpath:
>>> import os.path
>>> os.path
<module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> ^D
bash-3.2$ python
>>> import posixpath
>>> posixpath
<module 'posixpath' from '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

py2exe can't find msvcp90.dll

I'm working on converting a simple GUI script written with Python 2.7 and Pyqt4 into a standalone executable using py2exe. I keep getting "no such file exists" errors, and I've managed to fix a few, though this one seems stubborn. It can't find msvcp90.dll, and returns an error message with a short traceback to distutils and then back to my py2exe script, which isn't very enlightening.
I've installed the MS C++ redistributable runtime, as recommended in
py2exe fails to generate an executable
but my script still can't locate the .dll. Below is my py2exe script, with the name of my script blocked out:
from distutils.core import setup
from py2exe.build_exe import py2exe
import sys, os, zmq
sys.argv.append('py2exe')
os.environ["PATH"] = \
os.environ["PATH"] + \
os.path.pathsep + os.path.split(zmq.__file__)[0]
setup(
options = {'py2exe':{'bundle_files':1,"includes":["zmq.utils",
"zmq.utils.jsonapi","zmq.utils.strtypes"]}},
console = [{'script':"#######.py"}],
zipfile = None
)
I've already fixed an issue with zmq (which isn't ever used by my script, or my GUI, for that matter, as far as I know). What am I doing wrong?
Right, I've managed to get my app to build, and although the question is now moderately old, it's my hope this is eventually of use to someone.
Firstly, py2exe is probably the wrong tool. It's old and AFAICT unmaintained. Consider PyInstaller instead. Using PyInstaller is literally as simple as installing it, installing PyWin32, and then going python %path_to_pyinstaller%/pyinstaller.py --onefile --windowed source.py. PyInstaller deals with all the mess of side by side assemblies and so on without you having to do anything.
In short, use PyInstaller.
However, to answer your question, this worked for me:
The question you've linked to - in particular this answer is the right start. Find the right DLLs and copy them to C:\Python27\DLLs
Ditch your existing setup.py file. If you're not using zmq, there's no reason to import it. Also, for a windowed application you want windows= not console=. My file goes (for packaging show.py):
#!/usr/bin/python
from distutils.core import setup
import py2exe
setup(options={'py2exe':{'bundle_files':1}},
windows=['show.py'])
(This is pinched off http://www.blog.pythonlibrary.org/2010/07/31/a-py2exe-tutorial-build-a-binary-series/)