从PyPI安装我的sdist会将文件放在意想不到的位置

Jon*_*ley 7 python distutils setuptools distribute pypi

我的问题是,当我将我的Python包上传到PyPI,然后使用pip从那里安装它时,我的应用程序中断,因为它将我的文件安装到完全不同的位置,而不是我从本地sdist安装完全相同的包.

从本地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)
Run Code Online (Sandbox Code Playgroud)

这就像我期望的那样,并且运行正常(例如我的源代码可以找到我的数据目录,因为它们彼此相邻,就像它们在开发中一样.)

如果我将相同的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)
Run Code Online (Sandbox Code Playgroud)

这根本不起作用 - 我的应用程序无法找到它的数据文件,加上显然它是一团糟,用我所有的垃圾污染顶级/ python27目录.

我究竟做错了什么?如何使pip安装表现得像本地sdist安装?这甚至是我应该努力实现的目标吗?

细节

我安装了setuptools,也分发了,我正在调用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)
Run Code Online (Sandbox Code Playgroud)

我的MANIFEST.in提到了我想要包含在sdist中的所有文件,包括数据,示例和doc目录中的所有内容:

recursive-include data *.*
recursive-include examples *.py
recursive-include doc/html *.html *.css *.js *.png
include LICENSE.txt
include TODO.txt
Run Code Online (Sandbox Code Playgroud)

我的setup.py非常冗长,但我想最好将它包含在这里,对吧?我还包括对MANIFEST.in中提到的相同data/doc/examples目录的重复引用,因为我知道这是为了在安装期间将这些文件从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()
Run Code Online (Sandbox Code Playgroud)

Len*_*bro 5

data_files参数用于不属于软件包的数据文件。您可能应该使用package_data代替。

参见https://docs.python.org/3/distutils/setupscript.html#installing-package-data

那不会将数据安装在site-packages / data中,但是我认为那不是应该安装的位置。您将不知道它属于哪个软件包。它应该安装在site-packages//gloopy-0.1.alpha-py2.7.egg/[data|doc|examples]IMO中。

如果您确实认为数据不是打包数据,则应该使用data_files并且在这种情况下pip可以正确安装它,而我会声称setup.py install将其安装在错误的位置。但是在我看来,在这种情况下,它是package_data,因为它与软件包有关,并且未被其他软件使用。