Python relative imports - python

Right,
I have a structure like so:
/Project
__init__.py
script_a.py
/tests
__init__.py
test_something.py
When test_something tries to import using from . import script_a it returns the error Attempted relative import in non-package.
I've put in the empty __init__.py files and added /Project to PYTHONPATH but it still throws up this error!
Any ideas?
EDIT:
I have now used a tester.py situated in \Project and call:
import script_a
from tests.test_something import *
Now it works!!

When test_something tries to import using from . import script_a it returns the error Attempted relative import in non-package.
Using one dot . will lead you to the current directory. You should use two dots .. to get to the parent dir.
You cannot run a module with a relative import itself. You can only import it. So test_something.py can only run as an import but it is not possible to run the script as __main__

from Project import script_a should work for you.

Related

Need to know clean way to have import work when program is run from different directories [duplicate]

Let's say I have the following directory structure:
parent_dir/
foo_dir/
foo.py
bar_dir/
bar.py
If I wanted to import bar.py from within foo.py, how would I do that?
If all occurring directories are Python packages, i.e. they all contain __init__.py, then you can use
from ..bar_dir import bar
If the directories aren't Python packages, you can do this by messing around with sys.path, but you shouldn't.
You can use the sys and os modules for generalized imports. In foo.py start with the lines
import sys
import os
sys.path.append(os.path.abspath('../bar_dir'))
import bar
Let's say if you have following structure:
root
|_ productconst.py
|_ products
|_ __init__.py
And if you would like to import productconst in products.__init__, then following can be used :
from ..productconst import *
If you're having issues in python 3+, the following worked for me using sys.path.append("..").
sys.path.append("..")
from bar_dir import bar

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.

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.

How to do relative imports in Python with this structure?

Imagine I have this structure :
dir/
__init__.py
dir1/
__init__.py
x.py
dir2/
__init__.py
y.py
Now I want to import x.py to y.py .
I try this from ..dir1.x import * in y.py from PEP 328 but I get this error Attempted relative import in non-package .
I search for hours but I can not find any answer to this problem .
There are a lot of similar problems like mine but none of them help me like this
Please help .
Thanks a lot .
in y.py, add this piece of import code
import sys
sys.path.insert(0, '..')
then do
from dir1.x import *
Relative imports won't work when files are invocated directly:
python y.py
since they have __name__ == '__main__' instead of their full package name.
For the relative import to work you must use y as a package:
python -m dir.dir2.y

Categories