I'm trying to convert my .py script into an executable using py2exe. I've had a number of issues so far that have been largely addressed by the "options" in the setup file below. But now I have a problem that I have not been able to find a solution for, and wondering if others have had this same issue and fixed it.
When I execute the setup file below using "python setup.py py2exe" it gives me an executable but when I run it, it complains "No module named builtins".
The only other post I could find on this subject indicated that builtins is a python3 thing, but I'm running 2.7.
Appreciate any advice or tips on this.
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import os
import matplotlib
matplotlibdatadir = matplotlib.get_data_path()
matplotlibdata = findall(matplotlibdatadir)
setup(
console=['DET14.py'],
options={
'py2exe': {
'packages' : ['matplotlib', 'pytz'],
'dll_excludes':['MSVCP90.DLL',
'libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll',
'libgdk_pixbuf-2.0-0.dll'],
'includes':['scipy.sparse.csgraph._validation',
'scipy.special._ufuncs_cxx']
}
},
# data_files=matplotlibdata_files
data_files=matplotlib.get_py2exe_datafiles()
)
Here is the full listing of what the error message looks like:
I also found using 'pip install future'
resolved this issue
I got the information from here: https://askubuntu.com/questions/697226/importerror-no-module-named-builtins
I hope this clarifies this for other users, like me who stumbled upon your question
Running pip install future fixed this error for me.
For compatibility with Python2.7, the package future should be added to the install_requires in setup.py.
Note that nosetests also fails without matplotlib, but I'm not sure adding matplotlib as a dependency makes much sense.
Source
I finally got this working. It turned out that I had some errors in the original setup file, some of which were outright dumb, and some simply reflected my lack of understanding of how the parameters of the setup command works. I will add that this latter class of errors was only resolved with some Sherlock Holmes-style sleuthing and plain old trial and error. By that I mean that I have still not found any documentation that calls out the meaning and usage of the parameters of the setup command. If anyone has that info and could pass it along that would be much appreciated.
With that as background, here is the answer:
There were 2 basic problems:
The list of packages in the above setup file was woefully incomplete. I am still not certain that the rule is that you have to list every single package that your program relies upon, and some which it may rely upon that you didn't know about (e.g. pytz). But when I did that, I had something at that point that I could eventually get to work.
The error message in the above original question sort of looks like my program had a dependency on a thing called "patsy". This confused me because I had no idea what that was. It turns out that statsmodels (which is core to my project) has a dependency on patsy, so it needed to be included in the "packages" list.
Below is the setup file that ended up working. I hope this description of the logic behind the fix turns out to be helpful to others facing the same kind of problem.
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import os
import matplotlib
matplotlibdatadir = matplotlib.get_data_path()
matplotlibdata = findall(matplotlibdatadir)
setup(
console=['DET14.py'],
options={
'py2exe': {
'packages' : ['matplotlib', 'pytz','easygui',\
'statsmodels','pandas','patsy'],
'dll_excludes':['MSVCP90.DLL',
'libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll',
'libgdk_pixbuf-2.0-0.dll'],
'includes':['scipy.sparse.csgraph._validation',
'scipy.special._ufuncs_cxx']
}
},
data_files=matplotlib.get_py2exe_datafiles()
)
In case pip install future does not work for you, it's possible that you have a bad copy of the future module hiding somewhere. For me, PyCharm had installed future==0.18 while I wanted future=0.16. sudo pip uninstall future did not work, you could still import future and it would be 0.18. Solution was to find and delete it.
>>> import future
>>> future.__version__
'0.18.0'
>>> future.__file__
'/home/<USERNAME>/.local/lib/python2.7/site-packages/future/__init__.pyc'
rm -rf /home/<USERNAME>/.local/lib/python2.7/site-packages/future
Related
I'm struggling with using one of the python scripts I've written. I know there have been a couple similar questions to this one already, however I have tried pretty much everything I could find, and nothing works...
When I try to run a test program I get met with
ModuleNotFoundError: No module named 'v6-average-py'
I'll explain better throughout this post.
My file structure is this:
mean_package
|-README.md
|-setup.py
|-algorithm_pkg
|-__init__.py
Setup.py:
from os import path
from codecs import open
from setuptools import setup, find_packages
setup(
name='v6-average-py',
version="1.0.0",
description='v6 average',
long_description="description",
long_description_content_type='text/markdown',
url='https://github.com/IKNL/v6-average-py',
packages=find_packages(),
python_requires='>=3.6',
install_requires=[
'vantage6-client',
]
)
init.py is just two defined methods.
Then I run
pip install -e .
Which gives a bunch of requirement statisfied and
Running setup.py develop for v6-average-py
Successfully installed v6-average-py-1.0.0
And finally when it try to run a program I called testscript.py it fails at the first part with
client = ClientMockProtocol(
datasets=[".\\MOCK_DATA.csv", ".\\MOCK_DATA1.csv"],
module="v6-average-py"
)
It fails at
module="v6-average-py"
because the module can't be found I assume.
From what I have seen from similar questions it's either a problem with using different python versions, which I don't think is the issue here (running everything using pyenv, python 3.7.9 so it's all being run/installed with that).
I have also tried solutions where the problem has been find_packages() or the init.py file with no luck.
Maybe it's being put somewhere it can't be found?
Any input would be greatly appreciated
I am trying to build a standalone app that utilises Pandas. This is my setup.py file:
from setuptools import setup
APP = ['MyApp.py']
DATA_FILES = ['full path to/chromedriver']
PKGS = ['pandas','matplotlib','selenium','xlrd']
OPTIONS = {'packages': PKGS, 'iconfile': 'MyApp_icon.icns'}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app','pandas','matplotlib','selenium','xlrd'],
)
The making of the *.app file goes smoothly, but when I try to run it, it gives me the following error:
...
import pandas._libs.testing as _testing
File "pandas/_libs/testing.pyx", line 1, in init pandas._libs.testing
ModuleNotFoundError: No module named 'cmath'
I tried to include ‘cmath’ in my list of PKGS and in setup_requires in the setup.py file, but when I tried to build the app using py2app it gave me the error:
distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse('cmath')
I am stuck. I couldn't find anything useful online. cmath should be automatically included from what I have been reading. Any ideas on where is the problem and how can I fix it?
I think I have found a solution: downgrade to Python version 3.6.6.
See: python 3.6 module 'cmath' is not found
To uninstall Python I followed this process: https://www.macupdate.com/app/mac/5880/python/uninstall
Then I installed Python 3.6.6: https://www.python.org/downloads/release/python-366/
With Python 3.6.6, Py2App seem to work no problem and includes Pandas smoothly.
It seems that for some reasons cmath is not included in the latest versions of Python? I might be wrong. Please let me know what you think and if you have any questions.
P.S.: I am using MacOS (Mojave 10.14.6) and PyCharm.
I had a similar issue with py2app and cmath. I solved this by adding import cmath into the main script. (MyApp.py in your case) I think doing so may have the modulegraph to add the cmath library files.
I have a packaged project mytools which uses setuptools' setup to store its version in a setup.py project file e.g.
import setuptools
setuptools.setup(
name='mytools',
version='0.1.0'
)
I'd like to get the common mytools.__version__ feature based on the version value e.g.
import mytools
mytools.__version__
>>>'0.1.0'
Is there native / simple way in setuptools to do so? Couldn't find a reference to __version__ in setuptools.
Furthermore, I don't want to store the version in __init__.py because I'd prefer to keep the version in its current place (setup.py).
The many answers to similar questions do not speak to my specific problem, e.g. How can I get the version defined in setup.py (setuptools) in my package?
Adding __version__ to all top-level modules and packages is a recommendation from PEP 396.
Lately I have seen growing concerns raised about this recommendation and its actual usefulness, for example here:
https://gitlab.com/python-devs/importlib_resources/-/issues/100
https://gitlab.com/python-devs/importlib_metadata/-/merge_requests/125
some more that I can't find right now...
With that said...
Such a thing is often solved like the following:
# my_top_level_module/__init__.py
import importlib.metadata
__version__ = importlib.metadata.version('MyProject')
References:
https://docs.python.org/3/library/importlib.metadata.html
https://importlib-metadata.readthedocs.io/en/latest/using.html#distribution-versions
This doesn't make sense to me. How can I use the setup.py to install Cython and then also use the setup.py to compile a library proxy?
import sys, imp, os, glob
from setuptools import setup
from Cython.Build import cythonize # this isn't installed yet
setup(
name='mylib',
version='1.0',
package_dir={'mylib': 'mylib', 'mylib.tests': 'tests'},
packages=['mylib', 'mylib.tests'],
ext_modules = cythonize("mylib_proxy.pyx"), #how can we call cythonize here?
install_requires=['cython'],
test_suite='tests',
)
Later:
python setup.py build
Traceback (most recent call last):
File "setup.py", line 3, in <module>
from Cython.Build import cythonize
ImportError: No module named Cython.Build
It's because cython isn't installed yet.
What's odd is that a great many projects are written this way. A quick github search reveals as much: https://github.com/search?utf8=%E2%9C%93&q=install_requires+cython&type=Code
As I understand it, this is where PEP 518 comes in - also see some clarifications by one of its authors.
The idea is that you add yet another file to your Python project / package: pyproject.toml. It is supposed to contain information on build environment dependencies (among other stuff, long term). pip (or just any other package manager) could look into this file and before running setup.py (or any other build script) install the required build environment. A pyproject.toml could therefore look like this:
[build-system]
requires = ["setuptools", "wheel", "Cython"]
It is a fairly recent development and, as of yet (January 2019), it is not finalized / approved by the Python community, though (limited) support was added to pip in May 2017 / the 10.0 release.
One solution to this is to not make Cython a build requirement, and instead distribute the Cython generated C files with your package. I'm sure there is a simpler example somewhere, but this is what pandas does - it conditionally imports Cython, and if not present can be built from the c files.
https://github.com/pandas-dev/pandas/blob/3ff845b4e81d4dde403c29908f5a9bbfe4a87788/setup.py#L433
Edit: The doc link from #danny has an easier to follow example.
http://docs.cython.org/en/latest/src/reference/compilation.html#distributing-cython-modules
When you use setuptool, you should add cython to setup_requires (and also to install_requires if cython is used by installation), i.e.
# don't import cython, it isn't yet there
from setuptools import setup, Extension
# use Extension, rather than cythonize (it is not yet available)
cy_extension = Extension(name="mylib_proxy", sources=["mylib_proxy.pyx"])
setup(
name='mylib',
...
ext_modules = [cy_extension],
setup_requires=["cython"],
...
)
Cython isn't imported (it is not yet available when setup.pystarts), but setuptools.Extension is used instead of cythonize to add cython-extension to the setup.
It should work now. The reason: setuptools will try to import cython, after setup_requires are fulfilled:
...
try:
# Attempt to use Cython for building extensions, if available
from Cython.Distutils.build_ext import build_ext as _build_ext
# Additionally, assert that the compiler module will load
# also. Ref #1229.
__import__('Cython.Compiler.Main')
except ImportError:
_build_ext = _du_build_ext
...
It becomes more complicated, if your Cython-extension uses numpy, but also this is possible - see this SO post.
It doesn't make sense in general. It is, as you suspect, an attempt to use something that (possibly) has yet to be installed. If tested on a system that already has the dependency installed, you might not notice this defect. But run it on a system where your dependency is absent, and you will certainly notice.
There is another setup() keyword argument, setup_requires, that can appear to be parallel in form and use to install_requires, but this is an illusion. Whereas install_requires triggers a lovely ballet of automatic installation in environments that lack the dependencies it names, setup_requires is more documentation than automation. It won't auto-install, and certainly not magically jump back in time to auto-install modules that have already been called for in import statements.
There's more on this at the setuptools docs, but the quick answer is that you're right to be confused by a module that is trying to auto-install its own setup pre-requisites.
For a practical workaround, try installing cython separately, and then run this setup. While it won't fix the metaphysical illusions of this setup script, it will resolve the requirements and let you move on.
I am attempting to compile an executable for my python script using cxFreeze. Out of the many libraries which I need to import for my script, two seem to fail with cxFreeze. In particular, consider the following test.py script:
print('matplotlib.pyplot')
import matplotlib.pyplot
compiling this with cxFreeze and running gives the following output:
separately, the following test.py script:
print('BeautifulSoup from bs4')
from bs4 import BeautifulSoup
after being compiled with cxFreeze, produces the following output:
My setup.py file for cxFreeze looks as follows:
import sys
from cx_Freeze import setup, Executable
setup(
name = "myname",
version = "1.0",
description = "some description",
executables = [Executable("test.py", base = None)]
)
I am running Python 3.3 x86, and am using a 32 bit version of cxFreeze (most recent) on Windows 7.
I am having trouble chasing down this issue. For one, the directory "C:\Python\32-bit..." doesn't exist on my computer, so I am unclear as to why cxFreeze is trying to look there. Does anyone have any idea how to approach this, or perhaps has already dealt with this issue?
After some digging around, I was able to resolve the issue. For those who may be encountering the same issue, this is what solved it for me:
For the issue with matplotlib: I simply needed to explicitly specify to cxFreeze to include matplotlib.backends.backend_tkagg. My setup file ended up looking like this:
import sys
from cx_Freeze import setup, Executable
packages = ['matplotlib.backends.backend_tkagg']
setup(
name = "myname",
version = "1.0",
description = "some description",
options = {'build_exe': {'packages':packages}},
executables = [Executable("test.py", base = None)]
)
As for the BeautifulSoup issue: There are a couple of posts around the web that have dealt with this issue: cx_freeze sre_constants.error nothing to repeat, https://bitbucket.org/anthony_tuininga/cx_freeze/issue/59/sre_constantserror-nothing-to-repeat.
The relevant conclusion: something is wrong with the 4.3.2 build of cxFreeze that causes this issue. I simply used cxFreeze 4.3.1 to build my app and the problem was solved. It may also be possible to rebuild 4.3.2 locally and have the issue be resolved, but I did not attempt this solution.