Why Does Import Of Sibling Packages Not Always Work In Python: On ‘attempted relative import beyond top-level package’
2 min readDec 3, 2021
The aim of this page📝 is to explore/explain why in Python it is not possible to have a folder structure where there’s:
- 1 main file
- multiple subfolders that refer to each other
Attempting that (for example by creating ./test
and trying to refer to ./modules
) will fire
attempted relative import beyond top-level package
- the current working directory (
CWD
) is not a package - you need a folder within the current working directory containing the
main.py
() - this folder, the top-level package can be called something like
.\packages
but it can have other names, too - you cannot easily refer from top-level package to
main.py
, other modules withinCWD
, or to other top-level packages withinCWD
- I believe there are hacks, but why?
- for example, in C# it is conventional to have
src
for code andtest
for tests as siblings
- the CWD in Python does not work as a package — therefore you can’t refer from first-level subfolders across each other
- this is officially explicitly discouraged
- but there is demand — even bounty is given to the solution on Stack Overflow
- in essence, there is a big difference between
- running a Python file
- importing that file from somewhere else
- knowing what directory a file is in does not determine what package Python thinks it is in.
- that depends on how you load the file into Python (by running or by importing)
- essential: if
__name__
does not contain.
it is not considered to be a part of the package - it, therefore, is not important where it is on the disk
- if I navigate to the
./runner
subfolder and callpython real_run.py
the situation changes: - module
make_change.py
will NOT be able to calllogger.py
because they become siblings, i.e. 2 top-level packages