【问题标题】:Python setup.py: data_files can't copy 'directory': doesn't exist or not a regular filePython setup.py:data_files 无法复制“目录”:不存在或不是常规文件
【发布时间】:2021-02-24 20:20:24
【问题描述】:

我有以下python项目结构:

.
├ setup.py
├ doc
|   ├ file.css
|   ├ file.html
|   └ file.js
└ src
    ├ matlabsources
    |             └ <several folders architecture with .m and .slx files>
    └ mypythonpackage
        ├ __init__.py
        └ <several sub packages architecture with python files>

我想将 doc 文件夹中的所有文件添加到我的 whl 分发文件中。

setuptools.setup(
    name='myproject',
    author='me',
    packages=setuptools.find_packages(where='src', include=['packages*']),
    package_dir={'': 'src'},
    data_files ={'documentation': find_data_files('doc'), 'matlab': find_data_files('src/matlabsources')},
    include_package_data=True,
    install_requires=make_deps(REQS_FILENAME),
    python_requires='>= 2.7',  # Only compatible with Python 2.7.* and 3+
    use_scm_version={'version_scheme': simple_version},  # setuptools_scm: the blessed package to manage your versions by scm tags
    setup_requires=make_deps(SETUP_FILENAME),
    cmdclass=dict(bdist_egg=custom_bdist_egg, build=custom_build, activateIniGeneration=activateIniGeneration)
)


def find_data_files(directory):
    """
    Using glob patterns in ``package_data`` that matches a directory can
    result in setuptools trying to install that directory as a file and
    the installation to fail.

    This function walks over the contents of *directory* and returns a list
    of only filenames found.
    """

    strip = os.path.dirname(os.path.abspath(__file__))

    result = []
    for root, dirs, files in os.walk(directory):
        for filename in files:
          filename = os.path.join(root, filename)
          result.append(os.path.relpath(filename, strip))

    print("\n".join(result))
    return result

我收到以下错误:

error: can't copy 'documentation': doesn't exist or not a regular file

据我了解,'documentation'是目标目录,相对于sys.prefix,不存在是正常的。

我正在使用以下命令进行构建:

python setup.py bdist_wheel --universal

我也有这个警告

warning: install_data: setup script did not provide a directory for 'documentation' -- installing right in 'build\bdist.win32\wheel\myproject-1.7.z_gfdc81e60.d20201112.data\data'

这让我觉得我需要对我的setup.py 进行进一步配置才能使其工作

我哪里错了?

【问题讨论】:

  • 为什么?为什么要将文档添加到 wheel 文件中?您还想要安装 doc 文件吗?您希望将 doc 文件安装在哪里?谁将访问这些文件?文件将如何被访问? ——我在问,因为这是一个不寻常的问题,我不确定最终目标是什么。知道目的是什么,将有助于为您提供更有用的答案。
  • 是的,我想安装 doc 文件,为此必须将它们添加到 wheel 文件中,对吗?还是有其他方法?我简化了示例,但它们也是要安装的 matlab 文件,这些文件是从 python 包中访问的。文件应与源包放置在同一级别。
  • 我建议你看看package_data。我总结了hereStackOverflow 上还有其他重复的问题。如果你显示你的目录结构,我可能可以在这里写下一个真正的答案。
  • 只是为了确保,您希望保留此目录结构,但希望将docmatlabsources 作为mypythonpackage 的子包安装。那正确吗?所以在site-packages 目录中,你想让它们分别为[...]/site-packages/mypythonpackage/doc[...]/site-packages/mypythonpackage/matlabsources?如果没有,请编辑问题以显示安装后的预期目录结构。

标签: python setuptools data-files


【解决方案1】:

假设项目目录结构如:

myproject
├── doc
│   ├── alpha
│   │   ├── file.css
│   │   ├── file.html
│   │   └── file.js
│   ├── file.css
│   ├── file.html
│   └── file.js
├── MANIFEST.in
├── setup.cfg
├── setup.py
└── src
    ├── matlabsources
    │   ├── bravo
    │   │   ├── file.m
    │   │   └── file.slx
    │   ├── file.m
    │   └── file.slx
    └── mypythonpackage
        ├── charlie
        │   └── __init__.py
        └── __init__.py

使用MANIFEST.in,您可以指定要添加到_source 分发(sdist) 中的其他文件。

recursive-include doc *.css
recursive-include doc *.html
recursive-include doc *.js

recursive-include src/matlabsources *.m
recursive-include src/matlabsources *.slx

setuptools 脚本setup.py 应如下所示:

#!/usr/bin/env python3

import setuptools

def _find_packages():
    packages = setuptools.find_packages(where='src')
    packages.append('mypythonpackage.doc')
    packages.append('matlabsources')
    return packages

def _main():
    setuptools.setup(
        # see 'setup.cfg'
        #
        packages=_find_packages(),
        include_package_data=True,
        package_dir={
            'mypythonpackage': 'src/mypythonpackage',
            'mypythonpackage.doc': 'doc',
            'matlabsources': 'src/matlabsources',
        },
    )


if __name__ == '__main__':
    _main()

这会导致 sdist

$ python3 -m tarfile -l dist/myproject-0.0.0.dev0.tar.gz 
myproject-0.0.0.dev0/ 
myproject-0.0.0.dev0/MANIFEST.in 
myproject-0.0.0.dev0/PKG-INFO 
myproject-0.0.0.dev0/doc/ 
myproject-0.0.0.dev0/doc/alpha/ 
myproject-0.0.0.dev0/doc/alpha/file.css 
myproject-0.0.0.dev0/doc/alpha/file.html 
myproject-0.0.0.dev0/doc/alpha/file.js 
myproject-0.0.0.dev0/doc/file.css 
myproject-0.0.0.dev0/doc/file.html 
myproject-0.0.0.dev0/doc/file.js 
myproject-0.0.0.dev0/myproject.egg-info/ 
myproject-0.0.0.dev0/myproject.egg-info/PKG-INFO 
myproject-0.0.0.dev0/myproject.egg-info/SOURCES.txt 
myproject-0.0.0.dev0/myproject.egg-info/dependency_links.txt 
myproject-0.0.0.dev0/myproject.egg-info/requires.txt 
myproject-0.0.0.dev0/myproject.egg-info/top_level.txt 
myproject-0.0.0.dev0/pyproject.toml 
myproject-0.0.0.dev0/setup.cfg 
myproject-0.0.0.dev0/setup.py 
myproject-0.0.0.dev0/src/ 
myproject-0.0.0.dev0/src/matlabsources/ 
myproject-0.0.0.dev0/src/matlabsources/bravo/ 
myproject-0.0.0.dev0/src/matlabsources/bravo/file.m 
myproject-0.0.0.dev0/src/matlabsources/bravo/file.slx 
myproject-0.0.0.dev0/src/matlabsources/file.m 
myproject-0.0.0.dev0/src/matlabsources/file.slx 
myproject-0.0.0.dev0/src/mypythonpackage/ 
myproject-0.0.0.dev0/src/mypythonpackage/__init__.py 
myproject-0.0.0.dev0/src/mypythonpackage/charlie/ 
myproject-0.0.0.dev0/src/mypythonpackage/charlie/__init__.py 

轮子中

$ python3 -m zipfile -l dist/myproject-0.0.0.dev0-py3-none-any.whl 
File Name                                             Modified             Size
matlabsources/file.m                           2020-11-16 16:41:06            0
matlabsources/file.slx                         2020-11-16 16:41:06            0
matlabsources/bravo/file.m                     2020-11-16 16:41:18            0
matlabsources/bravo/file.slx                   2020-11-16 16:41:18            0
mypythonpackage/__init__.py                    2020-11-16 16:45:02           88
mypythonpackage/charlie/__init__.py            2020-11-16 16:55:22            0
mypythonpackage/doc/file.css                   2020-11-16 16:30:34            0
mypythonpackage/doc/file.html                  2020-11-16 16:30:34            0
mypythonpackage/doc/file.js                    2020-11-16 16:30:34            0
mypythonpackage/doc/alpha/file.css             2020-11-16 16:33:00            0
mypythonpackage/doc/alpha/file.html            2020-11-16 16:33:00            0
mypythonpackage/doc/alpha/file.js              2020-11-16 16:33:00            0
myproject-0.0.0.dev0.dist-info/METADATA        2020-11-16 17:03:32         1311
myproject-0.0.0.dev0.dist-info/WHEEL           2020-11-16 17:03:32           92
myproject-0.0.0.dev0.dist-info/top_level.txt   2020-11-16 17:03:32           30
myproject-0.0.0.dev0.dist-info/RECORD          2020-11-16 17:03:32         1499

【讨论】:

  • 这是我所拥有的,只是 doc 文件夹不在 mypackage 下,而是在 src 下。我找到了一个可行的解决方案,它提供了一个 > 的字典,我提供了一个 List)> 并且它可以工作。我不明白为什么,这不是文档中的内容。
  • 实际上我读得很差,因为它被指定为与字典 package_data 相反的元组列表。这就是为什么要保持一致性
  • packages=_find_packages() for packages.append('matlabsources') 行我收到错误:包目录'matlabsources' 不存在,我添加了一个__init__.py 文件,但它没有任何改变。
  • 我设法使 setup.py 以您的方式工作,但无事可做,matlab 文件夹最终不会出现在 whl 存档中。
  • 从复制您的用例开始,它可以工作,所以我将调查我自己的项目中出了什么问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-05
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
相关资源
最近更新 更多