Relative import error with py2exe - python

I was trying to generate an executable for a simple Python script. My setup.py code looks like this:
from distutils.core import setup
import py2exe
setup(console=["script.py"])
However, I am getting the error shown in the screenshot. Is there something I could try to fix this? I am using Windows 10.

It seems that in your mf3.py you are importing beyond the top level.
Let's suppose that your project structure is as follows:
folder/
main.py
mod/
__init__.py
components/
__init__.py
expander.py
language_id.py
utilities/
__init__.py
functions.py
First make sure that
main.py refers to the subpackages as:
from mod.components.expander import *
from mod.utilities.functions import *
expander.py and language_id.py have access to functions.py with:
from ..utilities.functions import *
Add options to your setup.py
You can also use more py2exe options in order that you are importing all the modules and the packages required by your project. E.g.
# setup.py
from distutils.core import setup
import py2exe
setup(console=["script.py"],
options={
"py2exe":{
"optimize": 2,
"includes": ["mf1.py", "mf2.py", "mf3.py"], # List of all the modules you want to import
"packages": ["package1"] # List of the package you want to make sure that will be imported
}
}
)
In this way you can force the import of the missing script of your project

Related

Relative imports in python with local ang global libraries

My apps are organized like this:
apps/
code/
libglobal/
funglobal.py
tests/
project/
liblocal/
funlocal.py
main.py
In main.py I have:
import liblocal.funlocal
In funlocal.py I try to import funglobal.py with:
from ....code.libglobal import funglobal
When I run
python3 -B tests/project/main.py
I get an error:
from ....code.libglobal import funglobal
ValueError: attempted relative import beyond top-level package
I have read a lot of information about relative imports with python3 and still don't find how to solve this error without changing the apps organization radically. Any solution?
As the script being executed has its __name__ set as __main__ and defines itself to be on the top level of the package, it refuses to recognize scripts in sibling directories.
You can fix this with a sys.path hack:
import sys, os
sys.path.insert(0, os.path.abspath('../..'))
or an interseting alternative with setuptools is presented in this answer.
Have you a __init__.py script in each folder ?
If no, you should create an empty script named __init__.py in each folder.

Can't import by library name, even though I have python setup.py develop it

I am running into a very strange python import problem. I wrote my own repo, and used a setup.py script to setup the import path, script below:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from __future__ import unicode_literals
from setuptools import setup, find_packages
__author__ = 'Shaun Rong'
__version__ = '0.1'
__maintainer__ = 'Shaun Rong'
__email__ = 'rongzq08#gmail.com'
if __name__ == "__main__":
setup(name='Quantomic',
version=__version__,
author="Ziqin (Shaun) Rong, Wenxuan Huang",
author_email="rongzq08#mit.edu key01027#mit.edu",
license="MIT License",
packages=find_packages(),
zip_safe=False)
I used python setup.py develop to run the codes. Now, however, I can't import the whole library by name Quantomic, any codes like
import Quantomic
or
from Quantomic import settings
will raise the error: ImportError: No module named Quantomic
I do have a __init__.py under the library root, and I checked sys.path, /Users/shaunrong/Documents/projects/Quantomic is in the path.
I do, however, can import using relative paths in any codes inside Quantomic, using like
import settings
will work OK.
Can anyone tell me what is going on? I am happy to provide more information upon request!
UPDATE
File/Folder structure looks like:
/Quantomic
__init__.py
settings.py
/data
__init__.py
price.py
Your setup.py file is in the wrong directory. Here is your folder structure
/Quantomic
setup.py
__init__.py
settings.py
/data
__init__.py
price.py
It should look like this
/Quantomic (can be named anything)
setup.py
/Quantomic
__init__.py
settings.py
/data
__init__.py
price.py
When you last ran setup.py, it likely installed a data library into your python installation. Or, because you used develop, it added the path above data to the pythonpath using a pth file in your python libs folder.

Namespacing in Python imports

I have a rather complex python build project with a PyQT GUI interface. The builder is supposed to accept configuration for a list of projects, which may differ from user to user, and then customize the build process for a selected project. As a result, parts of the builder project are versioned with the project to be built (project specific UI elements and controller files), with the rest being located in the builders directory. The issue I am running into is an overlap in namespacing for imports. For example:
The builder directory might look like:
Builder/
Controllers/
__init__.py
BuilderController1.py
BuilderController2.py
UI/
__init__.py
BuilderUI_1.py
BuilderUI_2.py
.../
__main__.py
The project directory might look like:
Project/
Project_Files/
Build/
Controllers/
__init__.py
ProjController1.py
ProjController2.py
UI/
__init__.py
ProjUI_1.py
ProjUI_2.py
.../
__init__.py
Project_setup.py
With code in __main__.py such as:
...
sys.path.append("../path/to/Project/Build")
projSetup = __import__("Project_setup)
projSetup.run()
...
And code in Project_setup.py such as:
...
from Controllers.ProjController1 import TestControl1
from Controllers.ProjController2 import TestControl2
def run():
registerStage(name = 'TestControl1', controller = TestControl1(mainApp.getController(), displayName='TestControl1'), displayName = 'Test Control Page 1', parent = None)
registerStage(name = 'TestControl2', controller = TestControl2(mainApp.getController(), displayName='TestControl2'), displayName = 'Test Control Page 2', parent = None)
...
The problem is that every time I run __main__.py, I get an error saying that:
ImportError: No module named Controllers.ProjController1
It seems that while searching the PYTHONPATH for the module ProjController1 the interpreter gets stranded in Builder/Controllers and then stops looking further down the path.
Is this reasonable behavior in python? Is there a method to obtain the same results that circumvents these issues?
I have tried using the various flavors of python importing ( import, __import__, imp, and importlib). Additionally it will work if I rename Project/Build/Controllers and Project/Build/UI, but given the possible complexity of these file structures I would rather not be stuck giving unique names to everything.
Relative paths are reliant on your current working directory. Try the following for your sys path append:
import os
dir_ = os.path.dirname(__file__)
sys.path.append(os.path.join(dir_, "/path/to/Project/Build"))
It's really better to make a package, then import via the fully qualified path. In your root project dir, put a file setup.py with contents similar to:
#!/usr/bin/env python
from setuptools import setup
from setuptools import find_packages
setup(
name='Name',
version='1.0',
packages=find_packages(exclude=('tests',)),
cmdclass={
},
package_data={
},
)
Then building and installing the package like so:
python setup.py build; python setup.py install
Perform the imports like so:
from project.hierarchy.module import Class
More information on creating packages is available in the Python docs.
Relative imports and modifying sys path have always caused me heartache.

Package import creates a module, submodules still importable

I've been working on a python package and now I would like to turn it into a small RPM distribution. Package includes a few modules, one of which is executable. I can create the RPM-package with python setup.py bdist_rpm and install it on a fedora box with rpm.
At this point have the desired command myscript and it works like a charm. But when i try to import the package in ipython, I run into something strange. I can do the following
from myscript import sdf
import myscript.mol2
Both work flawlessly, but
import myscript
myscript.sdf
throws
AttributeError: 'module' object has no attribute 'sdf'
I've been working with this for a while now to no avail. There's plenty of questions of import problems, but I haven't found an answer for this one yet.
What I should change to make it work?
The current folder structure is:
myscript/ #project root
setup.py
src/
myscript/
__init__.py
functions.py
sdf.py
mol2.py
runner.py
bin/
myscript #symbolic link to src/myscript/runner.py
setup.py is:
from distutils.core import setup
setup(name = 'myscript',
version = '0.75',
author ='me',
requires = ['numpy'],
packages = ['myscript'],
package_dir = {'myscript':'src/myscript'},
scripts = ['bin/myscript']
)
and __init__.py is:
__all__ = ['functions','sdf','mol2','runner']
This is normal behavior. If you want submodules to be imported then you must import them in the module.
# myscript/__init__.py
from . import sdf

ImportError on subpackage when running setup.py test

I'm trying to create an install package for a Python project with included unit tests. My project layout is as follows:
setup.py
src/
disttest/
__init__.py
core.py
tests/
disttest/
__init__.py
testcore.py
My setup.py looks like this:
from distutils.core import setup
import setuptools
setup(name='disttest',
version='0.1',
package_dir={'': 'src'},
packages=setuptools.find_packages('src'),
test_suite='nose.collector',
tests_require=['Nose'],
)
The file tests/disttest/testcore.py contains the line from disttest.core import DistTestCore.
Running setup.py test now gives an ImportError: No module named core.
After a setup.py install, python -c "from disttest.core import DistTestCore" works fine. It also works if I put import core into src/disttest/__init__.py, but I don't really want to maintain that and it only seems necessary for the tests.
Why is that? And what is the correct way to fix it?
You may want to double-check this, but it looks like your tests are importing the disttest package in the tests/ directory, instead of the package-under-test from the src/ directory.
Why do you need to use a package with the same name as the package-under-test? I'd simply move the testcore module up to the tests directory, or rename the tests/disttest package and avoid the potential naming conflict altogether.
In any case, you want to insert a import pdb; pdb.set_trace() line just before the failing import and play around with different import statements to see what is being imported from where (import sys; sys.modules['modulename'].__file__ is your friend) so you get a better insight into what is going wrong.

Categories