Ответ 1
Это больше, чем, по крайней мере, 5 лет, с тех пор, как я впервые задал себе почти тот же вопрос, и ваш вопрос теперь является импульсом, чтобы наконец найти его.
Для меня было также интересно, если можно добавить точки входа из того же каталога, что и script, без установки пакета. Хотя я всегда знал, что единственным содержимым пакета может быть какая-то мета с точками входа, смотрящими на некоторые другие пакеты.
В любом случае, вот некоторые настройки моего каталога:
ep_test newtover$ tree
.
├── foo-0.1.0.dist-info
│ ├── METADATA
│ └── entry_points.txt
└── foo.py
1 directory, 3 files
Вот содержимое foo.py
:
ep_test newtover$ cat foo.py
def foo1():
print 'foo1'
def foo2():
print 'foo2'
Теперь откройте ipython
:
In [1]: def write_ep(lines): # a helper to update entry points file
...: with open('foo-0.1.0.dist-info/entry_points.txt', 'w') as f1:
...: print >> f1, '\n'.join(lines)
...:
In [2]: write_ep([ # only one entry point under foo.test
...: "[foo.test]",
...: "foo_1 = foo:foo1",
...: ])
In [3]: !cat foo-0.1.0.dist-info/entry_points.txt
[foo.test]
foo1 = foo:foo1
In [4]: import pkg_resources
In [5]: ws = pkg_resources.WorkingSet() # here is the answer on the question
In [6]: list(ws.iter_entry_points('foo.test'))
Out[6]: [EntryPoint.parse('foo_1 = foo:foo1')]
In [7]: write_ep([ # two entry points
...: "[foo.test]",
...: "foo_1 = foo:foo1",
...: "foo_2 = foo:foo2"
...: ])
In [8]: ws = pkg_resources.WorkingSet() # a new instance of WorkingSet
С параметрами по умолчанию WorkingSet
просто пересматривает каждую запись в sys.path, но вы можете сузить список. pkg_resources.iter_entry_points
привязан к глобальному экземпляру WorkingSet
.
In [9]: list(ws.iter_entry_points('foo.test')) # both are visible
Out[9]: [EntryPoint.parse('foo_1 = foo:foo1'), EntryPoint.parse('foo_2 = foo:foo2')]
In [10]: foos = [ep.load() for ep in ws.iter_entry_points('foo.test')]
In [11]: for func in foos: print 'name is {}'.format(func.__name__); func()
name is foo1
foo1
name is foo2
foo2
И содержимое METADATA:
ep_test newtover$ cat foo-0.1.0.dist-info/METADATA
Metadata-Version: 1.2
Name: foo
Version: 0.1.0
Summary: entry point test
UPD1. Я снова подумал об этом и теперь понимаю, что вам нужен дополнительный шаг перед использованием новых плагинов: вам нужно перезагрузить модули.
Это может быть просто:
In [33]: modules_to_reload = {ep1.module_name for ep1 in ws.iter_entry_points('foo.test')}
In [34]: for module_name in modules_to_reload:
....: reload(__import__(module_name))
....:
Но если новая версия вашего пакета плагинов основана на значительных изменениях в других используемых модулях, вам может потребоваться определенный порядок перезагрузки и перезагрузки этих измененных модулей. Это может стать громоздкой задачей, так что перезапуск бота будет единственным способом.