Reputation: 1659
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
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
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
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