这个问题几乎是不言自明的。我有一个 .zip 包依赖项,需要将其包含在 python 包安装中。那么如何在我的 setup.py
中包含这个本地依赖项呢?我有 install_requires
但这会从 PyPI 加载我的依赖包,这在本例中不是我想要的。
我的项目中最相关的文件的结构如下:
myproject
|- setup.py
|- mypackage
|- __init__.py
|- vendor
|- __init__.py
|- dependencies
|- StreamingDataReader.zip
然后我尝试...
include_package_data=True,
package_data={
'StreamingDataReader': ['mypackage/vendor/dependencies/StreamingDataReader.zip'],
}
...没有成功。我的代码仍然无法找到该包:ImportError:没有名为“StreamingDataReader”的模块
最佳答案
这是一个老问题,但我有话要说,所以我发帖。
这里有两个不同的问题。首先是 zip 文件需要包含在您的发行版中。为此,请按照您的预期使用package_data
,但您需要为您的包指定您想要在其中包含哪些数据。您可以按如下方式执行此操作:
package_data= {"mypackage": ["vendor/dependencies/StreamingDataReader.zip"]}
不要同时使用include_package_data
;这会在 MANIFEST.in 中查找数据并忽略 package_data 参数。 setuptools
的设计确实很糟糕。对于二进制和源代码打包,我发现的最佳建议是确保所有数据都位于包目录中,并仅使用 package_data
。
您的第二个问题是您希望能够导入StreamingDataReader
。不幸的是,据我所知,没有办法使用 pip install
来使用 pip
来做到这一点,而没有其他方法。您有两个明显的选择:
(1) 您可以包含 requirements.txt
文件并将 zip 文件列为要求,并让人们提前执行 pip install -rrequirements.txt
pip install
您的项目。您的 requirements.txt
文件如下所示:
./mypackage/vendor/dependencies/StreamingDataReader.zip
但是要求用户这样做可能会带来难以接受的痛苦,而且对于任何依赖您的软件包的人来说都不起作用。
(2) 蛮力。只需使用zipfile
来扩展包即可。
我假设 StreamingDataReader.zip
文件是一个 Python 包 zip,在顶层有一个目录(我假设它名为 StreamingDataReader
)其中包含一个顶级 setup.py
和一个子目录,我们假设它名为 StreamingDataReader
,其中包含实际的软件。换句话说,我假设你的 zip 看起来像这样:
StreamingDataReader/
StreamingDataReader/setup.py
StreamingDataReader/StreamingDataReader/__init__.py
等等。我还假设您正在运行 Python 3.3 或更高版本,其中不再需要 __init__.py
文件来创建包层次结构。 (在以前的版本中,您需要操作 sys.path
,这不是什么大问题,但现在更容易了。)因此 vendor/__init__.py
是不为您做任何工作。
顺便说一下,这个解决方案假设运行您的软件的人对包含该软件的目录具有写入权限。
将以下内容放入顶级 __init__.py
中:
import zipfile, pathlib
_mpath = pathlib.Path(__file__).resolve().parent
_sdrDir = mpath.joinpath("vendor", "dependencies", "StreamingDataReader")
if not _sdrDir.is_dir():
_z = zipfile.Zipfile(sdrDir.parent.joinpath("StreamingDataReader.zip"), "r")
_z.extractall(sdrDir.parent)
_z.close()
del _z
# cleanup
del _mpath
del _sdrDir
一旦你这样做了,你就可以
import mypackage.vendor.dependencies.StreamingDataReader.StreamingDataReader as StreamingDataReader
无论你想去哪里。
最后,在您的包的 setup.py
中,您需要包含 StreamingDataReader
的依赖项,因为您不使用 pip
递归安装它。
是的,工作量很大。但据我所知,Python 安装机制中没有任何工具可以从您自己提供的 zip 文件安装包。
关于Python setup.py : how to include local package dependency?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49818553/