DEV Community 👩‍💻👨‍💻

Inada Naoki
Inada Naoki

Posted on • Updated on

Don't omit __init__.py

I saw some people think Python 3 allow package without __init__.py on Stackoverflow or mailing lists.

This is misunderstanding. Package directory without __init__.py is "namespace package", not a regular package. See PEP 420 for reference.

Namespace package is special package for people creating complex "distribution package" ("package" which can be registered on PyPI). There is guide for namespace package in "Python Packaging User guide".

There are some difference between namespace package and regular package.

For example, unittest module in standard library doesn't search into directory without __init__.py. If they do, they may take dozen seconds to search tests in node_modules which contains millions of files and subdirectories.

You should not omit __init__.py in your project unless you are 100% sure about what "namespace package" is. Use "regular package" with __init__.py instead.

Top comments (5)

Collapse
 
diek profile image
diek

Thanks, it is interesting but I did not understood shit about the difference of those package you say.

Can you extend your explanation?

Ty

Collapse
 
methane profile image
Inada Naoki

No need to understand "namespace package" unless you're distributing complex package.

If you are, read user guide.

Collapse
 
diek profile image
diek

Ty

Collapse
 
oniltonmaciel profile image
Onilton Maciel

To play the devil's advocate a little bit, the following quotes come from pep 420 python.org/dev/peps/pep-0420/:

"'regular package' refers to packages as they are implemented in Python 3.2 and earlier."

"A namespace package is not fundamentally different from a regular package. It is just a different way of creating packages. Once a namespace package is created, there is no functional difference between it and a regular package."

"There is no intention to remove support of regular packages. If a developer knows that her package will never be a portion of a namespace package, then there is a performance advantage to it being a regular package (with an init.py). Creation and loading of a regular package can take place immediately when it is located along the path. With namespace packages, all entries in the path must be scanned before the package is created."

Collapse
 
pryanga profile image
Allium

The way init.py solved my issue confuses what you have stated. In my case,
the test_inference.py inside /test directiry called inference.py as a module (import inference) but it resulted in module not found error.
/project
/test
|--test_inference.py
|--inference.py

However, after adding init.py to /tests directiry, unittest was able to import inferecne.py as a module.

Could you explain why?

Hey 😍

Want to help the DEV Community feel more like a community?

Head over to the Welcome Thread and greet some new community members!

It only takes a minute of your time, and goes a long way!