I use CX_Freeze to freeze one of my python programs. The build system works fine in windows. I can create a directory with executable and necessary dependencies that will run in any windows system.
When I try the same in Linux, the building part
python setup.py
works fine. But when I try to run the built executable, its gives the following error.
File "/usr/local/lib/python2.7/dist-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
exec code in m.__dict__
File "test.py", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/guidata/__init__.py", line 540, in <module>
import guidata.config
File "/usr/local/lib/python2.7/dist-packages/guidata/config.py", line 19, in <module>
add_image_module_path("guidata", "images")
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 100, in add_image_module_path
add_image_path(get_module_data_path(modname, relpath=relpath), subfolders)
File "/usr/local/lib/python2.7/dist-packages/guidata/configtools.py", line 86, in add_image_path
for fileobj in os.listdir(path):
OSError: [Errno 20] Not a directory: '/home/user/tmp/dist/library.zip/guidata/images'
It seems that guidata is trying to find images under non-existing library.zip/guidata/images directory. I made sure that I run same versions of guidata, cx_Freeze on both windows and linux. Any help to resolve the issue is appreciated.
Minimal example
import guidata
_app = guidata.qapplication() # not required if a QApplication has already been created
import guidata.dataset.datatypes as dt
import guidata.dataset.dataitems as di
class Processing(dt.DataSet):
"""Example"""
a = di.FloatItem("Parameter #1", default=2.3)
b = di.IntItem("Parameter #2", min=0, max=10, default=5)
type = di.ChoiceItem("Processing algorithm",
("type 1", "type 2", "type 3"))
param = Processing()
param.edit()
setup file
import sys
import os
"""Create a stand-alone executable"""
try:
import guidata
from guidata.disthelpers import Distribution
except ImportError:
raise ImportError, "This script requires guidata 1.4+"
def create_executable():
"""Build executable using ``guidata.disthelpers``"""
dist = Distribution()
dist.setup(name='Foo', version='0.1',
description='bar',
script="test.py", target_name='test.exe')
dist.add_modules('guidata', 'guiqwt')
# Building executable
dist.build('cx_Freeze')
if __name__ == '__main__':
create_executable()
OK. Here's the answer to my own question. After much digging up, I realized that it is a bug in guidata and/or python's os.path module. What happens is this. On guidata module, in configtools.py file, there is a function get_module_data_path, that checks whether the parent 'directory' of a path like /foo/bar/library.zip/yap to be a file.
import os.path as osp
...
...
datapath = get_module_path(modname)
parentdir = osp.join(datapath, osp.pardir)
if osp.isfile(parentdir):
# Parent directory is not a directory but the 'library.zip' file:
# this is either a py2exe or a cx_Freeze distribution
datapath = ...
Now the test
osp.isfile("/foo/bar/library.zip/yap/..")
returns True in windows but False in Linux. This breaks the code. Python documentation is unclear in stating whether this is a bug or the intended behavior.
At the moment I don't have a solution, but a hack. I changed the above code as:
import os.path as osp
...
...
datapath = get_module_path(modname)
parentdir = osp.join(datapath, osp.pardir)
parentdir2 = osp.split(datapath.rstrip(os.path.sep))[0]
if osp.isfile(parentdir) or osp.isfile(parentdir2):
# Parent directory is not a directory but the 'library.zip' file:
# this is either a py2exe or a cx_Freeze distribution
datapath = ...
and everything is fine.
Related
I'm creating a new testing frameworks, I started to implement my own functions in *.py files, but when I try to run test, I've got following stack:
(venv) PLAMWS0024:OAT user$ robot -v CONFIG_FILE:"/variables-config.robot" ./catalog/tests/test1.robot
Traceback (most recent call last):
File "/Users/user/PycharmProjects/OAT/venv/bin/robot", line 5, in <module>
from robot.run import run_cli
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/__init__.py", line 44, in <module>
from robot.rebot import rebot, rebot_cli
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/rebot.py", line 45, in <module>
from robot.run import RobotFramework
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/run.py", line 44, in <module>
from robot.running.builder import TestSuiteBuilder
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/running/__init__.py", line 98, in <module>
from .builder import TestSuiteBuilder, ResourceFileBuilder
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/running/builder/__init__.py", line 16, in <module>
from .builders import TestSuiteBuilder, ResourceFileBuilder
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/running/builder/builders.py", line 20, in <module>
from robot.parsing import SuiteStructureBuilder, SuiteStructureVisitor
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/parsing/__init__.py", line 380, in <module>
from .model import ModelTransformer, ModelVisitor
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/parsing/model/__init__.py", line 18, in <module>
from .statements import Statement
File "/Users/user/PycharmProjects/OAT/venv/lib/python3.8/site-packages/robot/parsing/model/statements.py", line 453, in <module>
class Error(Statement, Exception):
TypeError: multiple bases have instance lay-out conflict
I suspect it's because in one of my files I'm trying to get variables from Robot Framework built in functionalities.
and I'm thinking it's because I'm trying to use protected methods, but I am not sure.
I found issue TypeError: multiple bases have instance lay-out conflict and it shows that there might be a mismatch in naming convention (or am I wrong?), but my project is a bit small, so the only option is that Robot can't see the function itself.
What can I miss?
Some code:
Test itself:
*** Settings ***
Documentation TO BE CHANGED
... SET IT TO CORRECT DESCRIPTION
Library ${EXECDIR}/file.py
Library String
*** Test Cases ***
User can do stuff
foo bar
from datetime import datetime
from robot.api import logger
from robot.libraries.BuiltIn import _Variables
from robot.parsing.model.statements import Error
import json
import datetime
from catalog.resources.utils.clipboardContext import get_value_from_clipboard
Vars = _Variables()
def foo_bar(params):
# Get all variables
country = get_value_from_clipboard('${COUNTRY}')
address = get_value_from_clipboard('${ADDRESS}')
city = get_value_from_clipboard('${CITY}')
postcode = get_value_from_clipboard('${POSTALCODE}')
And calling Vars:
from robot.libraries.BuiltIn import _Variables
from robot.parsing.model.statements import Error
Vars = _Variables()
def get_value_from_clipboard(name):
"""
Returns value saved inside variables passed in Robot Framework
:param name: name of the variable, needs to have ${} part
as example: ${var} passed in config file
:return: value itself, passed as string
"""
try:
return Vars.get_variable_value(name)
except Error as e:
raise Error('Missing parameter in the clipboard, stack:' + str(e))
What fixed issue:
uninstall all requirements from requirements.txt file and install all one-by-one.
Additional steps I tried:
comment out all files one-by-one and run only robot command - failed, got same errors
cleaned vnenv as described here: How to reset virtualenv and pip? (failed)
check out if any variable has same naming as described in python3.8/site-packages/robot/parsing/model/statements.py - none
So looks like there was some clash in installing requirements by PyCharm IDE
Recently, I tried using the python Excel functions on Windows with the win32com.client library. I installed it with :
pip install pywin32
I used it on my script, with simple commands like :
import os
import win32com.client as win32
ExcelApp = win32.gencache.EnsureDispatch("Excel.Application")
ExcelWrkBook = ExcelApp.ActiveWorkbook
ExcelWrkSht = ExcelWrkBook.ActiveSheet
ExcelWrkSht.Cells(5,3).Value = "something"
So it all worked just fine , till I got an Error like this out of nowhere :
Traceback (most recent call last):
File "myscript.py", line 2, in
import win32com.client as win32
File "C:\Users\Mycomputer\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wi
n32com\client__init__.py", line 11, in
from . import gencache
File "C:\Users\Mycomputer\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wi
n32com\client\gencache.py", line 660, in
init()
File "C:\Users\Mycomputer\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wi
n32com\client\gencache.py", line 60, in init
_LoadDicts()
File "C:\Users\Mycomputer\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wi
n32com\client\gencache.py", line 113, in _LoadDicts
version = p.load()
EOFError: Ran out of input
this pops up whenever I import win32com.client as win32, I tried reinstalling the library but it is still the same , Any idea ?
It was a problem (client/ COM Server) communication, Solved by clearing the cache.
You can do it by deleting the gen_py folder "%userprofile%\AppData\Local\Temp\gen_py"
After debug the error was from GenCache. I am not that well informed with regards to these libraries but I found this interesting thread and replaced the gencache with Dispatch, so the Program changed to :
import os
import win32com.client as win32
ExcelApp = win32.Dispatch("Excel.Application")
ExcelWrkBook = ExcelApp.ActiveWorkbook
ExcelWrkSht = ExcelWrkBook.ActiveSheet
ExcelWrkSht.Cells(5,3).Value = "something"
I am trying to compile an executable from a python script that uses pysftp. I'm using cx_Freeze to do that.
Here is my code:
Test.py
import datetime
import time
import os
import pysftp
i = 0
while(i<10):
tm = datetime.datetime.now()
print (tm.strftime('%H:%M:%S'))
time.sleep(1)
i += 1
Here is the setup:
setup.py
from cx_Freeze import setup, Executable
base = None
executables = [Executable("Test.py", base=base)]
packages = ["idna", "datetime", "time", "os", "pysftp"]
options = {
'build_exe': {
'packages':packages,
},
}
setup(
name = "<any name>",
options = options,
version = "<any number>",
description = '<any description>',
executables = executables
)
When I run test.py from the command line, it works fine. But when I run the exe that is built after running the command python setup.py build, test.exe fails and displays this:
C:\Users\cb\Desktop\Python Scripts\Test cx_Freeze install\build\exe.win-amd64-3.7>Test.exe
Traceback (most recent call last):
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\cx_Freeze\initscripts\__startup__.py", line 14, in run
module.run()
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\cx_Freeze\initscripts\Console.py", line 23, in run
exec(code, {'__name__': '__main__'})
File "Test.py", line 4, in <module>
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\pysftp\__init__.py", line 12, in <module>
import paramiko
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\paramiko\__init__.py", line 22, in <module>
from paramiko.transport import SecurityOptions, Transport
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\paramiko\transport.py", line 90, in <module>
from paramiko.ed25519key import Ed25519Key
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\paramiko\ed25519key.py", line 17, in <module>
import bcrypt
File "C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages\bcrypt\__init__.py", line 25, in <module>
from . import _bcrypt
ModuleNotFoundError: No module named '_cffi_backend'
Any suggestions on what I should try?
I have already tried adding "cryptography" and "paramiko" to the packages list. I've looked online and found that I may have to explicitly state the lib I am using for cx_Freeze, but I am not sure what that is.
I'm using python 3.7.3-64bit and windows 10.
Try to add "paramiko" and "bcrypt" to the packages list in your setup.py script. If this still does not work, please post the new traceback you should get.
EDIT: this does not solve the problem according to the OP.
Search for a file named _cffi_backend*.* in your C:\Users\cb\AppData\Local\Programs\Python\Python37\lib\site-packages, do you find anything?
EDIT: according to OP's answer, there is file [Python version]\Lib\site-packages\_cffi_backend.cp37-win_amd64.pyd, and copying this file manually to the lib directory next to the built executable solves the issue.
You should be able to let cx_Freeze do this additional step automatically by modifying your setup.py script like this:
import _cffi_backend
_cffi_backend_file = _cffi_backend.__file__
include_files = [(_cffi_backend_file, 'lib')]
options = {
'build_exe': {
'include_files': include_files,
'packages': packages,
},
}
2nd EDIT:
Instead of the above proposals, try to simply add _cffi_backend to the includes list of the build_exe options in your setup.py script:
includes = ['_cffi_backend']
options = {
'build_exe': {
'includes': includes,
'packages': packages,
},
}
Thank you to jpeg for providing the great suggestions that led to help fixing this issue. What I had to do was to copy _cffi_backend.cp37-win_amd64.pyd to the lib directory next to the built executable.
You can find this file under your python install ([Python version]\Lib\site-packages\_cffi_backend.cp37-win_amd64.pyd)
I have a few python scripts that I have been able to convert to .exe relatively easily with cx_Freeze but I have hit a bump with a rubixcube I am creating with opengl.
I have two scripts;
import sys
from cx_Freeze import setup, Executable
#go to dir in cmd, run python setup.py build or; setup.py build... will create a folder build with name.exe
setup(
name = "Cube",
version = "1.1",
description = "Cube",
executables = [Executable("OwnCube.py", base = "Console")])
OwnCube.py is simply;
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
It then saves a build folder under 'Cube' with a .exe file called 'OwnCube.exe' along with all the dll's and data files. Running OwnCube.exe in cmd gives a nonetype error.
G:\Programs\PersonalPrograms\PythonScripts\Cube\build\exe.win32-3.6>OwnCube.exe
Traceback (most recent call last):
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\cx_Freeze\initscripts\__startup__.py", line 14, in run
module.run()
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\cx_Freeze\initscripts\Console.py", line 26, in run
exec(code, m.__dict__)
File "OwnCube.py", line 5, in <module>
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\OpenGL\GL\__init__.py", line 3, in <module>
from OpenGL import error as _error
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\OpenGL\error.py", line 12, in <module>
from OpenGL import platform, _configflags
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\OpenGL\platform\__init__.py", line 35, in <module>
_load()
File "C:\Users\Alex\AppData\Local\Programs\Python\Python36-32\lib\site-packages\OpenGL\platform\__init__.py", line 29, in _load
plugin = plugin_class()
TypeError: 'NoneType' object is not callable
I have done this multiple times with other libraries but I can't seem to get this working with OpenGl, am I missing something?
i meet this problem too, and all i have done to solve this is add OpenGL.platform.win32 in includes of setup.py. i use win10.
reason of this bug is :
def load( self ):
"""Attempt to load and return our entry point"""
try:
return **importByName**( self.import_path )
except ImportError as err:
return None
def importByName( fullName ):
"""Import a class by name"""
name = fullName.split(".")
moduleName = name[:-1]
className = name[-1]
module = __import__( ".".join(moduleName), {}, {}, moduleName)
return getattr( module, className )`
cx_freeze can not catch __import__ in your code, so we need to use import instead of __import__.
After much hair pulling.
Turns out I needed to include an options line in setup to include the OpenGL Library. Then I had to either set the environment variable to the TCL_LIBRARY and TK_LIBRARY or manually. I did this in the script as follows:
import sys
import os
from cx_Freeze import setup, Executable
build_exe_options = {"includes": ["OpenGL"]}
os.environ['TCL_LIBRARY'] = r'G:\python path\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'G:\python path\tcl\tcl8.6'
#go to dir in cmd, run python setup.py build or; setup.py build... will create a folder build with name.exe
setup(
name = "Cube",
version = "1.1",
description = "Cube",
options = {"build_exe": {"packages": ["OpenGL"]}},
executables = [Executable("OwnCube.py", base = "Console")]
)
I don't really understand why this happened, My guess would be that when compiling the OpenGL librarys to .dll or .so files it couldn't find the library tkinter or tcl that OpenGL was calling internally.
Hope this helps future searchers.
I have an app built in Gtk3 Python3.4(Windows) which works fine on Pycharm but when I create an exe using cx_freeze , It gives the following error -
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\cx_Freeze\initscripts\Console.py", line 27, in <module>
exec(code, m.__dict__)
File "obfuscated.py", line 2, in <module>
File "C:\Python34\lib\site-packages\gi\__init__.py", line 118, in require_version
raise ValueError('Namespace %s not available' % namespace)
ValueError: Namespace Gtk not available
The imports I've done in my app are -
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, Gio, GObject
import sqlite3
My setup.py file -
from cx_Freeze import setup, Executable
#import os
#os.environ['TCL_LIBRARY'] = "C:\\Users\\BRAHMDEV\\AppData\\Local\\Programs\\Python\\Python36\\tcl\\tcl8.6"
#os.environ['TK_LIBRARY'] = "C:\\Users\\BRAHMDEV\\AppData\\Local\\Programs\\Python\\Python36\\tcl\\tk8.6"
executables = [
Executable("obfuscated.py",
icon="evm_bg_KYa_icon.ico")
]
buildOptions = {"packages":["sqlite3", "gi"], "include_files":["mydatabase.db", "AgeSearch.png", "android.png", "candidate.jpg",
"CasteSearch.png", "duplicate.png", "FileStyle.css", "GenSearch.png", "Hof.png", "Placeholder.png", "voter slip.png"]}
setup(name="Voter Search Engine",
version="2.1.3",
description="Voter Search Engine Setup",
options={"build_exe":buildOptions},
executables=executables,
)
And when I executed python setup.py build this was what took place -
https://pastebin.com/uutDJ8at
Well , I tried this on Pyinstaller as well got the same error , but found the solution
here