How to import module inside package - python

Folder structure:
foo/
bar.py
__init__.py
test.py
foo/__init__.py has import bar
I am running test.py which has import foo
How do I get __init__.py to import bar.py?
ModuleNotFoundError: No module named 'foo'
Why does Python not create a new scope for my package and make the root for imports the foo directory?
Relative paths seem to not work either (I'm receiving a SyntaxError), although I'm looking for a solution that allows absolute paths.
import .bar
Two unacceptable answers:
I can't use import foo.bar. I need the foo package to have its own independent layer/scope so I can move it around anywhere in my computer and import it from anywhere. This means the root could change and import foo.bar will not always work.
I can't add the foo folder to my path. Obviously this would clutter the path and name conflicts could easily happen. Commence sense would say that this package's files should be separated from the path of what's using it.
Maybe there's a solution to add this package's directory to the path only for the scope of that package, somewhere in __init__.py?

Per PEP 328, the import X syntax is purely for absolute imports; since bar is not a top-level module here, the only valid import X syntax is import foo.bar.
The correct way to import bar from foo's __init__.py is:
from . import bar
Your point about wanting "absolute paths", but also wanting something like import .bar is impossible; even if import .bar worked, that's clearly a relative path (in that it only makes sense relative to the module that executes it; .bar would not make sense if imported outside of the foo package).
As for "Why does Python not create a new scope for my package and make the root for imports the foo directory?" the simple example is to imagine your sub-module is named math, not bar. What does:
import math
mean in this context? If it means your sub-module, how do you get the built-in, top-level math module? These problems (which I've encountered in Python 2 code when I failed to include from __future__ import absolute_import) are why PEP 328 and default absolute imports exist; one syntax is always absolute (removing ambiguity), and you can use the relative import syntax to perform relative imports (also without ambiguity) when needed.

Okay so you are having an error in __init__.py file in import bar right?
Well this shouldn't blow up but an easy alternate to this is from . import bar
EDIT
I understood the error occurs due to hierarchy and that __init__.py has a top level hierarchy. I found the following article of great help. Also see ShadowRanger's answer to this question.

Related

Why does error occurs when importing from same *sub*directory?

Consider this folder structure:
main.py
module_a/
aa.py
bb.py
__init__.py
In main.py, I import aa as:
from module_a import aa
aa.yyy()
Then in aa.py, I import bb and include its functions as:
import bb
bb.xxx()
However, when I run main.py, python says "No module named 'bb'".
May I know why this happens. What is the correct way to import bb.
Thanks!!!
I have tried to write aa.py as:
import .bb
bb.xxx()
But it still does not work.
why this happens
Because the aa folder is not a place that Python is searching for modules.
Python's imports are absolute by default. They only look in specific places determined by sys.path. In main.py, import module_a.aa works because the root folder of the project happens to be on the sys.path; that folder contains a module_a folder; and that folder contains aa.py.
What is the correct way to import bb.
Please use relative imports between files in your package. In this case, the necessary import in aa.py looks like:
from . import bb
Absolute imports are error-prone; a project that uses two packages whose contents have overlapping names will run into namespace collisions. (Sadly, the standard library uses absolute imports in most places, such that projects need to ban certain module names for safety.) Relative imports will also require much less maintenance, should you later rename a sub-package.
The only thing relative imports require is that the package gets loaded, which typically will happen automatically with the first (yes, absolute) import of any of the package contents. When the package is loaded, it automatically sets a __package__ attribute on the modules in that package, which Python can use to resolve the relative imports. It's important to note that relative imports are relative to the package hierarchy, not the directory structure, which is why this is necessary; imports like from .. import example do not work by figuring out the current file location and then going up a level in the directory hierarchy. Instead, they check the __package__ to figure out what the containing package is, then check the file/folder location for that, and work from there.
If the "driver" script is within the package, run it as a module, using the -m switch for Python. For example, from the root folder, if module_a/aa.py is the driver, use python -m module_a.aa. This instructs Python that module_a is the containing package for aa.py, and ensures it gets loaded even though no import in the code has loaded it.
Contrary to what many people will wrongly tell you, it is almost never required to manipulate sys.path; there are popular Python projects on GitHub, running hundreds of thousands of lines of code, which either do not use it at all or use it only once in an ancillary role (perhaps because of a special requirement for a documentation tool). Just don't do it.
Also contrary to what many people will wrongly tell you, __init__.py files are not required to create packages in Python. They are simply a place where additional code can be placed for package initialization - for example, to create aliases for sub-package contents, or to limit what will be imported with a *-import (by setting __all__).
import .bb
This is just invalid. Relative imports only use the from syntax. See above for the correct syntax.
Suppose the same file structure as stated in OP, and:
main.py:
import module_a.aa
module_a.aa.thisFile()
module_a.aa.module_a.bb.thisFile()
aa.py:
import module_a.bb
def thisFile():
print("aa")
bb.py:
def thisFile():
print("bb")
Then, this will print
aa
bb
like you would expect. The main difference here, is that bb.py is imported in aa.py via module_a.bb. Running main.py gives no problem, however, running aa.py does not work in this way. That is why you might want to add folders to your path, such that you can call a function from a different file without this trouble. This is done via:
import os, inspect, sys
current_folder = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parent_folder = os.path.dirname(current_folder)
sys.path.insert(0,parent_folder)
Then you can import your files such as import file. If you consider this option, I would suggest to do some reading about how this works. Tip: make sure you avoid cyclic import problems.

Attempted relative import in non-package for optional package [duplicate]

Imagine this directory structure:
app/
__init__.py
sub1/
__init__.py
mod1.py
sub2/
__init__.py
mod2.py
I'm coding mod1, and I need to import something from mod2. How should I do it?
I tried from ..sub2 import mod2 but I'm getting an "Attempted relative import in non-package".
I googled around but found only "sys.path manipulation" hacks. Isn't there a clean way?
Edit: all my __init__.py's are currently empty
Edit2: I'm trying to do this because sub2 contains classes that are shared across sub packages (sub1, subX, etc.).
Edit3: The behaviour I'm looking for is the same as described in PEP 366 (thanks John B)
Everyone seems to want to tell you what you should be doing rather than just answering the question.
The problem is that you're running the module as '__main__' by passing the mod1.py as an argument to the interpreter.
From PEP 328:
Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
In Python 2.6, they're adding the ability to reference modules relative to the main module. PEP 366 describes the change.
Update: According to Nick Coghlan, the recommended alternative is to run the module inside the package using the -m switch.
Here is the solution which works for me:
I do the relative imports as from ..sub2 import mod2
and then, if I want to run mod1.py then I go to the parent directory of app and run the module using the python -m switch as python -m app.sub1.mod1.
The real reason why this problem occurs with relative imports, is that relative imports works by taking the __name__ property of the module. If the module is being directly run, then __name__ is set to __main__ and it doesn't contain any information about package structure. And, thats why python complains about the relative import in non-package error.
So, by using the -m switch you provide the package structure information to python, through which it can resolve the relative imports successfully.
I have encountered this problem many times while doing relative imports. And, after reading all the previous answers, I was still not able to figure out how to solve it, in a clean way, without needing to put boilerplate code in all files. (Though some of the comments were really helpful, thanks to #ncoghlan and #XiongChiamiov)
Hope this helps someone who is fighting with relative imports problem, because going through PEP is really not fun.
main.py
setup.py
app/ ->
__init__.py
package_a/ ->
__init__.py
module_a.py
package_b/ ->
__init__.py
module_b.py
You run python main.py.
main.py does: import app.package_a.module_a
module_a.py does import app.package_b.module_b
Alternatively 2 or 3 could use: from app.package_a import module_a
That will work as long as you have app in your PYTHONPATH. main.py could be anywhere then.
So you write a setup.py to copy (install) the whole app package and subpackages to the target system's python folders, and main.py to target system's script folders.
"Guido views running scripts within a package as an anti-pattern" (rejected
PEP-3122)
I have spent so much time trying to find a solution, reading related posts here on Stack Overflow and saying to myself "there must be a better way!". Looks like there is not.
This is solved 100%:
app/
main.py
settings/
local_setings.py
Import settings/local_setting.py in app/main.py:
main.py:
import sys
sys.path.insert(0, "../settings")
try:
from local_settings import *
except ImportError:
print('No Import')
explanation of nosklo's answer with examples
note: all __init__.py files are empty.
main.py
app/ ->
__init__.py
package_a/ ->
__init__.py
fun_a.py
package_b/ ->
__init__.py
fun_b.py
app/package_a/fun_a.py
def print_a():
print 'This is a function in dir package_a'
app/package_b/fun_b.py
from app.package_a.fun_a import print_a
def print_b():
print 'This is a function in dir package_b'
print 'going to call a function in dir package_a'
print '-'*30
print_a()
main.py
from app.package_b import fun_b
fun_b.print_b()
if you run $ python main.py it returns:
This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
main.py does: from app.package_b import fun_b
fun_b.py does from app.package_a.fun_a import print_a
so file in folder package_b used file in folder package_a, which is what you want. Right??
def import_path(fullpath):
"""
Import a file with full path specification. Allows one to
import from anywhere, something __import__ does not do.
"""
path, filename = os.path.split(fullpath)
filename, ext = os.path.splitext(filename)
sys.path.append(path)
module = __import__(filename)
reload(module) # Might be out of date
del sys.path[-1]
return module
I'm using this snippet to import modules from paths, hope that helps
This is unfortunately a sys.path hack, but it works quite well.
I encountered this problem with another layer: I already had a module of the specified name, but it was the wrong module.
what I wanted to do was the following (the module I was working from was module3):
mymodule\
__init__.py
mymodule1\
__init__.py
mymodule1_1
mymodule2\
__init__.py
mymodule2_1
import mymodule.mymodule1.mymodule1_1
Note that I have already installed mymodule, but in my installation I do not have "mymodule1"
and I would get an ImportError because it was trying to import from my installed modules.
I tried to do a sys.path.append, and that didn't work. What did work was a sys.path.insert
if __name__ == '__main__':
sys.path.insert(0, '../..')
So kind of a hack, but got it all to work!
So keep in mind, if you want your decision to override other paths then you need to use sys.path.insert(0, pathname) to get it to work! This was a very frustrating sticking point for me, allot of people say to use the "append" function to sys.path, but that doesn't work if you already have a module defined (I find it very strange behavior)
Let me just put this here for my own reference. I know that it is not good Python code, but I needed a script for a project I was working on and I wanted to put the script in a scripts directory.
import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
As #EvgeniSergeev says in the comments to the OP, you can import code from a .py file at an arbitrary location with:
import imp
foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()
This is taken from this SO answer.
Take a look at http://docs.python.org/whatsnew/2.5.html#pep-328-absolute-and-relative-imports. You could do
from .mod1 import stuff
From Python doc,
In Python 2.5, you can switch import‘s behaviour to absolute imports using a from __future__ import absolute_import directive. This absolute- import behaviour will become the default in a future version (probably Python 2.7). Once absolute imports are the default, import string will always find the standard library’s version. It’s suggested that users should begin using absolute imports as much as possible, so it’s preferable to begin writing from pkg import string in your code
I found it's more easy to set "PYTHONPATH" enviroment variable to the top folder:
bash$ export PYTHONPATH=/PATH/TO/APP
then:
import sub1.func1
#...more import
of course, PYTHONPATH is "global", but it didn't raise trouble for me yet.
On top of what John B said, it seems like setting the __package__ variable should help, instead of changing __main__ which could screw up other things. But as far as I could test, it doesn't completely work as it should.
I have the same problem and neither PEP 328 or 366 solve the problem completely, as both, by the end of the day, need the head of the package to be included in sys.path, as far as I could understand.
I should also mention that I did not find how to format the string that should go into those variables. Is it "package_head.subfolder.module_name" or what?
You have to append the module’s path to PYTHONPATH:
export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"
A hacky way to do it is to append the current directory to the PATH at runtime as follows:
import pathlib
import sys
sys.path.append(pathlib.Path(__file__).parent.resolve())
import file_to_import # the actual intended import
In contrast to another solution for this question this uses pathlib instead of os.path.
This method queries and auto populates the path:
import os
import inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
os.sys.path.insert(1, parentdir)
# print("currentdir = ", currentdir)
# print("parentdir=", parentdir)
What a debate!
Relative newcomer to python (but years of programming experience, and dislike of perl). Relative lay-person when it comes to the dark art of Apache setup, but I know what I (think I) need to get my little experimental projects working at home.
Here is my summary of what the situ seems to be.
If I use the -m 'module' approach, I need to:-
dot it all together;
run it from a parent folder;
lose the '.py';
create an empty (!) __init__.py file in every sub-folder.
How does that work in a cgi environment, where I have aliased my scripts directory, and want to run a script directly as /dirAlias/cgi_script.py??
Why is amending sys.path a hack? The python docs page states: "A program is free to modify this list for its own purposes." If it works, it works, right? The bean counters in Accounts don't care how it works.
I just want to go up one level and down into a 'modules' dir:-
.../py
/cgi
/build
/modules
so my 'modules' can be imported from either the cgi world or the server world.
I've tried the -m/modules approach but I think I prefer the following (and am not confused how to run it in cgi-space):-
Create XX_pathsetup.py in the /path/to/python/Lib dir (or any other dir in the default sys.path list). 'XX' is some identifier that declares an intent to setup my path according to the rules in the file.
In any script that wants to be able to import from the 'modules' dir in above directory config, simply import XX_pathsetup.py.
And here's my really simple XX_pathsetup.py:
import sys, os
pypath = sys.path[0].rsplit(os.sep,1)[0]
sys.path.insert( 0, pypath+os.sep+'modules' )
Not a 'hack', IMHO. 1 small file to put in the python 'Lib' dir, one import statement which declares intent to modify the path search order.

Importing across a python package

pkg/
__init__.py
foo.py
bar.py
baz.py
I have a bunch of module imports that are the same across foo.py, bar.py, and baz.py.
Is there a way I can do the imports in __init__.py? What would I have to write in foo.py?
Placing the imports in __init__.py would be a bad idea; __init__.py is used as the contents of your module object, so it is a public interface. Also, __init_.py is imported initially when your package is imported, while you don't actually need the imports to occur until your submodules need them.
The best approach is to put common code in an internal detail module, marked with a single initial underscore (meaning "private"), e.g. _imports.py, then in your other files write from ._imports import *.
You guessed the right way of doing this, but I can make this a little more formal and give (hopefully) a clearer explanation than the one you found elsewhere. If you want to modularize imports, which depending on your coding philosophy could be a good or bad idea in and of itself (transparency vs. code reuse), whether or not the imports happen in __init__.py you can import your imports from another script. For instance:
"""import_scripts.py"""
import numpy as np
import scipy as sp
...
"""actual_code.py"""
from import_scripts import *
# np and sp are now in scope
Importing from __init__.py is mostly the same, you just traditionally use a relative import instead if you're accessing it from the same module:
# To import form __init__
from . import *
Important to note though, that these kind of imports will only work if you run these python scripts explicitly as modules rather than as scripts. This means:
python -m foo
instead of
python foo.py
Important, but subtle distinction.
Hope that helps. Let me know if you have any more questions.

Relative Import Confusion in Python

I am having some trouble figuring out how to do relative imports in Python. I am currently working on my first major project so I want to do it right using unit tests. However, I am having trouble with my file structure and relative imports.
Here is my current structure:
App/
__init__.py
src/
__init__.py
person.py
tests/
__init__.py
person_tests.py
What I want to do is be able to import person.py into person_tests.py for the unit tests. I have attempted the following:
from . import person
from .. import person
from .App.src import person
from ..App.src import person
from ..src.person import *
from ..src import person
from .src import person
Every one of the above throws either a syntax error or
ValueError: Attempted relative import in non-package
Can someone please clarify this for me?
Edit: Python version is 2.7.
Edit: I would like to be able to use this with say unittest or nose.
My guess (and I'll delete this if I'm wrong) is that you're trying to use person_tests.py as a top-level script, rather than as a module inside a package, by doing something like this:
$ cd App/tests
$ python person_tests.py
In that case, person_tests does not end up as App.tests.person_tests, but as just __main__ (or, with minor variations, as the top-level person_tests, which has the same basic issues). So, .. does not refer to App, and therefore there is no way to get to person as a relative import.
More generally, nothing on PYTHONPATH, including ., should ever be in the middle of any package directory, or things will get broken.
The right answer is to not do that. Do something like this:
$ python -m App.tests.person_tests
Or write a top-level (outside the package) script that imports the module, and run that top-level script.
Just as abarnert says, you can not excute the script as main for the relative import based on the current name of the script. Quoted from the doc:
Note that both explicit and implicit relative imports are based on the
name of the current module. Since the name of the main module is
always "__main__", modules intended for use as the main module of a
Python application should always use absolute imports.
. represents the current package and .. represents the parent package. So some of your import statement is wrong.
from . import person # wrong for no person module in package tests
from .. import person # wrong for no person module in package app
from .App.src import person # wrong for no app package in package tests
from ..App.src import person # wrong for no app package in package app
from ..src.person import * # right
from ..src import person # right
from .src import person # wrong
You can refer PEP328 for the standard of relative import.
you could append it to sys.path.
import sys
sys.path.append("../src")
import person

Multilevel relative import

Multilevel relative import
I have following folder structure
top\
__init__.py
util\
__init__.py
utiltest.py
foo\
__init__.py
foo.py
bar\
__init__.py
foobar.py
I want to access from foobar.py the module utiltest.py. I tried following relative import, but this doesn't work:
from ...util.utiltest import *
I always get
ValueError: Attempted relative import beyond toplevel package
How to do such a multileve relative import?
I realize this is an old question, but I feel the accepted answer likely misses the main issue with the questioner's code. It's not wrong, strictly speaking, but it gives a suggestion that only coincidentally happens to work around the real issue.
That real issue is that the foobar.py file in top\foo\bar is being run as a script. When a (correct!) relative import is attempted, it fails because the Python interpreter doesn't understand the package structure.
The best fix for this is to run foobar.py not by filename, but instead to use the -m flag to the interpreter to tell it to run the top.foo.bar.foobar module. This way Python will know the main module it's loading is in a package, and it will know exactly where the relative import is referring.
You must import foobar from the parent folder of top:
import top.foo.bar.foobar
This tells Python that top is the top level package. Relative imports are possible only inside a package.

Categories

Resources