Skip to content
Advertisement

Missing Python headers (Python.h) on Heroku

I’m trying to deploy to Heroku a Python application which requires some C extensions. The problem is that when I deploy the app to Heroku via git push heroku master I get the following error:

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('"'"'rn'"'"', '"'"'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, 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('"'"'rn'"'"', '"'"'n'"'"');f.close();exec(compile(code, __file__, '"'"'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'

From what I understand, I’m missing the Python.h header file, which is required to build my C extension. I’ve already tried apt install python-dev, python-devel, python3-dev and so on, but all resulting in the same output:

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

The output of cat /etc/os-release is the following

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

Now, how do I install the python headers? Thanks in advance

Advertisement

Answer

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

This looks to me like a badly-written C extension which is hardcoded to only work on “Python 3.6 with PyMalloc”. Since you’re using Python 3.7.9 the path obviously doesn’t exist.

The usual approach is to

#include <Python.h>

When setuptools/distutils builds a module it sets the include path appropriately (you can see that it’s done this with -I/app/.heroku/python/include/python3.7m in your output).

Personally I’d have my doubts about any C extension that hardcodes the paths like this – it’s such an odd thing to do that it doesn’t leave you with much faith in the quality of the rest of the code. It’s also likely that this extension has only been tested or designed to work on Python 3.6, so there’s no guarantee it works on Python 3.7 (generally there aren’t huge compatibility changes between versions, but then we already know that this extension writer has made some odd decisions…)

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement