Getting 'tuple' object has no attribute 'split' when using py2exe - python

I am using Py2exe to create a executable app for my GUI and this is my setup code:
import matplotlib
from distutils.core import setup
import FileDialog
import zmq.libzmq
import py2exe
setup(
data_files=[matplotlib.get_py2exe_datafiles(),(zmq.libzmq.__file__,)],
console = [{'script': 'SVS-virtual-lib2.py'}],
options={
'py2exe': {
'packages': ['FileDialog'],
'includes': ['zmq.backend.cython'],
'excludes': ['zmq.libzmq'],
'dll_excludes': ['libzmq.pyd']
}
}
)
But i get the following error:
File "C:\Users\nzarinabad\AppData\Local\Continuum\Anaconda\lib\distutils\util.py", line 128, in convert_path
paths = string.split(pathname, '/')
File "C:\Users\nzarinabad\AppData\Local\Continuum\Anaconda\lib\string.py", line 294, in split
return s.split(sep, maxsplit)
AttributeError: 'tuple' object has no attribute 'split
Dose anyone who why i get the error and how to fix it?
Thank you

Please see the documentation, if you want to combine matplotlib.get_py2exe_datafiles() with other files, you have to do some manual work:
from distutils.core import setup
import py2exe
from distutils.filelist import findall
import os
import matplotlib
matplotlibdatadir = matplotlib.get_data_path()
matplotlibdata = findall(matplotlibdatadir)
matplotlibdata_files = []
for f in matplotlibdata:
dirname = os.path.join('matplotlibdata', f[len(matplotlibdatadir)+1:])
matplotlibdata_files.append((os.path.split(dirname)[0], [f]))
matplotlibdata_files.append(zmq.libzmq.__file__)
# ...
setup(
data_files=matplotlibdata_files,
# rest of your code

Related

Display git commit hash in frozen Python script (Cx_Freeze)

I'm having a python project and use git as version control software.
The software will be deployed using Cx_Freeze.
I would like to display the version and author (and possibly other metadata) captured during the build process (freezing the script) within an About dialogue in my Application.
This is an example of the setup script:
import sys
import subprocess
from cx_Freeze import setup, Executable
build_exe_options = {}
base = "Win32GUI"
version = subprocess.run(['git', 'describe', '--abbrev=4', '--dirty', '--always', '--tags'],
capture_output=True, encoding='utf-8').stdout.strip()
setup(
name="XY",
version=version,
author="My Name",
description="Mysterious GUI application",
options={"build_exe": build_exe_options},
executables=[Executable("XY.py", base=base)],
)
Simple example of an About dialogue:
from tkinter import messagebox
def on_about():
messagebox.showinfo(f'About', 'Software XY, written by {author}, version {version}')
# Should display e.g. 'Software XY, written by My Name, version 4b06-dirty'
Does anyone know if this is possible and how to achieve this?
Thanks to all in advance!
I came up with a first solution where I create a sub-module within the main package of my application when the setup script is being executed. I import the __version__ variable into the __init__.py of that package only when its frozen and if the sub-module exists:
setup.py:
import subprocess
import os.path
import mymodule
from cx_Freeze import setup, Executable
def create_versionmodule(packagepath: str):
"""
creates a file packagepath/_version.py which defines a __version__ variable
which contains the stripped output of "git describe --dirty --always --tags"
"""
version = subprocess.run(['git', 'describe', '--dirty', '--always', '--tags'],
capture_output=True, encoding='utf-8').stdout.strip()
with open(os.path.join(packagepath, '_version.py'), mode='w', encoding='utf-8') as file:
file.write(f'__version__: str = {version!r}\n')
build_exe_options = {}
base = "Win32GUI"
create_versionmodule(packagepath=os.path.dirname(mymodule.__file__))
setup(
name="XY",
description="Mysterious GUI application",
options={"build_exe": build_exe_options},
executables=[Executable("XY.py", base=base)],
)
mymodule/__init__.py:
import sys as _sys
__version__ = 'UNKNOWN'
if getattr(_sys, "frozen", False):
try:
from mymodule._version import __version__
except ModuleNotFoundError:
pass
Now I can access the version variable from everywhere in my code:
import mymodule
from tkinter import messagebox
def on_about():
messagebox.showinfo(f'About', 'Software XY, version {mymodule.__version__}')

Problem when using cx_Freeze: "cannot import name 'tf2'"

I have a code in python and I used cx_Freeze to convert it to an .exe. This task works without any error.
But when I try to run my .exe the following error happens:
from tensorflow.python import tf2
ImportError: cannot import name 'tf2'
My ann.py code is:
import numpy as np
import sys
.
.
.
X_test=XinN
Y_test=XoutN
#Criando o modelo
from keras.models import Sequential
from keras.layers import Dense
modelo = Sequential()
for i in range(int((num_par-4)/2)):
modelo.add(Dense(int(parametros[i+4]), kernel_initializer='normal',activation=ativacao(int(parametros[i+5])))) #camadas ocultas
modelo.add(Dense(num_out, kernel_initializer='normal',activation=ativacao(int(parametros[num_par-1])))) #camada de saĆ­da
modelo.compile(optimizer='adam',loss='mean_squared_error')
hist = modelo.fit(X_train, Y_train, epochs=800, verbose=0, batch_size=10,validation_data=(X_test, Y_test))
XobsoutN=modelo.predict(XobsN)
Xobsout=XobsoutN*(max_out-min_out)+min_out
np.savetxt("Xobsout.txt",Xobsout.transpose(),delimiter='\t')
loss=[" "," "]
loss[0] = hist.history['loss']
loss[1] = hist.history['val_loss']
np.savetxt("erro.txt",loss,delimiter='\t')
And my setyp.py for cx_Freeze is:
from cx_Freeze import setup, Executable
import sys
base = None
if sys.platform == 'win32':
base = None
executables = [Executable("ANN.py", base=base)]
packages = ["idna"]
options = {
'build_exe': {
'includes':['atexit', 'numpy.core._methods', 'numpy.lib.format'],
'packages':packages,
},
}
import os
os.environ['TCL_LIBRARY'] = "C:\\ProgramData\\Anaconda3\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = "C:\\ProgramData\\Anaconda3\\tcl\\tk8.6"
setup(
name = "Nome Executavel",
options = options,
version = "1.0",
description = 'Descricao do seu arquivo',
executables = executables
)
Anyone can help me to solve this error?
I had many others errors using cx_Freeze and this forum was pretty helpful to solve all of them. Thanks a lot!
Try to add "tensorflow" to the packages list in your setup.py script:
packages = ["idna", "tensorflow"]

py2exe generate custom Icon

So this is a question that has been asked many times. And I followed all the things found on the interwebs, however. My icon just isn't appearing, and I'm not getting any sort of error message. The rest of my program functions fine, it's just the darn ugly icon.
Here's my setup.py file, please let me know if/what I'm doing wrong? Sorry if there is a dumb error. :(
import os, os.path, sys
import subprocess
from distutils.core import setup
import py2exe
import glob
import numpy
sys.argv.append('py2exe')
target = {
'script' : "MY_PROGRAM.py",
'version' : "1.0",
'company_name' : "MY_COMPANY",
'copyright' : "",
'name' : "PROGRAM_NAME",
'dest_base' : "PROGRAM_NAME",
'icon_resources': [(1, "MY_ICON.ico")]
}
opts = {
'py2exe': { 'includes': ['matplotlib.numerix.random_array', 'dbhash',
'anydbm', 'skimage', 'pymorph', 'register'],
'excludes': ['_gtkagg', '_tkagg'],
'dll_excludes': ['libgdk-win32-2.0-0.dll',
'libgobject-2.0-0.dll'],
'bundle_files': 1
}
}
setup(
data_files = [('Images', glob.glob('Images/*.*'))],
windows = [target],
zipfile = None
)
....
For some reason it works now. I used a different website to convert my png file to a .ico, and voila magic.
:( so much struggles

pymssql throws ImportError: No module named _mssql when build app with py2exe

I have python application that shoud be launched as windows executable. I'm using py2exe and pymssql 1.9.908.
I used next build script to generate application:
from distutils.core import setup
import MySQLdb
import fnmatch
import os
import pymssql
import shutil
import py2exe
import glob
##############
name = 'BGAgent'
old_version = '0.1'
ver = '0.1'
distDir = 'Dist' + name + ver
shutil.rmtree(distDir, True)
shutil.rmtree('Dist' + name + old_version, True)
os.mkdir(distDir)
##############
class Target(object):
""" A simple class that holds information on our executable file. """
def __init__(self, **kw):
""" Default class constructor. Update as you need. """
self.__dict__.update(kw)
# MySQLdb
#dst = os.path.join(distDir, "MySQLdb")
#copy_tree(MySQLdb.__path__[0], dst )
# pymssql
site_packages_dir = os.path.dirname(pymssql.__file__)
pymssql_files = []#'pymssql.py', 'pymssql.pyc', 'pymssql.pyo', '_mssql.pyd']
for eggInfo in glob.glob(os.path.join(site_packages_dir, '*mssql*')) :
pymssql_files.append(os.path.basename(eggInfo))
for fname in pymssql_files :
src = os.path.join(site_packages_dir, fname)
dst = os.path.join(distDir, fname)
if(os.path.isfile(src)) :
shutil.copy(src, dst)
else :
shutil.copytree(src, dst)
includes = ['MySQLdb', 'pymssql', 'OpenSSL']
excludes = ['run_w.exe'] #['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger', 'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl', 'Tkconstants', 'Tkinter']
packages = ['MySQLdb', 'pymssql', 'OpenSSL']
dll_excludes = []#['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll', 'tk84.dll']
data_files = ['server.pem',
'config.ini',
'run.bat',
#os.path.join(os.path.split(pymssql.__file__)[0], 'ntwdblib.dll'),
]
icon_resources = []
bitmap_resources = []
other_resources = []
MyApp_Target = Target(
# what to build
script = "run.py",
icon_resources = icon_resources,
bitmap_resources = bitmap_resources,
other_resources = other_resources,
dest_base = name,
version = ver,
company_name = "",
copyright = "",
name = name,
)
setup(
data_files = data_files,
options = {"py2exe": {"compressed": 0,
"optimize": 1,
"includes": includes,
"excludes": excludes,
"packages": packages,
"dll_excludes": dll_excludes,
"bundle_files": 3,
"dist_dir": distDir,
"xref": False,
"skip_archive": False,
"ascii": False,
"custom_boot_script": '',
}
},
zipfile = r'library.zip',
console = [],
windows = [MyApp_Target],
service = [],
com_server = [],
ctypes_com_server = []
)
Build works, but I have error when I tried to launch application:
File "pymssql.pyo", line 12, in <module>
File "pymssql.pyo", line 10, in __load
File "_mssql.pxd", line 10, in init pymssql (pymssql.c:7370)
ImportError: No module named _mssql
_mssql.pyd and pymssql.pyd files are in executable directory.
OS version Windows 7 Enterprice SP 1.
In the program you are trying to import (eg. in the A.py for A.exe ), specify import statement for _mssql as well. You might also need to import a couple of other modules (decimal & uuid )to get the exe working
Just add the statement import _mssql in your file. Next, run your program. When you get the same thing, just import that module in your code. This method works well for me.
from distutils.core import setup
import py2exe, os, pymssql
import decimal
data_files = []
data_files.append(os.path.join(os.path.split(pymssql.__file__)[0], 'ntwdblib.dll'))
py2exe_options = {"py2exe":{"includes": ['decimal'],
"dll_excludes":["mswsock.dll",
"powrprof.dll",
"user32.dll",
"shell32.dll",
"wsock32.dll",
"advapi32.dll",
"kernel32.dll",
"ntwdblib.dll",
"ws2_32.dll",
"oleaut32.dll",
"ole32.dll",
],
}}
setup(console=["jobs_pcc_main.py"], options= py2exe_options, data_files=data_files)
To whom might help
I got lots of issues trying to user pymssql with Pyinstaller and
I finally got it right so posting here might help someone
after you install pymssql using pip install pymssql
use this parameters in pyinstaller to get it included
--onefile --paths=.\venv\ --hidden-import='pymssql' --hidden-import='uuid' --collect-all='pymssql' --collect-all='uuid'

exe generated with py2exe can't find pywinauto

I've been trying to pack my app with py2exe. The application works fine but it keeps failing to find/use pywinauto. I been googling but I get nothing, I'm now I'm totally lost...
Here's the packing script:
from distutils.core import setup
setup(
windows = ["mainForm.py"],
data_files=[
('', ['mainForm.ui']),
('', ['osk.sqlite'])
],
options = {
"py2exe":{
"optimize": 2,
"includes": [
'sip', 'pyttsx.drivers.sapi5', 'win32com', 'xml.etree.ElementTree', 'sqlite3',
'pywinauto', 'pywinauto.application', 'pywinauto.controls', 'pywinauto.tests', 'SendKeys'
],
"typelibs": [('{C866CA3A-32F7-11D2-9602-00C04F8EE628}', 0, 5, 0)]
}
}
)
And here's the ouput when running the exe
Traceback (most recent call last):
File "mainForm.py", line 129, in changeState
File "mainForm.py", line 230, in setWriteMode
File "mainForm.py", line 105, in FillApps
File "WindowHandler.pyo", line 26, in getWindowList
NameError: global name 'pywinauto' is not defined
I hope anyone could point me into the right direct.
Thanks in advance
From my experience, py2exe handles imports in a weird way. Sometimes it has trouble finding linked-imports (like you import WindowHandler, which imports pywinauto).
I would start with this in mainForm.py:
import sys
import WordOps
import Voice
import WindowHandler
from PyQt import QtCore, QtGui, uic
And in setup.py, start with this:
options={'py2exe':{
'includes': ['sip'],
'bundle_files': 1
}
}
Make sure your program works before compiling to an exe, then try running setup.py.
When you start getting errors when running setup.py (like the one you posted), add more imports to mainForm.py. So for that error, your new header will look like:
import sys
import WordOps
import Voice
import WindowHandler
from PyQt import QtCore, QtGui, uic
# imports for py2exe
import pywinauto
It will not break your code because it will just be an "unused" import.
Keep doing that until setup.py works.

Categories