Python: 为什么 pip install 不从 sdist 部署我的代码?
Python: Why does pip install not deploy my code from sdist?
我正在尝试将小型 Python 3.9 应用程序打包到 .tar.gz
软件分发文件(又名“sdist”)中。
我的代码有这样的结构:
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
文件。 IE。当我安装到 venv
并查看 Lib/site-packages
目录中的 venv
时,我只看到一个名为 my_code-0.1-py3.9.egg-info
的目录,而我的代码不在其中。尝试导入或 运行 我在 PackageA.PackageB
中的模块失败。
我的问题是 - 为什么 pip install
没有构建和安装我的代码,我该如何解决这个问题?
TL;DR 因为 find_packages(include=["PackageA.PackageB"])
会过滤掉父 PackageA
,所以它不包含在安装中。只需使用
setup(
packages=find_packages(),
...
)
会好的。
更长的解释是 include
arg 并不意味着“除了 find_packages()
发现的内容之外还包含”。它的意思是“只包括 find_packages()
在 include
过滤器列表中找到的包”,所以它只能缩小包的选择范围。比较
的输出
$ python -c "from setuptools import find_packages as f; print(f())"
['PackageA', 'PackageA.PackageB']
对
$ 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()
的 include
和 exclude
参数的简短提及,但 IMO 更有帮助的是函数的文档字符串:
>>> 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 3.9 应用程序打包到 .tar.gz
软件分发文件(又名“sdist”)中。
我的代码有这样的结构:
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
文件。 IE。当我安装到 venv
并查看 Lib/site-packages
目录中的 venv
时,我只看到一个名为 my_code-0.1-py3.9.egg-info
的目录,而我的代码不在其中。尝试导入或 运行 我在 PackageA.PackageB
中的模块失败。
我的问题是 - 为什么 pip install
没有构建和安装我的代码,我该如何解决这个问题?
TL;DR 因为 find_packages(include=["PackageA.PackageB"])
会过滤掉父 PackageA
,所以它不包含在安装中。只需使用
setup(
packages=find_packages(),
...
)
会好的。
更长的解释是 include
arg 并不意味着“除了 find_packages()
发现的内容之外还包含”。它的意思是“只包括 find_packages()
在 include
过滤器列表中找到的包”,所以它只能缩小包的选择范围。比较
$ python -c "from setuptools import find_packages as f; print(f())"
['PackageA', 'PackageA.PackageB']
对
$ 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()
的 include
和 exclude
参数的简短提及,但 IMO 更有帮助的是函数的文档字符串:
>>> 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'.