我已经发布了一个 PyPI 包,它需要一些额外的 Apt 包,因此我的 Github 存储库中有一个
setup.sh
,我想与 pip install mypackage
的安装过程一起执行(即,每当用户运行 pip install mypackage
时)应在安装过程中运行 shell 脚本。)
我让我的
setup.py
使用这样的 cmdclass 参数
from setuptools import setup, find_packages
from setuptools.command.install import install
import subprocess
import codecs
import os
class CustomInstall(install):
def run(self):
subprocess.check_call("bash setup.sh", shell=True)
install.run(self)
with open('requirements.txt') as f:
requirements = f.read().splitlines()
setup(
...
cmdclass={'install': CustomInstall}, install_requires=requirements,
...
)
当我通常使用
python setup.py sdist bdist_wheel
构建它时,Custominstall
类运行良好,但在 pip 安装过程中它会忽略 Custominstall
类。
最后我找到了 this stackoverflow 线程,从中我了解到我只需要运行
python setup.py sdist
我就这么做了,但现在我得到了
with open('requirements.txt') as f:
^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
我做错了什么?是不是路径不正确?需求文件位于我的存储库的父文件夹中(不在任何其他文件夹中)
直接的问题是
pip
进程运行在调用用户所在的目录中。也许另请参阅当前工作目录到底是什么?
解决这个问题的方法是如何获取当前正在执行的Python文件的路径和名称?基本上,检查
__file__
并从中派生出您想要访问的目录。
但是,你的问题的前提似乎存在严重缺陷。您应该声明对您所依赖的任何 Python 包的依赖关系,并让
pip
从那里获取它;或者,创建一个 Debian 软件包,然后根据其他 Debian 软件包声明所有依赖项。 (当然,你可以两者都做。当然,在后一种情况下,你可能也应该做前者,这样你的软件包就可以安装在非 Debian 平台上。)
您还没有告诉我们您的软件包将依赖哪些软件包,因此我们只能用最广泛的术语来表达这一点。假设您的套餐取决于
requests
和 beautifulsoup4
。然后你的 setup.py
应该声明这些依赖关系:
setup(
...
install_requires=["requests", "beautifulsoup4"],
...
)
为了方便起见,你也可以在requirements.txt
中声明这些,但是这个文件在Python打包中没有正式的作用。您的依赖项需要在
setup.py
中声明(或者对于现代包,肯定更喜欢
pyproject.toml
或
setup.cfg
)。如果其中一些依赖项可以通过操作系统包管理器来实现,那么为了方便起见提供另一种安装机制是严格可选的,但这是一个很好的附加组件。你的包脚本不应该依赖于此(但也许反之亦然)。
#!/bin/sh
apt-get install -y python3-requests python3-bs4
(也许还注意到 Debian 软件包通常与相应的 Python 软件包具有不同的名称。这很麻烦,但基本上是不可避免的。)