从PyPI安装我的sdist文件将文件放在意想不到的位置
我的问题是,当我把我的Python包上传到PyPI后,再用pip从那里安装时,我的应用程序就出问题了,因为它把我的文件安装到完全不同的位置,而不是我在本地用相同的包安装时的那些位置。
从本地的sdist安装时,文件在我系统上的位置是这样的:
/Python27/
Lib/
site-packages/
gloopy-0.1.alpha-py2.7.egg/ (egg and install info files)
data/ (images and shader source)
doc/ (html)
examples/ (.py scripts that use the library)
gloopy/ (source)
这个位置是我预期的,工作得也很好(比如我的源代码可以找到我的数据目录,因为它们是并排放在一起的,就像在开发时一样)。
但是如果我把同样的sdist上传到PyPI,然后用pip从那里安装,情况就完全不同了:
/Python27/
data/ (images and shader source)
doc/ (html)
Lib/
site-packages/
gloopy-0.1.alpha-py2.7.egg/ (egg and install info files)
gloopy/ (source files)
examples/ (.py scripts that use the library)
这样根本不行——我的应用找不到它的数据文件,而且显然这很乱,把我的一些文件搞得满处都是,污染了顶层的/python27目录。
我到底哪里做错了?我该怎么让pip的安装行为像本地的sdist安装一样?这真的是我应该追求的目标吗?
详细信息
我已经安装了setuptools和distribute,并且我调用了distribute_setup.use_setuptools()
我用的是WindowsXP,Python2.7。
我的开发目录看起来是这样的:
/gloopy
/data (image files and GLSL shader souce read at runtime)
/doc (html files)
/examples (some scripts to show off the library)
/gloopy (the library itself)
我的MANIFEST.in文件提到了我想要包含在sdist中的所有文件,包括数据、示例和文档目录中的所有内容:
recursive-include data *.*
recursive-include examples *.py
recursive-include doc/html *.html *.css *.js *.png
include LICENSE.txt
include TODO.txt
我的setup.py文件内容比较多,但我想把它放在这里,对吧?我还重复提到了数据、文档和示例目录,因为我知道这是为了确保这些文件在安装时能从sdist复制到系统中。
NAME = 'gloopy'
VERSION= __import__(NAME).VERSION
RELEASE = __import__(NAME).RELEASE
SCRIPT = None
CONSOLE = False
def main():
import sys
from pprint import pprint
from setup_utils import distribute_setup
from setup_utils.sdist_setup import get_sdist_config
distribute_setup.use_setuptools()
from setuptools import setup
description, long_description = read_description()
config = dict(
name=name,
version=version,
description=description,
long_description=long_description,
keywords='',
packages=find_packages(),
data_files=[
('examples', glob('examples/*.py')),
('data/shaders', glob('data/shaders/*.*')),
('doc', glob('doc/html/*.*')),
('doc/_images', glob('doc/html/_images/*.*')),
('doc/_modules', glob('doc/html/_modules/*.*')),
('doc/_modules/gloopy', glob('doc/html/_modules/gloopy/*.*')),
('doc/_modules/gloopy/geom', glob('doc/html/_modules/gloopy/geom/*.*')),
('doc/_modules/gloopy/move', glob('doc/html/_modules/gloopy/move/*.*')),
('doc/_modules/gloopy/shapes', glob('doc/html/_modules/gloopy/shapes/*.*')),
('doc/_modules/gloopy/util', glob('doc/html/_modules/gloopy/util/*.*')),
('doc/_modules/gloopy/view', glob('doc/html/_modules/gloopy/view/*.*')),
('doc/_static', glob('doc/html/_static/*.*')),
('doc/_api', glob('doc/html/_api/*.*')),
],
classifiers=[
'Development Status :: 1 - Planning',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python :: 2.7',
],
# see classifiers http://pypi.python.org/pypi?:action=list_classifiers
)
config.update(dict(
author='Jonathan Hartley',
author_email='tartley@tartley.com',
url='http://bitbucket.org/tartley/gloopy',
license='New BSD',
) )
if '--verbose' in sys.argv:
pprint(config)
setup(**config)
if __name__ == '__main__':
main()
2 个回答
你可以使用 pkgutil.get_data() 来加载包的数据,这个方法会帮你找到包数据具体安装的位置。
这里有一篇很不错的博客文章,讲的是如何在包中包含数据文件: 将数据文件包含到Python包中
data_files
这个参数是用来处理那些不属于包的数据文件的。不过,你可能更应该使用package_data
。
你可以查看这个链接了解更多信息:https://docs.python.org/3/distutils/setupscript.html#installing-package-data
使用data_files
不会把数据安装到site-packages/data目录下,不过我觉得其实也不应该放在那里。因为你可能不知道这些数据属于哪个包。它应该安装在site-packages//gloopy-0.1.alpha-py2.7.egg/[data|doc|examples]
这个位置。
如果你真的认为这些数据不是包的数据,那你可以使用data_files
,在这种情况下,pip会正确安装它,而我认为setup.py install
会把它安装到错误的地方。不过在我看来,这种情况下它应该是package_data,因为它和这个包有关,而不是被其他软件使用。