So I'm trying to compile a python script named "File.py" using this code:
from cx_Freeze import setup, Executable
# Define packages needed(not builtin)
packages = ['scipy' , 'numpy']
options = {
'build_exe': {
'packages': packages,
},
}
setup(name='Monitor',
version = '0.8',
description = 'Monitors stuff.',
options = options,
executables = [Executable("File.py")])
"File.py" only uses scipy and numpy, which I have included in the packages variable. However, after compiling and running File.exe, I get the error: "ModuleNotFoundError: No module named 'scipy.spatial.ckdtree'". I am using python 3.6 and cx_Freeze 6 (which supports python 3.6). How can I get cx_Freeze to include all of the necessary modules?
Try giving the actual address of the library. So find where the scipy and numpy files are and in the packages, include something like this: r"C:\Users\yourname\AppData\Local\Programs\Python\Python36\DLLs\tcl86t.dll",
r"C:\Users\yourname\AppData\Local\Programs\Python\Python36\DLLs\tk86t.dll",
Probably dead, but I'll put in my two cents having encountered a couple issues like this with scipy over the years in combination with cx_Freeze. I had trouble finding documentation of this issue on SO.
First, when you run File.exe, check the full stack trace in the dialog box when you get the error. ModuleNotFoundError is your symptom, but root cause is in which file is attempting to load the module, usually an __init__.py file somewhere in scipy.
Second, go to that file and compare the module name being loaded against the package name and aliases. You are looking for discrepancies in the case of the module name or path to the module. For example, one ckdtree load issue I have come across was __init__.py was attempting to load 'ckdtree', but the module in the distribution was 'cKDTree' or had a capital letter where there wasn't supposed to be one. Changing the case in the file attempting to load the module fixes the issue.
Related
I'm currently trying to create an executable for my application with Pyinstaller.
I already could fix some general import errors by including the respective libraries in the hiddenimports section in my .spec file.
However I'm now getting the following error when executing my .exe:
ImportError: attempted relative import with no known parent package
Looking at the Traceback it seems like my used package (sklearn) is using relative imports.
Reading through similar questions, I only found solutions for this problem in case relative imports are needed in the own package. But how to solve the problem when it occurs in a package which I'm not able to adapt?
I tried to add sklearn and the respective subpackages (e.g.sklearn.utils.fixes) explicitely in hiddenimports but this didn't work.
I created a game using pygame (python2.7) and tried to convert it using py2exe.
These are the modules I used:
pygame,Tkinter,random
here's my "setup.py":
from distutils.core import setup
import py2exe
setup(options={
"py2exe":{
"includes": ["Tkinter","pygame","random"]
}
}
)
when I try to run the .exe file I get this Error:
NotImplementedError: font module not avaible
(ImportError: DLL load failed: module couldn't be found
What do I have to change?
There's two things to check here. First, ensure that you are using 32-bit python and 32-bit pygame. Pygame only plays nice with 32-bit python, and you're opening a can of worms if you ignore that. The other thing to check is to make sure that all the modules are spelt the way that they are spelt on your system when you load in the dlls. (A common suspect is that Tkinter has an upper case module name and this might throw something off)
I am trying to follow the tutorial for creating python packages from shared objects compiled from C++ via boost::python, but I am running into some problems I need clarification about.
Assume I have a local $install_dir into which I install the compiled shared objects in the form of a python package via CMake. Parallel to the tutorial liked above, my structure is:
$installdir/
my_package/
__init__.py
module/
__init__.py
_module.so
I have added $installdir to my $PYTHONPATH.
$installdir/my_package/__init__.py is empty.
$installdir/my_package/module/__init__.py contains:
from _module import *
When I then import my_package.module I get ModuleNotFoundError: No module named '_module' raised from $installdir/my_package/module/__init__.py.
The issue seems to be that _module.so is not found from $installdir/my_package/module/__init__.py.
Why is the approach from the tutorial not working?
If I add $installdir/my_package/module to $PYTHONPATH directly everything works fine, but it feels like that should not be neccessary, as $installdir/my_package/module/__init__.py should find _module.so locally.
I implemented the following portable workaround for now within $installdir/my_package/module/__init__.py:
import sys, pathlib
sys.path.insert(0,str(pathlib.Path(__file__).parent.absolute()))
from _module import *
Bonus Question:
Changing the file name extension from .so to .pyd breaks the import (ModuleNotFoundError) even without any packaging and .pyd being accessible directly via $PYTHONPATH. I define the extension via CMake's SUFFIX target property. This is obviously mostly cosmetic, but I would still like to understand the reason and how to fix it.
Edit:
This is Ubuntu 20.04 with python 3.8 and boost 1.71
On windows I have built a very simple "hello world" C extension (the file hello.c from this site https://gist.github.com/physacco/2e1b52415f3a964ad2a542a99bebed8f). Using VS2015 I successfully obtain hello.dll. The problem is that I can't figure out how to import this file/module.
In the python shell (python 3.7) I have made sure that I'm in the same folder as the hello.dll. I have also made sure that sys.path() contains the folder path. But when I write "import hello" I get an error "ModuleNotFoundError: No module named 'hello'"
Does anyone has an idea of what is wrong is this very simple setup?
Update:
When trying to import a module that does not exist the ModuleNotFoundError is reported. After renaming the hello.dll to hello.pyd an ImportError is returned. So it seems like it tries to actually load the module.
Python compiled modules on Windows have the extension .pyd, not .dll. If you'd built it using setup.py the file would be built with the correct name. However, you built it yourself and gave it a name that Python doesn't recognise as a module.
In terms of the build command: you have to link it with libpython. You don't look to be doing this. The error you report is definitely one that you can get if the module is not linked against all its dependencies.
I know you don't want to use setup.py, however I'd use it at least once just to see what it does and if it works. You'll then at least have a command that you can copy with a working set of options.
In my IronPython script, I'm using standard libary modules like ConfigParser, logging and JSON.
Then I use pyc.py to create an executable. At first I ran into problems, namely '...ImportException: no module named ...'
since they weren't being included in the exe and accompanying dlls.
So I ran a solution from here: IronPython: EXE compiled using pyc.py cannot import module "os" and it mostly worked.
For example, importing 'ConfigParser' would work since in the IronPython 'Lib' folder as a module, it's there as 'ConfigParser.py'. However I'm still having trouble using JSON and logging since they're inside of folders with their name (packages?).
I'm feeling that I'm just missing something simple, and probably need to read up more on python modules and how they really work, but I'm not sure what I should be looking for.
Any help would be greatly appreciated.
Thanks!
EDIT:
I can't answer my own question yet, so I'll leave this here.
Somehow got it to work in a really 'hacky' way. There must be another much cleaner solution to this that I'm missing (some option in pyc.py?)
Here's what I did:
1) Made the StdLib.dll file generated from the link above (IronPython: EXE compiled using pyc.py cannot import module "os"). This would be missing the std lib packages.
2) Used SharpDevelop to compile the standard lib packages that weren't included in the above dll following the method here: http://community.sharpdevelop.net/blogs/mattward/archive/2010/03/16/CompilingPythonPackagesWithIronPython.aspx
3) Used SharpDevelop to build my program and tie together all the references.
- Reference to the dlls made in step 2
- Reference to the StdLib.dll made in step 1
Again, there must be a better solution to this.
I've found two ways to compile standard library python packages:
1st way: Individually compile each package into a dll
Using pyc.py, run something like (this example compiles logging package):
ipy pyc.py ".\Lib\logging\__init__.py" ".\Lib\logging\config.py" ".\Lib\logging\handlers.py" /target:dll /out:logging
This creates a logging.dll file, which you can then use like this:
import clr
clr.AddReference('StdLib') #from the compilation of non-package std libraries
clr.AddReference('logging')
import logging
**Note: This is assuming you've run the solution from IronPython: EXE compiled using pyc.py cannot import module "os" to create StdLib.dll
2nd way: Modify the compilation script that generated StdLib.dll
I changed this line:
#Build StdLib.DLL
gb = glob.glob(r".\Lib\*.py")
gb.append("/out:StdLib")
To this:
#Build StdLib.DLL
gb1 = glob.glob(r".\Lib\*.py")
gb2 = glob.glob(r".\Lib\*\*.py")
gb3 = glob.glob(r".\Lib\*\*\*.py")
gb = list(set(gb1 + gb2 + gb3))
gb.append("/out:StdLib")
This includes the subfolders in the Lib directory which get missed in the original regex (only modules get included). Now, packages like xml, json, logging, etc. get included into StdLib.dll