Skip to content

Error when installing PyICU on Heroku

I am trying to deploy my Python app on Heroku, but have been unsuccessful owing to PyICU not installing correctly. I've confirmed that this is the only issue with my deployment; when I remove PyICU from my requirements file, everything works. But my site can't work without it. I've also tried downloading the .whl file and then adding that to my requirements file, but then I get another error:

ERROR: PyICU-2.7.3-cp38-cp38m-win_amd64.whl is not a supported wheel on this platform. I don't understand why - it's the correct Python and os version.

Here are the relevant excerpts from the build log:

-----> Building on the Heroku-20 stack
-----> Using buildpack: heroku/python
-----> Python app detected
-----> Using Python version specified in runtime.txt
-----> Installing python-3.8.10
-----> Installing pip 20.2.4, setuptools 47.1.1 and wheel 0.36.2
-----> Installing SQLite3
-----> Installing requirements with pip
       ...
         Building wheel for PyICU (setup.py): started
         Building wheel for PyICU (setup.py): finished with status 'error'
         ERROR: Command errored out with exit status 1:
          command: /app/.heroku/python/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"'; __file__='"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-zeqs7m46
              cwd: /tmp/pip-install-e4xp9bv_/pyicu/
         Complete output (90 lines):
         (running 'icu-config --version')
         (running 'pkg-config --modversion icu-i18n')
         
         Building PyICU 2.4.3 for ICU 66.1
         
         (running 'icu-config --cxxflags --cppflags')
         Could not configure CFLAGS with icu-config
         (running 'pkg-config --cflags icu-i18n')
         (running 'icu-config --ldflags')
         Could not configure LFLAGS with icu-config
         (running 'pkg-config --libs icu-i18n')
         Adding LFLAGS="-licui18n -licuuc -licudata" from /usr/bin/pkg-config
         running bdist_wheel
         running build
         running build_py
         creating build
         creating build/lib.linux-x86_64-3.7
         copying PyICU.py -> build/lib.linux-x86_64-3.7
         creating build/lib.linux-x86_64-3.7/icu
         copying icu/__init__.py -> build/lib.linux-x86_64-3.7/icu
         running build_ext
         building '_icu' extension
         creating build/temp.linux-x86_64-3.7
         gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/app/.heroku/python/include/python3.7m -c _icu.cpp -o build/temp.linux-x86_64-3.7/_icu.o -DPYICU_VER="2.4.3"
         In file included from /usr/include/c++/9/clocale:42,
                          from /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:41,
                          from /usr/include/c++/9/bits/localefwd.h:40,
                          from /usr/include/c++/9/string:43,
                          from /usr/include/unicode/std_string.h:37,
                          from /usr/include/unicode/unistr.h:38,
                          from common.h:106,
                          from _icu.cpp:27:
         ./locale.h:29:23: error: ‘Locale’ was not declared in this scope; did you mean ‘locale_t’?
            29 | PyObject *wrap_Locale(Locale *locale, int flags);
               |                       ^~~~~~
               |                       locale_t
         ./locale.h:29:31: error: ‘locale’ was not declared in this scope; did you mean ‘locale_t’?
            29 | PyObject *wrap_Locale(Locale *locale, int flags);
               |                               ^~~~~~
               |                               locale_t
         ./locale.h:29:39: error: expected primary-expression before ‘int’
            29 | PyObject *wrap_Locale(Locale *locale, int flags);
               |                                       ^~~
         ./locale.h:29:48: error: expression list treated as compound expression in initializer [-fpermissive]
            29 | PyObject *wrap_Locale(Locale *locale, int flags);
               |                                                ^
         ./locale.h:30:29: error: ‘Locale’ does not name a type; did you mean ‘locale_t’?
            30 | PyObject *wrap_Locale(const Locale &locale);
               |                             ^~~~~~
               |                             locale_t
         ./locale.h:30:43: error: ‘PyObject* wrap_Locale(const int&)’ redeclared as different kind of entity
            30 | PyObject *wrap_Locale(const Locale &locale);
               |                                           ^
         ./locale.h:29:11: note: previous declaration ‘PyObject* wrap_Locale’
            29 | PyObject *wrap_Locale(Locale *locale, int flags);
               |           ^~~~~~~~~~~
         In file included from /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:41,
                          from /usr/include/c++/9/bits/localefwd.h:40,
                          from /usr/include/c++/9/string:43,
                          from /usr/include/unicode/std_string.h:37,
                          from /usr/include/unicode/unistr.h:38,
                          from common.h:106,
                          from _icu.cpp:27:
         /usr/include/c++/9/clocale:53:11: error: ‘::lconv’ has not been declared
            53 |   using ::lconv;
               |           ^~~~~
         /usr/include/c++/9/clocale:54:11: error: ‘::setlocale’ has not been declared
            54 |   using ::setlocale;
               |           ^~~~~~~~~
         /usr/include/c++/9/clocale:55:11: error: ‘::localeconv’ has not been declared
            55 |   using ::localeconv;
               |           ^~~~~~~~~~
         In file included from /usr/include/c++/9/bits/localefwd.h:40,
                          from /usr/include/c++/9/string:43,
                          from /usr/include/unicode/std_string.h:37,
                          from /usr/include/unicode/unistr.h:38,
                          from common.h:106,
                          from _icu.cpp:27:
         /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:52:23: error: ‘uselocale’ was not declared in this scope; did you mean ‘u_fsetlocale’?
            52 |   extern "C" __typeof(uselocale) __uselocale;
               |                       ^~~~~~~~~
               |                       u_fsetlocale
         /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h: In function ‘int std::__convert_from_v(__locale_struct* const&, char*, int, const char*, ...)’:
         /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:75:53: error: ‘__gnu_cxx::__uselocale’ cannot be used as a function
            75 |     __c_locale __old = __gnu_cxx::__uselocale(__cloc);
               |                                                     ^
         /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:100:33: error: ‘__gnu_cxx::__uselocale’ cannot be used as a function
           100 |     __gnu_cxx::__uselocale(__old);
               |                                 ^
         error: command 'gcc' failed with exit status 1
         ----------------------------------------
         ERROR: Failed building wheel for PyICU
         Running setup.py clean for PyICU
       
           Running setup.py install for PyICU: started
           Running setup.py install for PyICU: finished with status 'error'
           ERROR: Command errored out with exit status 1:
            command: /app/.heroku/python/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"'; __file__='"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-bdqgdfr6/install-record.txt --single-version-externally-managed --compile --install-headers /app/.heroku/python/include/python3.7m/PyICU
                cwd: /tmp/pip-install-e4xp9bv_/pyicu/
           Complete output (90 lines):
           (running 'icu-config --version')
           (running 'pkg-config --modversion icu-i18n')
           
           Building PyICU 2.4.3 for ICU 66.1
           
           (running 'icu-config --cxxflags --cppflags')
           Could not configure CFLAGS with icu-config
           (running 'pkg-config --cflags icu-i18n')
           (running 'icu-config --ldflags')
           Could not configure LFLAGS with icu-config
           (running 'pkg-config --libs icu-i18n')
           Adding LFLAGS="-licui18n -licuuc -licudata" from /usr/bin/pkg-config
           running install
           running build
           running build_py
           creating build
           creating build/lib.linux-x86_64-3.7
           copying PyICU.py -> build/lib.linux-x86_64-3.7
           creating build/lib.linux-x86_64-3.7/icu
           copying icu/__init__.py -> build/lib.linux-x86_64-3.7/icu
           running build_ext
           building '_icu' extension
           creating build/temp.linux-x86_64-3.7
           gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/app/.heroku/python/include/python3.7m -c _icu.cpp -o build/temp.linux-x86_64-3.7/_icu.o -DPYICU_VER="2.4.3"
           In file included from /usr/include/c++/9/clocale:42,
                            from /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:41,
                            from /usr/include/c++/9/bits/localefwd.h:40,
                            from /usr/include/c++/9/string:43,
                            from /usr/include/unicode/std_string.h:37,
                            from /usr/include/unicode/unistr.h:38,
                            from common.h:106,
                            from _icu.cpp:27:
           ./locale.h:29:23: error: ‘Locale’ was not declared in this scope; did you mean ‘locale_t’?
              29 | PyObject *wrap_Locale(Locale *locale, int flags);
                 |                       ^~~~~~
                 |                       locale_t
           ./locale.h:29:31: error: ‘locale’ was not declared in this scope; did you mean ‘locale_t’?
              29 | PyObject *wrap_Locale(Locale *locale, int flags);
                 |                               ^~~~~~
                 |                               locale_t
           ./locale.h:29:39: error: expected primary-expression before ‘int’
              29 | PyObject *wrap_Locale(Locale *locale, int flags);
                 |                                       ^~~
           ./locale.h:29:48: error: expression list treated as compound expression in initializer [-fpermissive]
              29 | PyObject *wrap_Locale(Locale *locale, int flags);
                 |                                                ^
           ./locale.h:30:29: error: ‘Locale’ does not name a type; did you mean ‘locale_t’?
              30 | PyObject *wrap_Locale(const Locale &locale);
                 |                             ^~~~~~
                 |                             locale_t
           ./locale.h:30:43: error: ‘PyObject* wrap_Locale(const int&)’ redeclared as different kind of entity
              30 | PyObject *wrap_Locale(const Locale &locale);
                 |                                           ^
           ./locale.h:29:11: note: previous declaration ‘PyObject* wrap_Locale’
              29 | PyObject *wrap_Locale(Locale *locale, int flags);
                 |           ^~~~~~~~~~~
           In file included from /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:41,
                            from /usr/include/c++/9/bits/localefwd.h:40,
                            from /usr/include/c++/9/string:43,
                            from /usr/include/unicode/std_string.h:37,
                            from /usr/include/unicode/unistr.h:38,
                            from common.h:106,
                            from _icu.cpp:27:
           /usr/include/c++/9/clocale:53:11: error: ‘::lconv’ has not been declared
              53 |   using ::lconv;
                 |           ^~~~~
           /usr/include/c++/9/clocale:54:11: error: ‘::setlocale’ has not been declared
              54 |   using ::setlocale;
                 |           ^~~~~~~~~
           /usr/include/c++/9/clocale:55:11: error: ‘::localeconv’ has not been declared
              55 |   using ::localeconv;
                 |           ^~~~~~~~~~
           In file included from /usr/include/c++/9/bits/localefwd.h:40,
                            from /usr/include/c++/9/string:43,
                            from /usr/include/unicode/std_string.h:37,
                            from /usr/include/unicode/unistr.h:38,
                            from common.h:106,
                            from _icu.cpp:27:
           /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:52:23: error: ‘uselocale’ was not declared in this scope; did you mean ‘u_fsetlocale’?
              52 |   extern "C" __typeof(uselocale) __uselocale;
                 |                       ^~~~~~~~~
                 |                       u_fsetlocale
           /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h: In function ‘int std::__convert_from_v(__locale_struct* const&, char*, int, const char*, ...)’:
           /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:75:53: error: ‘__gnu_cxx::__uselocale’ cannot be used as a function
              75 |     __c_locale __old = __gnu_cxx::__uselocale(__cloc);
                 |                                                     ^
           /usr/include/x86_64-linux-gnu/c++/9/bits/c++locale.h:100:33: error: ‘__gnu_cxx::__uselocale’ cannot be used as a function
             100 |     __gnu_cxx::__uselocale(__old);
                 |                                 ^
           error: command 'gcc' failed with exit status 1
           ----------------------------------------
       ERROR: Command errored out with exit status 1: /app/.heroku/python/bin/python -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"'; __file__='"'"'/tmp/pip-install-e4xp9bv_/pyicu/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-bdqgdfr6/install-record.txt --single-version-externally-managed --compile --install-headers /app/.heroku/python/include/python3.7m/PyICU Check the logs for full command output.
 !     Push rejected, failed to compile Python app.
 !     Push failed

How should I go about correctly installing PyICU on Heroku so my app can work correctly?