gsakkis
gsakkis

Reputation: 1659

Python package without __init__

I pip install-ed the flufl.enum Python package and I noticed that it works despite missing a flufl/__init__.py module as regular Python packages. Even stranger is this:

>>> import flufl
>>> flufl
<module 'flufl' (built-in)>

I tried to reproduce this creating foo/bar/__init__.py without foo/__init__.py and (predictably) import foo fails. How does flufl do it?

Upvotes: 14

Views: 3456

Answers (3)

Michael Merickel
Michael Merickel

Reputation: 23341

flufl is just a namespace package, declared in the egg's namespace_packages.txt

If you look at its source tree it actually does have flufl/__init__.py, but for distribution as an egg it looks like it's not necessary due to setuptools magic.

Upvotes: 0

Antonio Cuni
Antonio Cuni

Reputation: 226

the magic is done in the flufl.enum-3.2-py2.7-nspkg.pth file, which is put into site-packages by "pip install":

import sys,new,os
p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('flufl',))
ie = os.path.exists(os.path.join(p,'__init__.py'))
m = not ie and sys.modules.setdefault('flufl',new.module('flufl'))
mp = (m or []) and m.__dict__.setdefault('__path__',[])
(p not in mp) and mp.append(p)

pth files are evaluated at startup. In particular, this file creates a new module named "flufl" and puts it into sys.modules. That also explains why you see it as "built-in":

>>> import new
>>> new.module('foo')
<module 'foo' (built-in)>

Upvotes: 19

Stefano Borini
Stefano Borini

Reputation: 143935

I don't get it

ls /Users/sbo/lib/python2.7/site-packages/flufl.enum-3.2-py2.7.egg/flufl/
__init__.py   __init__.pyc  enum/

Did you compile flufl.enum together with python ? It's the only way it can be a builtin module.

By the way, I actually read a PEP where packages could skip the init, but I don't remember if it was approved, rejected, or under scrutiny.

Upvotes: 0

Related Questions