-
-
Notifications
You must be signed in to change notification settings - Fork 7.8k
[Bug]: matplotlib crashes if _tkinter
doesn't have __file__
#23074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
cc @anntzer |
I don't really have a solution available? If the tkinter symbols are not public, I don't know what we can do... |
This is part of our logic to find at runtime the tk libraries. At a minimum we should not fail in this way (I think just protect it with I'm not sure how much special casing we would take on to support @indygreg , but will definitely consider proposals ! |
(fwiw I don't think we should try to catch this specific case with PyObject_HasAttrString -- next time it'll be the import that fails, or some other python distro that instead sets |
Thanks for filing this @konstin! What's the fundamental requirement here? From the source code it seems to be that matplotlib needs a function pointer / address of Is this functionality critical? If matplotlib could run with these symbols as optional, what's the user impact? Is that an option worth considering? As it stands, teaching python-build-standalone to export these symbols is doable. But the reason the symbols were made private is so they don't collide with an external shared library that some random other Python extension could pull in. See astral-sh/python-build-standalone#114 for more. A hacky compromise here could be to alias these special symbols under a non-standard name so they don't conflict with the official symbols. That requires any C code to be aware of the alternate symbol names. That's a tall ask. But it also might be a fair request since this is the only Python C extension I'm aware of trying to access C symbols from libraries that aren't explicitly in libpython. I think you've just gotten lucky so far that this has managed to largely just work. |
If we do not find these symbols, the user does not get the tkagg backend.
fair, and then catch that in the fallback logic and try the next one? |
Yes (so that basically means we need to raise an ImportError, as that's what the fallback machinery recognizes -- now you've conviced me we do need to do such a wrapping). |
The point of this run-time lookup is so that we do not have to a build-time dependency on tk. I think this is closed by #23089 (we will now gracefully skip the tkagg backend in python-build-standalone case). If you want to support mpl + tkagg @indygreg I think this is something you should handle on your side. As I said above, we will definitely consider reasonable patches if needed. |
This patch is the result of: $ bazel run //tools/python:requirements.update -- --upgrade $ bazel run //tools/python:mirror_pip_packages --config=k8_upstream_python -- --ssh_host software I added special logic to exclude `pygobject` from being fixed with `auditwheel`. For some reason `auditwheel` fixing causes issues at runtime. I suspect it has to do with assumptions that the code makes about files living relative to the path of the .so file, but I'm not sure. Either way, this pulls in the latest matplotlib. In particular, the fix of interest is matplotlib/matplotlib#23074. Unfortunately, this means that the `rules_python` toolchain does not allow for tkagg plots. We'll probably have to use the Gtk runtime as a work around. Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com> Change-Id: I083dc0fcae8315a7a40a351abad3ae2df0031c5d
This patch adds support for using matplotlib plus its Gtk backend with `--config=k8_upstream_python`. Unfortunately, the Tk backend doesn't work because of how Python is packaged. See the following issue for more information: matplotlib/matplotlib#23074 Separately, we need to patch pygobject and matplotlib for various hermeticity reasons. To accomplish this, I've added patching support for wheels downloaded via rules_python. I should have set it up to use annotations (the same mechanism we use for injecting deps), but it was a little cumbersome. Annotations are not set up for using in arguments to repository rules. I instead opted for a separate JSON file. You can find it at `tools/python/patches.json`. You can try the two new example programs: $ bazel run --config=k8_upstream_python //build_tests:matplotlib_example $ bazel run --config=k8_upstream_python //build_tests:pygobject_example Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com> Change-Id: I3c4e8648a8012aa23dedd53610e82d590d1c409d
Adding some extra context for other lost souls. I encountered this issue after switching to a python interpreter provided by bazel's rules_python with a statically linked tkinter. I have run the following code import sys
print(f"interpreter: {sys.executable}")
print("_tkinter" in sys.builtin_module_names)
import tkinter
print(tkinter.TkVersion)
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
|
@driftregion what version of mpl do you have? Post 3.6 I think the failure should be graceful (as if tk is not available). |
@tacaswell mpl version 3.10.0. I'm doing some interactive plotting within a tkinter app, so TkAgg is the only choice of backend afaik. My workaround is to use a different interpreter that references an external |
Ah, you are forcing the use of tk rather than us failing on auto-discovery. In that case we should be failing like this and using a differently built interpreter is your only option (as would be the case if you had a Python build that simply did not include |
Bug summary
In the python-build-standalone cpython distributions,
_tkinter
is doesn't have a separate shared library and therefore also doesn't have a__file__
attribute, causing a crash in matplotlib.Code for reproduction
Actual outcome
Expected outcome
matplotlib works even if _tkinter is not a shared library, maybe with reduced functionality but it shouldn't crash
Additional information
The code that causes this is
matplotlib/src/_tkagg.cpp
Lines 310 to 322 in f25c2d0
I've previously reported this at astral-sh/python-build-standalone#129 where @indygreg noted that "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.".
CC @indygreg
Operating system
ubuntu 20.04
Matplotlib Version
3.5.2
Matplotlib Backend
n/a
Python version
cpython-3.10.4+20220502-x86_64_v3-unknown-linux-gnu-pgo+lto-full
Jupyter version
n/a
Installation
pip
The text was updated successfully, but these errors were encountered: