I have following setup.py:
from setuptools import setup
from distutils.core import setup
setup(
name="foobar",
version="0.1.0",
author="Batman",
author_email="batman#gmail.com",
packages = ["foobar"],
include_package_data=True,
install_requires=[
"asyncio",
],
entry_points={
'console_scripts': [
'foobar = foobar.__main__:main'
]
},
)
Now, the main.py file gets installed and callable by foobar out of console after installation, which is what I wanted. Problem is, main.py has import at line 3 and that does not work.
So my folder structure is as follows
dummy/setup.py
dummy/requirements.txt
dummy/foobar/__init__.py
dummy/foobar/__main__.py
dummy/foobar/wont_be_imported_one.py
I run python3 setup.py bdist being in dummy directory.
Upon running foobar after installation, I get error
File "/usr/local/bin/foobar", line 9, in <module>
load_entry_point('foobar==0.1.0', 'console_scripts', 'foobar')()
[...]
ImportError: No module named 'wont_be_imported_one'.
UPDATE.
__init__.py has content of
from wont_be_imported_one import wont_be_imported_one
wont_be_imported_one.py has from wont_be_imported_one function which I actually need to import.
In Python 3, imports are absolute by default, and so from wont_be_imported_one import ... inside of foobar will be interpreted as a reference to some module named wont_be_imported_one outside of foobar. You need to use a relative import instead:
from .wont_be_imported_one import wont_be_imported_one
# ^ Add this
See PEP 328 for more information.
Related
I have a Cython extension module for a Python project I want to install to the same namespace as the project on installation. When I try to specify in the extension to install it inside the package itself, it can't be found and imported. If I specify the extension goes in the root of the Python namespace, it works fine, but it's not in the module namespace I want. How do I get the Extension Module to be importable from the same namespace as the package itself?
I've made a simple test case for this question.
Folder Structure:
mypkg
├── foo
│ ├── __init__.py
│ └── barCy.pyx
└── setup.py
The .barCy.pyx file:
cpdef long bar():
return 0
The setup.py code:
import distutils.extension
from Cython.Build import cythonize
from setuptools import setup, find_packages
extensions = [distutils.extension.Extension("foo.bar",
['foo/barCy.pyx'])]
setup(
name='foo',
packages=find_packages(),
ext_modules=cythonize(extensions),
)
The __init.py__ is empty.
I want to be able to do:
>>> import foo.bar as bar
>>> bar.bar()
0
Instead, I get
>>> import foo.bar as bar
ModuleNotFoundError: No module named 'foo.bar'
If I were to change the Extension("foo.bar",... to Extension("bar",..., then I can do import bar like it were a top level package. Although that is the expected behavior, it's not what I want as I only want this extension module to be accessible through the foo namespace.
My Python interpreter was being run from the same folder as the setup.py script, so doing import foo was importing the local package, rather than the one installed in Python interpreter's site-packages directory. Because they have the same folder structure, the local directory was chosen as the superseding imported package.
Do testing/running from a different folder than the source.
I am attempting to compile a *.pyx file. It uses some definitions and constants inside a __init__.py in the same directory. The project structure is:
setup.py
Foo/__init__.py
Foo/Foo.pyx
and the setup command is as follows:
from setuptools import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
setup(
cmdclass = {'build_ext': build_ext},
ext_module = [ Extension(name='Foo', sources=['Foo/Foo.pyx']) ],
include_dirs=[numpy.get_include()],
name='Foo',
packages=['Foo'],
zip_safe=True
)
Problem arises when the egg is built and deployed. The resultant egg has the following structure:
Foo.so
Foo.py
Foo/__init__.py
Now, Foo.py contains some dynamic import code that basically imports the *.so file. However, because of the presence of Foo/__init__.py, import Foo attempts to import symbols only from __init__.py, which contains just some constants (all the relevant code is actually in Foo.so).
I've hacked around this issue by pasting all the definitions from __init__.py into Foo.pyx, but I'm trying to figure out what a proper solution might be.
Any advice is appreciated!
I tracked down my problem to an extraneous argument to the setup() command. Judging by the documentation at https://docs.python.org/2/distutils/setupscript.html, I do not need the packages=['Foo'] argument, and in fact that's what's causing it to create the inner Foo package that's messing everything up.
I am trying to compile, install and run a package that we'll call myPackage. It contains a *.pyx file that calls the function fftw_set_timelimit() from library fftw. Currently, when I run a script clientScript.py that imports the package I obtain the following error message :
Traceback (most recent call last):
File "clientScript.py", line 5, in <module>
import myPackage.myModule
ImportError: /usr/local/lib/python2.7/dist-packages/myPackage/myModule.so: undefined symbol: fftw_set_timelimit
From what I understand (I am quite new to python and cython), the linking with the C library is not yet performed in my package. Indeed, my setup.py file looks like this :
from setuptools import setup,find_packages
from Cython.Build import cythonize
import os
setup(
name = "myPackage",
version = "0.0.1",
url = "none",
author = "me",
author_email = "me#me.me",
packages=find_packages(),
ext_modules = cythonize("pyClo/pyClo.pyx"),
)
As you can see my setup.py file uses setuptools. I decided to do so since it is recommended by the Python Packaging User Guide. However, the instructions in the Cython documentation use distutils instead. Linking libraries is done through a call to distutils.Extension('file',['file.pyx'],libraries='fftw'). How do I achieve the same result using setuptools ?
It turns out setuptools has a module setuptools.extension.Extension which is used in the same way as the distutils.extension.Extension module .
In the end, the setup.py file looks something like :
from setuptools import setup, find_packages
from setuptools.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension(
"myPackage.myModule",
["myPackage/myModule.pyx"],
include_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
libraries=['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 'fftw3f_threads', 'fftw3l_threads'],
library_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
),
]
setup(
name = "myPackage",
packages = find_packages(),
ext_modules = cythonize(extensions)
)
Here is an overview of my installation directory :
.
├── MANIFEST.in
├── myPackage
│ └── myModule.pyx
├── README.rst
└── setup.py
where myModule.pyx is the file that calls fftw_set_timelimit().
MANIFEST.in contains :
include myPackage/*.*
and README.rst is a mere plain text file.
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
I'm trying to import a cython module data.pyx into another cython module user.pyx.
Everything compile fine, but when I try to call user.pyx in a python module, I am getting the error 'ImportError: No module named data'.
Everything is in the same directory.
package/
__init__.py #empty
setup.py
data.pxd
data.pyx
user.pyx
My setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("data", ["data.pyx"]),
Extension("user", ["user.pyx"],include_dirs = ['myPackageDir'])
]
setup(
name = 'app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Running the following test.py will raised the error.
import user #this line raised the 'ImportError: No module named data' below
user.doSomething()
The exception I get is
Traceback:
File "test.py", line 1, in <module>
import package.user
File "user.pyx", line 1, in init user (user.c:3384)
ImportError: No module named data
How can I make the import work? Thanks for any help.
I encounter this problem again in an another project. To solve it, here is what I did:
all import and cimport statement must be fully qualified
all the python code must be contained in a rootFolder
the setup.py must be at the same level than the rootFolder
all folder in the rooFolder including the rootFolder must contains a __init__.py
in your setup.py the extension's include_dirs must contains '.'
I created a simple project which illustrates this here.
This page helped me created it.
But my project is simpler and I think it would have helped me a lot if I had it.
My project also illustrate how to automatically build all cython files in a project.
I might be missing something about Cython, but I think it's:
import package.user
user.doSomething()