user3205479
user3205479

Reputation: 1523

Understand package imports

I have started learning python very recently. I do have a typescript and C# background. I was trying to understand the packages and imports statements. Following is the very basic folder structure I have created and I have few questions on this

app/
 |-> pkg1/
      |-> fib.py
      |-> __init__.py
 |- >pkg2/
      |-> mul.py
      |-> __init__.py
 |-> app.py
ext/
 |-> ext.py
 |-> __init__.py 

fib.py
------
from pkg2.mul import mul
// from ..pkg2.mul import mul -> Error: attempted relative import beyond top-level package
// but this should work as per docs https://docs.python.org/3/tutorial/modules.html#intra-package-references
// can someone tell why do I get this error?

def fib(n):
    return mul(n) * 2

mul.py
------
def mul(n):
    return n * 10

app.py
------
from pkg1.fib import fib
print(fib(1))

I have read Python treats any file as entry file.

Am I missing something? In typescript we use relative imports and C# we use namespaces and include files but here I am pretty confused. Any help is greatly appreciated.

Upvotes: 1

Views: 55

Answers (2)

tantalum
tantalum

Reputation: 2452

The basic issue is that your app is not package (because it is missing an __init__.py file) which means when you go two levels up to the app directory you aren't in a package any more, and thus the error stating that you are attempting to import beyond the top-level package.

See this section on intra-package references for more info on how you could restructure your package to allow what you are attempting to do. You also check out this section explaining the module search path for a little more context.

Upvotes: 0

wim
wim

Reputation: 362567

Your relative import attempt did not work because pkg1 and pkg2 are separate packages. Relative imports only work within one package.

Does python even know app.py is the entry point?

No. It's just some .py file sitting around in a directory.

Why does it work when I have given pkg2.mul in fib.py

Coincidence. You are in the app/ directory, and the first element of sys.path is the working directory. It likely won't work if you cd to some other directory.

Why does it work when I have given pkg1.fib in app.py

Same as above.

What if I want to include ext.py inside mul.py and app.py

You have to package ext and include it as a dependency of app.

As per folder structure, if app.py imports pkg1.fib (relative to app.py) is valid then fib.py must import mul in different way correct? Why it is working for pkg2.mul? Is it actually valid? pkg2/ is not relative to fib.py.

It's not importing relative to app.py. They are both importing from cwd (check the first element of sys.path displayed by using python -m site)

Upvotes: 2

Related Questions