Heroku 上缺少 Python 头文件 (Python.h)

问题描述

我正在尝试将需要一些 C 扩展的 Python 应用程序部署到 Heroku。问题是,当我通过 git push heroku master 将应用程序部署到 Heroku 时,出现以下错误

Counting objects: 9,done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7),done.
Writing objects: 100% (9/9),1.04 KiB | 534.00 KiB/s,done.
Total 9 (delta 3),reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Building on the Heroku-20 stack
remote: -----> Python app detected
remote:  !     Python has released a security update! Please consider upgrading to python-3.7.10
remote:        Learn More: https://devcenter.heroku.com/articles/python-runtimes
remote: -----> Requirements file has been changed,clearing cached dependencies
remote: -----> Installing python-3.7.9
remote: -----> Installing pip 20.1.1,setuptools 47.1.1 and wheel 0.34.2
remote: -----> Installing sqlite3
remote: -----> Installing requirements with pip
remote:        Obtaining file:///tmp/build_003b7c25 (from -r /tmp/build_003b7c25/requirements.txt (line 9))
remote:        Collecting click==7.1.2
remote:          Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
remote:        Collecting Flask==1.1.2
remote:          Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
remote:        Collecting gunicorn==20.0.4
remote:          Downloading gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
remote:        Collecting itsdangerous==1.1.0
remote:          Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
remote:        Collecting Jinja2==2.11.2
remote:          Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
remote:        Collecting MarkupSafe==1.1.1
remote:          Downloading MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl (33 kB)
remote:        Collecting Werkzeug==1.0.1
remote:          Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
remote:        Collecting youtube-dl==2020.12.14
remote:          Downloading youtube_dl-2020.12.14-py2.py3-none-any.whl (1.8 MB)
remote:        Installing collected packages: click,Werkzeug,MarkupSafe,Jinja2,itsdangerous,Flask,gunicorn,youtube-dl,c-rename
remote:          Running setup.py develop for c-rename
remote:            ERROR: Command errored out with exit status 1:
remote:             command: /app/.heroku/python/bin/python -c 'import sys,setuptools,tokenize; sys.argv[0] = '"'"'/tmp/build_003b7c25/setup.py'"'"'; __file__='"'"'/tmp/build_003b7c25/setup.py'"'"';f=getattr(tokenize,'"'"'open'"'"',open)(__file__);code=f.read().replace('"'"'\r\n'"'"','"'"'\n'"'"');f.close();exec(compile(code,__file__,'"'"'exec'"'"'))' develop --no-deps
remote:                 cwd: /tmp/build_003b7c25/
remote:            Complete output (20 lines):
remote:            running develop
remote:            running egg_info
remote:            creating c_rename.egg-info
remote:            writing c_rename.egg-info/PKG-INFO
remote:            writing dependency_links to c_rename.egg-info/dependency_links.txt
remote:            writing top-level names to c_rename.egg-info/top_level.txt
remote:            writing manifest file 'c_rename.egg-info/SOURCES.txt'
remote:            reading manifest file 'c_rename.egg-info/SOURCES.txt'
remote:            writing manifest file 'c_rename.egg-info/SOURCES.txt'
remote:            running build_ext
remote:            building 'c_rename' extension
remote:            creating build
remote:            creating build/temp.linux-x86_64-3.7
remote:            creating build/temp.linux-x86_64-3.7/c_extensions
remote:            gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/app/.heroku/python/include/python3.7m -c c_extensions/rename.c -o build/temp.linux-x86_64-3.7/c_extensions/rename.o
remote:            c_extensions/rename.c:2:10: Fatal error: python3.6m/Python.h: No such file or directory
remote:                2 | #include <python3.6m/Python.h>
remote:                  |          ^~~~~~~~~~~~~~~~~~~~~
remote:            compilation terminated.
remote:            error: command 'gcc' Failed with exit status 1
remote:            ----------------------------------------
remote:        ERROR: Command errored out with exit status 1: /app/.heroku/python/bin/python -c 'import sys,'"'"'exec'"'"'))' develop --no-deps Check the logs for full command output.
remote:  !     Push rejected,Failed to compile Python app.
remote: 
remote:  !     Push Failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to free-music-web.
remote: 
To https://git.heroku.com/free-music-web.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: Failed to push some refs to 'https://git.heroku.com/free-music-web.git'

据我所知,我缺少构建 C 扩展所需的 Python.h 头文件。 我已经试过了 apt install python-devpython-develpython3-dev 等,但都产生相同的输出

Reading package lists... Done
Building dependency tree       
Reading state information... Done
W: Not using locking for read only lock file /var/lib/dpkg/lock-frontend
W: Not using locking for read only lock file /var/lib/dpkg/lock
E: Unable to locate package python-dev

cat /etc/os-release输出如下

NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

现在,我该如何安装 python 头文件? 提前致谢

解决方法

#include <python3.6m/Python.h>

在我看来,这就像一个写得很糟糕的 C 扩展,它被硬编码为只能在“带有 PyMalloc 的 Python 3.6”上工作。由于您使用的是 Python 3.7.9,该路径显然不存在。

通常的做法是

#include <Python.h>

当 setuptools/distutils 构建模块时,它会适当地设置包含路径(您可以看到它是通过输出中的 -I/app/.heroku/python/include/python3.7m 完成的)。

就我个人而言,我对任何对路径进行硬编码的 C 扩展都表示怀疑 - 这是一件很奇怪的事情,它不会让您对其余代码的质量充满信心。也有可能这个扩展只经过测试或设计为在 Python 3.6 上工作,所以不能保证它在 Python 3.7 上工作(通常版本之间没有巨大的兼容性变化,但我们已经知道这个扩展编写者已经做了一些奇怪的决定...)