![](/img/trans.png)
[英]How do I make an ubuntu/debian package for a twistd/twisted plugin?
[英]How do I write a setup.py for a twistd/twisted plugin that works with setuptools, distribute, etc?
Twisted Plugin System是編寫可擴展扭曲應用程序的首選方法。
但是,由於插件系統的結構方式(插件進入一個不應該是Python包的twisted / plugins目錄),編寫一個正確的setup.py來安裝這些插件似乎並非易事。
我已經看到一些嘗試將'twisted.plugins'添加到distutils setup命令的'packages'鍵中,但由於它不是真正的包,所以會發生不好的事情(例如,有些人會添加__init__.py
)工具)。
其他嘗試似乎使用'package_data'(例如, http ://bazaar.launchpad.net/~glyph/divmod.org/trunk/view/head: /Epsilon/epsilon/setuphelper.py ),但這也可能失敗以奇怪的方式。
問題是:有沒有人成功編寫過setup.py來安裝扭曲的插件,它適用於所有情況?
我記錄下面的setup.py,只有當用戶的pip <1.2時才需要(例如在Ubuntu 12.04上)。 如果每個人都有1.2或更新的pip,你唯一需要的是packages=[..., 'twisted.plugins']
。
通過阻止pip將行“ twisted
”寫入.egg-info/top_level.txt
,你可以繼續使用packages=[..., 'twisted.plugins']
並且有一個工作pip uninstall
,不會刪除所有twisted/
。 這涉及monkeypatching setuptools /分布在setup.py
的頂部附近。 這是一個示例setup.py
:
from distutils.core import setup
# When pip installs anything from packages, py_modules, or ext_modules that
# includes a twistd plugin (which are installed to twisted/plugins/),
# setuptools/distribute writes a Package.egg-info/top_level.txt that includes
# "twisted". If you later uninstall Package with `pip uninstall Package`,
# pip <1.2 removes all of twisted/ instead of just Package's twistd plugins.
# See https://github.com/pypa/pip/issues/355 (now fixed)
#
# To work around this problem, we monkeypatch
# setuptools.command.egg_info.write_toplevel_names to not write the line
# "twisted". This fixes the behavior of `pip uninstall Package`. Note that
# even with this workaround, `pip uninstall Package` still correctly uninstalls
# Package's twistd plugins from twisted/plugins/, since pip also uses
# Package.egg-info/installed-files.txt to determine what to uninstall,
# and the paths to the plugin files are indeed listed in installed-files.txt.
try:
from setuptools.command import egg_info
egg_info.write_toplevel_names
except (ImportError, AttributeError):
pass
else:
def _top_level_package(name):
return name.split('.', 1)[0]
def _hacked_write_toplevel_names(cmd, basename, filename):
pkgs = dict.fromkeys(
[_top_level_package(k)
for k in cmd.distribution.iter_distribution_names()
if _top_level_package(k) != "twisted"
]
)
cmd.write_file("top-level names", filename, '\n'.join(pkgs) + '\n')
egg_info.write_toplevel_names = _hacked_write_toplevel_names
setup(
name='MyPackage',
version='1.0',
description="You can do anything with MyPackage, anything at all.",
url="http://example.com/",
author="John Doe",
author_email="jdoe@example.com",
packages=['mypackage', 'twisted.plugins'],
# You may want more options here, including install_requires=,
# package_data=, and classifiers=
)
# Make Twisted regenerate the dropin.cache, if possible. This is necessary
# because in a site-wide install, dropin.cache cannot be rewritten by
# normal users.
try:
from twisted.plugin import IPlugin, getPlugins
except ImportError:
pass
else:
list(getPlugins(IPlugin))
我用pip install
, pip install --user
和easy_install
測試了這個。 使用任何安裝方法,上面的monkeypatch和pip uninstall
工作正常。
您可能想知道:我是否需要清除monkeypatch以避免搞亂下一次安裝? (例如pip install --no-deps MyPackage Twisted
;你不想影響Twisted的top_level.txt
。)答案是否定的; monkeypatch不影響另一個安裝,因為pip
為每次安裝產生一個新的python
。
相關:請記住,在項目中,您不能有文件 twisted/plugins/__init__.py
。 如果在安裝過程中看到此警告:
package init file 'twisted/plugins/__init__.py' not found (or not a regular file)
這是完全正常的,你不應該試圖通過添加修復它__init__.py
。
這是一篇博客文章,描述了使用'package_data'進行的操作:
http://chrismiles.livejournal.com/23399.html
以什么奇怪的方式可以失敗? 如果軟件包的安裝沒有將軟件包數據放入sys.path上的目錄,則可能會失敗。 在這種情況下,Twisted插件加載器將找不到它。 但是,我所知道的所有Python軟件包安裝都會將它們放在安裝Python模塊或軟件包本身的同一目錄中,這樣就不會有問題了。
也許您可以調整package_data的想法來改為使用data_files:它不需要您將twisted.plugins列為包,因為它使用絕對路徑。 不過,它仍然是一個kludge。
我對純distutils的測試告訴我,它可以覆蓋另一個發行版的文件。 我想使用pkgutil.extend_path和distutils測試窮人的命名空間包,結果發現我可以使用spam.eggs安裝spam.ham / setup.py和spam/eggs/__init__.py
spam/ham/__init__.py
init__.py /setup.py。 目錄不是問題,但文件將被愉快地覆蓋。 我認為這實際上是在distutils中的未定義行為,這些行為涓涓細流到setuptools和pip,所以pip可以IMO關閉為wontfix。
安裝Twisted插件的常用方法是什么? 手動放在這里?
我用這種方法:
.py
'和' .pyc
'版本放入包中的“ twisted/plugins/
”文件夾中。 請注意,'。 .pyc
'文件可以為空,它應該存在。 在setup.py
指定將兩個文件復制到庫文件夾(確保不會覆蓋現有插件!)。 例如:
# setup.py from distutils import sysconfig LIB_PATH = sysconfig.get_python_lib() # ... plugin_name = '<your_package>/twisted/plugins/<plugin_name>' # '.pyc' extension is necessary for correct plugins removing data_files = [ (os.path.join(LIB_PATH, 'twisted', 'plugins'), [''.join((plugin_name, extension)) for extension in ('.py', '.pyc')]) ] setup( # ... data_files=data_files )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.