Django ImportError - python

I created my own Django application with directory structure
/appname
__init__.py
models.py
/submodule1
__init__.py
a.py
Inside a.py I have the following import
from ..models import Something
This works okay if I have /appname inside my /djangoproject folder, but when I install the app to Python's site-packages (via setup.py which I created), all hell breaks loose and a.py can no longer import Something, with the following error:
ImportError: cannot import name Something
Here is the setup.py:
from distutils.core import setup
setup(name='appname',
version='0.1',
packages=['appname', 'appname.contrib'],
)

It turns out that it was a circular import error. models.py was importing a.py and a.py was importing models.py.
Breaking this circle solved the import issues, but now it is time to figure out how to do lazy evaluation in Python :-)

Put empty file named: __init__.py inside /submodule1 so Python can parse it as module. It should help. The same in /appname - there should be also __init__.py file

Related

Import error using relative import syntax

I have a project structured like so:
/proj
main.py
config/
__init__.py
setup.py
gui/
__init__.py
app.py
The program is run by calling python main.py.
In main.py I have from gui import App.
In gui/__init__.py I have from .app import App.
Lastly, in app.py I have from ..config import configure; this throws a ValueError that reads attempted relative import beyond top-level package. To resolve this, I can alter the strucure:
/proj
main.py
proj/
config/
__init__.py
setup.py
gui/
__init__.py
app.py
But then I have to change the import statments to include proj (i.e. from proj.gui import App). Is it possible to use relative imports in the former case with the current structure? If not, how can I import what I need from the config subpackage?
As strange as it sounds, you can do :
from config import configure
in app.py, for your former case (current structure), because when you run python main.py, it interprets config as the next level package, and .. won't work.
(Btw, I think there is lots of room for Python imports to improve. The current PEP 328 is confusing at best).

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.

Relative import in Python 3.6

I want to use relative import in Python 3.
My project:
main_folder
- __init__.py
- run.py
- tools.py
I want to have in run.py (MyClass declared in __init__.py):
from . import MyClass
And in run.py:
from .tools import my_func
An ImportError is raise.
Alternatively, with absolute import, debugging in PyCharm does not work and the library takes from installed packages, not my directory.
I know one way, but it is terrible:
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
How to use this import in my project?
When you use PyCharm, it automatically makes the current module main, so relative statements like from . import <module> will not work. read more here.
to fix your problem, put the __init__.py and tools.py files in a sub-directory
main_directory/
run.py
sub_directory/
__init__.py
tools.py
in your run.py file, write the following as your import statements
from sub_directory import tools
from sub_directory.__init__ import MyClass
Edit: as #9000 mentioned, you can write from sub_directory import MyClass and achieve the same thing.

How to import from a python package which is in a sibling directory?

I am new to python and i am having some issues with packages and imports.
My structure is as follows:
src/
base/
packcore/
__init__.py
utils/
__init__.py
util_1.py
util_2.py
helpers/
__init__.py
helper_1.py
helper_2.py
some_script.py
app.py
packcore is an external package that has been installed using pip and put into the --target=base.
some of the helpers in the packcore uses some of the utils.
From app.py i want to be able to import a helper/util.
But when i use from base.packcore.utils import some_util i get an error saying that no module named packcore from inside the helper/util
and if i do from packcore.utils import some_util i get an error no module named packcorefrom theapp.py`
help would be much appreciated :)
If you add an __init__.py to base/, you can make it a Python package to import from. You also need to make the parent a package (Which is currently called src) so it is actually a sibling module, rather than many isolated modules.
From there, you can either do an absolute import from the main package:
from src.base.packcore.helpers import helper_1
Or relative (Assuming you are in some_script.py or app.py):
from .base.packcore.helpers import helper_1

Import method from __init__.py

Having some issues with importing modules in python. This is my folder structure
my_app/
app.py
__init__.py (I want to import a function from this file)
folder1/
__init.py
method1.py
folder2/
__init__.py
method.py
In my root __init__.py I have this function
def want_to_be_run_elsewhere():
pass
In my app.py, I want to import this function and run it when I start my application, but I'm unsure how to do it.
from my_app import want_to_be_run_elsewhere
This throws a no module named my_app
From what I can tell, I have all the necessary __init__.py files, so maybe it could be sys.path related?
I've read some similar threads on here but I haven't been able to solve this.
Usually you would do the import like
from . import want_to_be_run_elsewhere
This doesn't work here, because you are calling app.py. If you import my_app.app, it is part of the module. If you call it it is not. Importing from the module it is in using . will then not work.
You could either move app.py outside of my_app, removing it from the module and making imports work again.
Or you can use
from __init__ import want_to_be_run_elsewhere
in app.py
I believe
from my_app import want_to_be_run_elsewhere
will only work if you have actually pip install -e my_app/. Then it should work too.

Categories