5

我有一个带有setup.py脚本的 Python 应用程序,可以通过 Pip 或 setuptools 安装。但是,我发现这两种方法之间存在一些令人讨厌的差异,我想知道分发数据文件的正确方法

import glob
import setuptools

long_description = ''
setuptools.setup(
  name='creator-build',
  version='0.0.3-dev',
  description='Meta Build System for Ninja',
  long_description=long_description,
  author='Niklas Rosenstein',
  author_email='rosensteinniklas@gmail.com',
  url='https://github.com/creator-build/creator',
  py_modules=['creator'],
  packages=setuptools.find_packages('.'),
  package_dir={'': '.'},
  data_files=[
    ('creator', glob.glob('creator/builtins/*.crunit')),
  ],
  scripts=['scripts/creator'],
  classifiers=[
    "Development Status :: 5 - Production/Stable",
    "Programming Language :: Python",
    "Intended Audience :: Developers",
    "Topic :: Utilities",
    "Topic :: Software Development :: Libraries",
    "Topic :: Software Development :: Libraries :: Python Modules",
    ],
  license="MIT",
)
  1. 使用Pip, 中指定的文件data_files最终以sys.prefix + '/creator'.
  2. 使用setuptools(即setup.py直接运行),文件以lib/python3.4/site-packages/creator_build-0.0.3.dev0-py3.4.egg/creator.

理想情况下,我希望文件始终位于同一位置,而与安装方法无关。我还希望将文件放入模块目录中(setuptools 这样做的方式),但是如果将包安装为压缩的 Python Egg可能会导致问题。

如何确保data_files使用两种安装方法最终位于同一位置?另外,我怎么知道我的模块是否安装为压缩的 Python Egg,然后如何加载数据文件?

4

1 回答 1

0

我一直在问,包括官方文档在内的普遍共识是:

警告 data_files 已弃用。它不适用于轮子,因此应避免使用。

相反,每个人似乎都指向include_package_data相反。
这里有一个缺点,它不允许包含src根目录之外的内容。这意味着,如果creator是 outside creator-build,它将不包括它。甚至package_data会有这个限制。

唯一的解决方法是,如果您的数据文件位于源文件之外(例如,出于很多我们不需要讨论的原因,我试图将其包含在内examples/*.py) ,您可以热插拔它们,进行设置并然后删除它们。

import setuptools, glob, shutil

with open("README.md", "r") as fh:
    long_description = fh.read()

shutil.copytree('examples', 'archinstall/examples')

setuptools.setup(
    name="archinstall",
    version="2.0.3rc4",
    author="Anton Hvornum",
    author_email="anton@hvornum.se",
    description="Arch Linux installer - guided, templates etc.",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/Torxed/archinstall",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3.8",
        "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
        "Operating System :: POSIX :: Linux",
    ],
    python_requires='>=3.8',
    package_data={'archinstall': glob.glob('examples/*.py')},
)

shutil.rmtree('archinstall/examples')

这充其量是丑陋的,但有效。
我的参考文件夹结构是(在 git repo 中):

.
├── archinstall
│   ├── __init__.py
│   ├── lib
│   │   ├── disk.py
│   │   └── exceptions.py
│   └── __main__.py
├── docs
│   ├── logo.png
├── examples
│   ├── guided.py
│   └── minimal.py
├── LICENSE
├── profiles
│   ├── applications
│   │   ├── awesome.json
│   │   ├── gnome.json
│   │   ├── kde.json
│   │   └── postgresql.json
│   ├── desktop.py
│   ├── router.json
│   ├── webserver.json
│   └── workstation.json
├── README.md
└── setup.py

这是我可以看到如何包含例如我profiles的以及examples不将它们移动到存储库根目录之外的唯一方法(我不想这样做,因为我希望用户在导航到时轻松找到它们github上的回购)

最后一点。如果您不介意污染src目录,就我而言,这只是archinstall. 您可以在需要包含的任何内容中进行符号链接,而不是复制它。

cd archinstall
ln -s ../examples ./examples
ln -s ../profiles ./profiles

这样,当setup.pypip安装它时,它们最终会在<package dir>它的根目录中。

于 2020-07-08T10:21:01.253 回答