Closed konstin closed 2 years ago
This is similar to https://github.com/indygreg/PyOxidizer/issues/69.
My general response to this is: __file__
is documented as optional by Python: any code requiring __file__
is bugged and should instead be using a mechanism described in https://pyoxidizer.readthedocs.io/en/pyoxidizer-0.20.0/oxidized_importer_resource_files.html.
But this case is more complex than simple resource file handling. It looks like matplotlib is opening the library in order for C code to get a handle on tk function symbols. 🤯
This is highly unorthodox, as it assumes C extensions are standalone libraries (an implementation detail of the Python distribution) and that said libraries export tk symbols (again, an implementation detail).
I'll likely need to converse with a matplotlib developer on how to best support this. I would like to have a compatibility story here, as matplotlib is a popular package and I'd like it to be supported.
fixed in matplotlib 🎉
Basic matplotlib usage such as
import matplotlib.pyplot as plt; plt.plot(list(range(10)), list(range(10)))
crashes withmodule '_tkinter' has no attribute '__file__'
.On system python, _tkinter is a shared library (
/usr/lib/python3.8/lib-dynload/_tkinter.cpython-38-x86_64-linux-gnu.so
), while in these python builds it's a builtin module which does not have__file__
. matplotlib expects tkinter to be an .so it can load: https://github.com/matplotlib/matplotlib/blob/f25c2d025fa8f70d6688e7acf4b85e4eb7590299/src/_tkagg.cpp#L310-L322To reproduce:
Running
TCL_LIBRARY="$(pwd)/python/install/lib/tcl8.6" venv/bin/python -c "import matplotlib.pyplot as plt; plt.plot(list(range(10)), list(range(10)))"
instead as suggested by the docs makes no difference.EDIT: I'm mainly using the standalone builds by libloading
libpython.so
and launching one of the very high level c api commands, so i'd be happy about any workaround that works with libloading or importlib hackery from rust.