quaint-painting-55375
03/25/2025, 10:22 PM___________ ERROR collecting src/lumos_expression/_evaluator_test.py ___________
ImportError while importing test module 'backend/python/libs/lumos_expression/src/lumos_expression/_evaluator_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Users/florian/.pyenv/versions/3.10.6/lib/python3.10/importlib/__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/ddtrace/internal/module.py:309: in _exec_module
self.loader.exec_module(module)
backend/python/libs/lumos_expression/src/lumos_expression/__init__.py:2: in <module>
from ._evaluator import ExpressionEvaluation, ExpressionInput, LumosExpressionClient
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/ddtrace/internal/module.py:309: in _exec_module
self.loader.exec_module(module)
backend/python/libs/lumos_expression/src/lumos_expression/_evaluator.py:10: in <module>
from ._environment import DEFAULT_TRANSLITERATOR_IDENTIFIER, ENVIRONMENT_SINGLETON, transliterate
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/ddtrace/internal/module.py:309: in _exec_module
self.loader.exec_module(module)
backend/python/libs/lumos_expression/src/lumos_expression/_environment.py:1: in <module>
import icu
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/ddtrace/internal/module.py:309: in _exec_module
self.loader.exec_module(module)
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/icu/__init__.py:37: in <module>
from ._icu_ import *
/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/ddtrace/internal/module.py:248: in _create_module
return self.loader.create_module(spec)
E ImportError: dlopen(/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/icu/_icu_.cpython-310-darwin.so, 0x0002): symbol not found in flat namespace '__ZN6icu_7718AnnualTimeZoneRule8MAX_YEARE'
When I compile this package locally with pip directly I am able to use it by doing ICU_VERSION=77 LDFLAGS=$(brew --prefix icu4c)/lib CPPFLAGS=$(brew --prefix icu4c)/include pip install pyicu and I am achieving the same ability to build with pex when running pants test by passing these variables through subprocess-environment.env_vars :
[subprocess-environment]
env_vars = [
"ICU_VERSION",
"LDFLAGS",
"CPPFLAGS",
"PKG_CONFIG_PATH",
]
I am a bit stuck on debugging at this point, I can't figure out how to get pex to output detailed logs so I can see exactly how the icu lib is being compiled. I tried pants -ltrace test but it did not show me the underlying logs when pex was building the environment. Does anyone have ideas on where to go next?
For reference when I pip install with -vvv flag I see the following output:
Building PyICU 2.15 for ICU 77 (max ICU major version supported: 77)
running bdist_wheel
running build
running build_py
creating build/lib.macosx-15.1-arm64-cpython-310/icu
copying py/icu/__init__.py -> build/lib.macosx-15.1-arm64-cpython-310/icu
running build_ext
building 'icu._icu_' extension
creating build/temp.macosx-15.1-arm64-cpython-310
clang++ -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -I/opt/homebrew/opt/icu4c@77/include -I/Users/florian/code/lumos/.direnv/python-3.10/include -I/Users/florian/.pyenv/versions/3.10.6/include/python3.10 -c _icu_.cpp -o build/temp.macosx-15.1-arm64-cpython-310/_icu_.o -std=c++17 -DPYICU_VER=\"2.15\" -DPYICU_ICU_MAX_VER=\"77\"
And I was hoping to compare the output from pex if I could get any visibility into itelegant-florist-94385
03/25/2025, 10:56 PMpants --keep-sandboxes=always package :: and look for an output saying something about a temp directory, probably something like /tmp/pants-sandbox-asdhkh
In this sandbox, there will be a __run.sh file which is the exact command run by pants. (and the rest of the sandbox is the dependencies used in the job). You can inspect this file, tweak it (eg. to add verbosity, test options, etc.) and run it yourself to experiment. If you can narrow down what changes need to be made there, you can work backward to translate them to pants optionsquaint-painting-55375
03/26/2025, 8:38 AM--manylinux flag which is creating an isolated build context that strips headers and prevents ICU from dynamically linking.
Given that, what are my options? Can I change the flags passed to pex when it builds? Is there some other way to link the wheel I built locally instead of pex building it?elegant-florist-94385
03/26/2025, 9:51 AMhappy-kitchen-89482
03/26/2025, 5:44 PMsubprocess-environment.env_vars ?quaint-painting-55375
03/26/2025, 6:59 PMsubprocess-environment.env_vars to provide the ICU_VERSION and CPPFLAGS / LDFLAGS, but once built, I cannot run pants test on the built environment. The error I get is:
E ImportError: dlopen(/Users/florian/.cache/pants/named_caches/pex_root/venvs/1/s/1af2c70d/venv/lib/python3.10/site-packages/icu/_icu_.cpython-310-darwin.so, 0x0002): symbol not found in flat namespace '__ZN6icu_7718AnnualTimeZoneRule8MAX_YEARE'
My two hypotheses were:
• Pex is building with the --manylinux flag which strips out headers that are necessary
• Pants is building a standalone python version in a hermetic way which is preventing it from linking out to shared libraries for ICU
I am not sure if they are right, but that is what I am operating on. Given that this is what I have tried:
• get pants to not use a hermetic standalone python build and use the one on my path instead (pyenv) but I was not able to figure out how to do this
• remove the --manylinux flag from pex when building the deps, but I was not able to figure out hgow to do this
• prebuild the wheel and link it so it does not need to build it, this was successful but I got the same error, this led me to believe it wasn't an issue with building the wheel, but with the python version I am running against
• provide a static version of pyicu where all the shared libraries are statically linked and embedded so it does not need to rely on shared libraries -- haven't tried this yethappy-kitchen-89482
03/26/2025, 10:24 PM-L and -I in the variable settings above?)happy-kitchen-89482
03/27/2025, 1:20 AMpip alone:
$ mkdir /tmp/venv && cd /tmp/venv && python3.11 -m venv . && source ./bin/activate
$ ICU_VERSION=77 LDFLAGS=-L$(brew --prefix icu4c)/lib CPPFLAGS=-I$(brew --prefix icu4c)/include pip install PyICU
Collecting PyICU
...
Installing collected packages: PyICU
Successfully installed PyICU-2.15
$ python -c "from icu import UnicodeString"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/private/tmp/venv/lib/python3.11/site-packages/icu/__init__.py", line 37, in <module>
from ._icu_ import *
ImportError: dlopen(/private/tmp/venv/lib/python3.11/site-packages/icu/_icu_.cpython-311-darwin.so, 0x0002): symbol not found in flat namespace '__ZN6icu_7718AnnualTimeZoneRule8MAX_YEARE'happy-kitchen-89482
03/27/2025, 3:24 AMpip via the instructions at https://gitlab.pyicu.org/main/pyicu#installing-pyicuhappy-kitchen-89482
03/27/2025, 3:24 AMhappy-kitchen-89482
03/27/2025, 3:24 AM$ export PATH="$(brew --prefix)/opt/icu4c/bin:$(brew --prefix)/opt/icu4c/sbin:$PATH"
$ export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$(brew --prefix)/opt/icu4c/lib/pkgconfig"
$ pip install --no-binary=:pyicu: --no-cache-dir pyicu
...
$ DYLD_LIBRARY_PATH="$(brew --prefix icu4c)/lib" python -c "from icu import UnicodeString"happy-kitchen-89482
03/27/2025, 3:25 AM[subprocess-environment].env_vars and [test].extra_env_varshappy-kitchen-89482
03/27/2025, 3:25 AMquaint-painting-55375
03/27/2025, 2:29 PMPKG_CONFIG_PATH , was it the --no-binary or was it the DYLD_LIBRARY_PATH ? Or some combination. Anyways -- interestingly today I was able to get it working by symlinking icu (brew "icu4c@77", link: :force) and then pants and pex were able to build it without issue and run tests without the symbol error. I think symlinking did something similar to the DYLD_LIBRARY_PATH by making sure that it knew where to look for the shared objects?quaint-painting-55375
03/27/2025, 2:29 PMhappy-kitchen-89482
03/27/2025, 6:06 PMPKG_CONFIG_PATH at pex build time and DYLD_LIBRARY_PATH at test runtime (so both of those at Pants runtime)happy-kitchen-89482
03/27/2025, 6:07 PM--no-binary isn’t important, since there’s no prebuilt wheelhappy-kitchen-89482
03/27/2025, 6:08 PMhappy-kitchen-89482
03/27/2025, 6:08 PM