How to Fix "Attempted Relative Import in Non-Package" Even With _Init_.Py

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



Leave a reply



Submit