我正在try 将一个小型Python 3.9应用程序打包到一个.tar.gz软件分发文件(又名"sdist")中.

我的代码有以下 struct :

my-code
  PackageA
    PackageB
      Module1.py
      __init__.py 
    __init__.py
  setup.py

我的setup.py文件如下所示:

from setuptools import find_packages, setup

setup(
    name="my-code",
    version="0.1",
    install_requires=[],
    packages=find_packages(include=["PackageA.PackageB"]),
    include_package_data=True,
    description="My Code"
)


当我运行python setup.py sdist --formats=gztar时,我成功地得到了一个my-code-0.1.tar.gz文件,我可以看到它包含我的.py个文件.

然而,当我运行pip install my-code-0.1.tar.gz时,pip似乎没有编译和部署我的.py个文件.也就是说,当我安装到venv中并在Lib/site-packages目录中查找venv时,我只看到一个名为my_code-0.1-py3.9.egg-info的目录,而我的代码不在其中.try 导入或运行PackageA.PackageB中的模块失败.

我的问题是-Why is my code not built and installed by 100 and how can I fix this?

推荐答案

TL;DR因为find_packages(include=["PackageA.PackageB"])会过滤掉父级PackageA,所以它不包括在安装中.使用

setup(
    packages=find_packages(),
    ...
)

一切都会好起来的.

更详细的解释是,include arg并不意味着"除了find_packages()发现的以外还包括".它的意思是"只包含find_packages()找到的、在include过滤器列表中的包",因此它只能缩小包 Select .比较

$ python -c "from setuptools import find_packages as f; print(f())"
['PackageA', 'PackageA.PackageB']

vs

$ python -c "from setuptools import find_packages as f; print(f(include=['PackageA.PackageB']))"
['PackageA.PackageB']

由于PackageA不包括在内,PackageA/__init__.py将在源代码分发中被省略,从而有效地从PackageA中删除包属性——在tar归档中,它现在将是一个常规目录.运行pip install mydist.tar.gz将无法再找到PackageA,因此PackageA.PackageB也无法找到.因此,不会安装任何设备.setuptools个文档中的Automatic package discovery部分简短地提到了find_packages()includeexclude个参数,但更有用的是函数的docstring:

>>> from setuptools import find_packages
>>> help(find_packages)
find(where='.', exclude=(), include=('*',)) method of builtins.type instance
    Return a list all Python packages found within directory 'where'

    ...

    'include' is a sequence of package names to include.  If it's
    specified, only the named packages will be included.  If it's not
    specified, all found packages will be included.  'include' can contain
    shell style wildcard patterns just like 'exclude'.

Python相关问答推荐

非常奇怪:tzLocal.get_Localzone()基于python3别名的不同输出?

将数据框架与导入的Excel文件一起使用

从numpy数组和参数创建收件箱

如何找到满足各组口罩条件的第一行?

在极中解析带有数字和SI前缀的字符串

重置PD帧中的值

合并与拼接并举

Pandas—MultiIndex Resample—我不想丢失其他索引的信息´

以异步方式填充Pandas 数据帧

如果有2个或3个,则从pandas列中删除空格

分解polars DataFrame列而不重复其他列值

无法使用请求模块从网页上抓取一些产品的名称

如何在Polars中将列表中的新列添加到现有的数据帧中?

迭代工具组合不会输出大于3的序列

删除另一个div中的特定div容器

如何在微调Whisper模型时更改数据集?

如何使用count()获取特定日期之间的项目

运行从Airflow包导入的python文件,需要airflow实例?

简化通用属性的创建

更新-如何与一个我无法使用python获得的按钮进行交互-Selify?