简体   繁体   中英

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?

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)>

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM