首页 > 解决方案 > 在 Setup.py 中控制数据目录的包含和排除的正确语法是什么?

问题描述

问:在使用setup.pyMANIFEST.IN创建 python 发行版时,如何在最终安装目录中定义我想要和不想要的嵌套数据目录(复杂示例!)

背景: 我的程序有一组数据目录(不是源目录)。在这些主目录中的每一个中,都有一些具有用户特定名称的子目录。在我的 setup.py 中,我想排除 我自己的数据目录,同时仍然包括所有用户都应该有权访问的其他子目录。

我的Pycharm开发环境中当前存在的文件树:

  PycharmProjects
     pythonProject
         data_files_directory_1
            subdirectory_to_be_EXcluded
                 data_file_to_be_EXcluded.txt
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
             index.html
         data_files_directory_2
            subdirectory_to_be_EXcluded
                 data_file_to_be_EXcluded.txt
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
             index.html
         src
             __init__.py
             constants.py
             helper1.py
             helper2.py
             main.py

预期结果:

在目标机器上安装后想要的文件树:

  PycharmProjects
     pythonProject
         data_files_folder_1
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
         data_files_folder_2
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
             index.html
         src
             __init__.py
             constants.py
             helper1.py
             helper2.py
             main.py

实际结果:

  PycharmProjects
     pythonProject
         data_files_directory_1
            subdirectory_to_be_EXcluded
                 data_file_to_be_EXcluded.txt
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
             index.html
         data_files_directory_2
            subdirectory_to_be_EXcluded
                 data_file_to_be_EXcluded.txt
            subdirectory_to_be_INcluded
                  data_file_to_be_INcluded.txt
             index.html
         src
             __init__.py
             constants.py
             helper1.py
             helper2.py
             main.py

我尝试了什么/源代码:

清单.IN

...
graft data_files_directory_1
graft data_files_directory_2
...

安装程序.py

setup(
    ...
    # include everything in MANIFEST.IN:
    include_package_data=True, 
    # ...but exclude just these directories */subdirectory_to_be_EXcluded/* from all packages
    exclude_package_data={"": ["*/subdirectory_to_be_EXcluded/*"]},
    ...
)

问题: 如您所见,排除请求被忽略。

我必须承认,在大量使用关于 setup.py 和安装程序的 Google、YouTube 和 PyCharm 文档之后,我并不清楚包含排除非源目录和文件的正确方法是什么。似乎许多可能的解决方案已被弃用

这样做的正确方法是什么?

有人可以指出一些好的工作示例吗?

标签: pythonmanifestsetup.py

解决方案


这是最终奏效的解决方案。

我确实记得删除了旧的builddist目录,并且我还确保按照 @jarcobi 的建议删除所有 *.egg-info文件。但是仅仅清除所有过时的文件并不足以解决问题。

最终起作用的是这样编辑setup.py

setup(
    ...
    packages=find_packages(exclude=["*/subdirectory_to_be_EXcluded/*"]),
    # include everything in MANIFEST.IN:
    include_package_data=True, 
    # ...but exclude just these directories */subdirectory_to_be_EXcluded/* from all packages
    exclude_package_data={"": ["*/subdirectory_to_be_EXcluded/*"]},
    ...
)

并因此编辑MANIFEST.IN

...
graft data_files_directory_1/subdirectory_to_be_INcluded
include data_files_directory_1/index.html
graft 

data_files_directory_2/subdirectory_to_be_INincluded 包括 data_files_directory_2/index.html ...

现在我得到了所需的文件树。

补充说明: 我实际上仍然不清楚为什么这些特定更改有效,但我尝试的其他解决方案没有。但是我现在可以继续安装了,所以我想这已经足够好了,我正在解决这个问题。

一个请求:我想向社区中那些编写文档、如何指导或创建教学视频的人提出我的请求,以便通过更多有效的 Cookbook 示例和解释来减少模棱两可和令人困惑的解释。

需要改进的领域:对我来说,我经常感到困惑的一个特定领域是,一份文件说操作员在“包”上操作,而另一份文件表明操作员在“目录”上操作。

混淆更加严重,因为有时“包”一词被用来表示“包含init.py文件的目录”。

“包”这个词的选择似乎表明这些运算符适合使用任何不包含init.py文件的数据目录。

事实上,在某些情况下,运营商似乎仅限于 python 包目录。然而,一些运算符似乎确实可以在任何子目录上工作,即使是那些不包含init.py文件的子目录。*。然而,当“目录”不那么容易误导时,一些作者将它们称为“包”上的操作。

最后,除此之外,“包”有时仅表示由setup.py sdist创建的安装 tar.gz 文件,或由setup.py bdist_wheel创建的.whl文件。

任何可以创建权威解释的人,说明哪些setuptoolsMANIFEST.IN操作符在任何目录上工作(哪些不工作) ,以及哪些只在具有init.py文件的目录上工作。

亲爱的读者,您是我们的英雄吗?

任何尝试进行此类解释并成功避免陷入“包裹”的多种不同含义的混​​乱丛林中的任何人,都将为社区提供非常有价值的服务。

你是那个准备好接受艰巨劳动的英雄吗?


推荐阅读