Пакет Python без __init__

I pip install -ed flufl.enum пакет Python, и я заметил, что он работает, несмотря на отсутствие модуля flufl/__init__.py в качестве обычных пакетов Python. Даже незнакомец:

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

Я попытался воспроизвести это создание foo/bar/__init__.py без foo/__init__.py и (предсказуемо) import foo не удалось. Как это сделать flufl?

Ответы

Ответ 1

волшебство сделано в файле flufl.enum-3.2-py2.7-nspkg.pth, который помещается в пакеты сайта с помощью "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 файлы оцениваются при запуске. В частности, этот файл создает новый модуль с именем "flufl" и помещает его в sys.modules. Это также объясняет, почему вы видите его как "встроенный":

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

Ответ 2

Я не понимаю его

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

Вы скомпилировали flufl.enum вместе с python? Это единственный способ, которым это может быть встроенный модуль.

Кстати, я действительно читал PEP, где пакеты могли пропустить init, но я не помню, было ли это одобрено, отклонено или под контролем.

Ответ 3

flufl - это просто пакет пространства имен, объявленный в egg namespace_packages.txt

Если вы посмотрите на его исходное дерево, у него действительно есть flufl/__init__.py, но для распространения в виде яйца он выглядит как не нужен из-за магии setuptools.