6

For example there is some folder:

.
├── file_a.py
├── file_b
│  └── __init__.py
└── file_b.py

where file_a.py has something like:

from file_b import some_function

I know this is definitely not good practice, but what is the order of resolution behind?

i.e. How python decides which module to be imported for an "absolute import"?

asked Mar 12, 2018 at 16:21
2
  • The Python path? Commented Mar 12, 2018 at 16:39
  • If I had designed it, file_b.py would play the role that file_b/__init__.py currently does, and the latter would not exist. Commented Mar 14, 2024 at 2:39

3 Answers 3

5

I'm not sure where (or whether) this information is in the documentation - a quick check in the import system docs didn't turn it up - but PEP 420 says the following:

While looking for a module or package named "foo", for each directory in the parent path:

  • If <directory>/foo/__init__.py is found, a regular package is imported and returned.
  • If not, but <directory>/foo.{py,pyc,so,pyd} is found, a module is imported and returned. The exact list of extension varies by platform and whether the -O flag is specified. The list here is representative.
  • If not, but <directory>/foo is found and is a directory, it is recorded and the scan continues with the next directory in the parent path.
  • Otherwise the scan continues with the next directory in the parent path.

If the scan completes without returning a module or package, and at least one directory was recorded, then a namespace package is created.

So according to PEP 420, if a package and a non-package module are found in the same directory with the same name, the package wins.

answered Mar 12, 2018 at 16:46
Sign up to request clarification or add additional context in comments.

Comments

2

Based on @JonKiparsky 's suggestion, I dug through importlib a bit, and finally found importlib._bootstrap.FileFinder.find_spec, which does indeed explicitly check for a directory before looking for valid files that fit the package name. Glad to see @user2357112 's answer, though, that this is supposed to be defined behavior, and isn't just happenstance.

answered Mar 12, 2018 at 16:49

Comments

1

I did a little experiment, made somelib.py and somelib/__init__.py Then tried the following

>>> from somelib import foo
in somelib/__init__.py
>>>

Evidently python prefers a directory-based module to a file-based one

As @scnerd points out, this could be accidental behavior, but it's what I'm seeing in the default implementation.

If you want to know how this happens, you would probably review importlib for the gruesome details

answered Mar 12, 2018 at 16:28

1 Comment

I can't find any definition of what the "right answer" should be, though... It seems entirely possible that Pypy, Jython, IronPython, etc. might coincidentally do it differently

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.