How to fix Attempted relative import in non-package even with __init__.py
Yes. You're not using it as a package.
python -m pkg.tests.core_test
Attempted relative import in non-package' although packages with __init__.py in one directory
Relative imports only work for packages, but when you importing in extended.py
you are running a top-level module instead.
The current directory may hold a __init__.py
file but that doesn't make exended.py
part of a package yet.
For something to be considered a package, you need to import the directory name instead. The following would work:
main.py
packagename\
__init__.py
basic.py
extended.py
then in main.py
put:
import packagename.extended
and only then is extended
part of a package and do relative imports work.
The relative import now has something to be relative to, the packagename
parent.
Getting Attempted relative import in non-package error in spite of having __init__.py
You cannot run a python module directly as a script (I don't really know the reason why).
EDIT : The reason is explained in the PEP338 which is the spec for the "-m"
option.
The release of 2.5b1 showed a surprising (although obvious in
retrospect) interaction between this PEP and PEP 328 - explicit
relative imports don't work from a main module. This is due to the
fact that relative imports rely on__name__
to determine the current
module's position in the package hierarchy. In a main module, the
value of__name__
is always__main__
, so explicit relative imports
will always fail (as they only work for a module inside a package).For the 2.5 release, the recommendation is to always use absolute imports in any module that is intended to be used as a main module
To test your application, encapsulate api_main in a function and create a top-level main.py file which will run the main loop :
cclogger/api_main.py :
import re
import os
from .bottle import run, default_app, debug, get
from .common_util import date_str_to_datetime, UTCOffset, date_filter
#app = Bottle()
def main():
default_app().router.add_filter('date', date_filter)
from . import api, dev
@get('/index')
def index():
return "CCLogger API main live and kicking."
if dev:
debug(True)
run(reloader=True, port=9000)
else:
os.chdir(os.path.dirname(__file__))
application = default_app()
And /main.py :
from cclogger import api_main
if __name__ == '__main__':
api_main.main()
You can run your application by typing python main.py
, python -m main
or python -c "import cclogger.api_main; api_main.main()"
.
PS : thanks for linking the complete source, it's always much more helpful than the stubs provided with the question.
relative path not working even with __init__.py
You need to update your sys.path
, which is where python looks for modules, as opposed to your system's path in the current environment, which is what os.environ["PATH"]
is referring to.
Example:
import os, sys
sys.path.insert(0, os.path.abspath(".."))
import aa
After doing this, you can use your functions in aa
like this: aa.myfunc()
There's some more information in the accepted answer for python: import a module from a directory
relative import from __init__.py file throws error
You have to understand how Python handles modules.
When you start the interpreter with a script, this script becomes the main module, with the matching name __main__
.
When using import
, other modules are searched in the search path, that you can also access (and change) using sys.path
. The first entry of sys.path
is usually empty and stands for the current directory.
A directory within the search path is a package if it contains a __init__.py
file.
Now, when you execute a script within a directory that contains an __init__.py
file, this script will become __main__
and the directory is not regarded as a package, as it is not in sys.path
!
For example, consider the following directory layout:
root/
pkg/
__init__.py
b.py
c.py
a.py
When you run python a.py
from the root/
directory, you can import pkg/
and use relative imports within this package (e.g., from . import c
in b.py
or __init__.py
).
When you run python b.py
from the pkg
directory, you cannot use relative imports since Python does not recognize pkg
as a package: it is not in sys.path
. For Python, pkg
is an ordinary directory, no matter if it contains a __init__.py
. The fully qualified name of c.py
is just c
, not pkg.c
, so a relative from . import c
won't work.
Imports inside package now that __init__.py is optional
The missing __init__.py
are not the problem - you are using outdated relative imports.
import sub.module # implicit relative import - py2 only
from . import sub.module # explicit relative import
Note that a .
import always requires the from .<where> import <name>
form. It would not produce a valid name otherwise. The following should work, assuming your run script.py
via python3 -m src.script
- an IDE will likely do the same.
from . import sub.module
from .sub import module
from .sub.module import *
from . import parent_module
If you are running as plain python3 script.py
or python3 -m script
, you cannot use relative imports. Only absolute imports will work in this case.
import sub.module
from sub import module
from sub.module import *
import parent_module
While you do not need __init__.py
files, it is a good idea to add them if your package is not a namespace. Otherwise, other similarly constructed packages of the same name may be inserted into yours.
ModuleNotFoundError even with __init__.py
You either need to make both assignments be part of a package, by putting a __init__.py
inside project
and then doing from ..assignment01 import old_file
. You will need to call your code from above project
(python -m project.assignment1.newfile.main
) , so python picks up the outer package and is able to resolve ..
. Or you can leave out the ..
and simply call from project
, as noted in the other answer. In any case the idea is to get assignment0
somewhere that python can find it and import.
Or you need to add project
to your sys.path
:
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
Your current import fails because python is looking in assignment02
for assignment01
and, of course, failing.
Related Topics
How to Pad a String With Zeroes
Open Web in New Tab Selenium + Python
String Count With Overlapping Occurrences
How to Print a Single Backslash
How to Find the Cumulative Sum of Numbers in a List
How to Remove an Element from a List by Index
How to Make One Python File Run Another
How to Update a Plot in Matplotlib
What Causes My Function to Return None At the End
Scatter Plot With Different Text At Each Data Point
How to Have One Colorbar For All Subplots
How to Melt a Pandas Dataframe
How to Create a Tuple With Only One Element
How to Select a Variable by (String) Name
Writing a List to a File With Python, With Newlines