Description
Bug summary
If you use a FIPS (Federal Information Processing Standards) compliant Python install, then you cannot use pyplot.show
to display a plot with plt.rcParams['text.usetex'] = True
due to a hashlib.md5
call in texmanager.py.
This is similar to #18192 (and much of this report is modeled off of that)
There are 3 places in the code that seem to still use hashlib.md5
:
matplotlib/lib/matplotlib/texmanager.py
Line 171 in 24bb51c
There probably isn't a great reason not to replace md5 with sha256 (or something else) in these locations.
Code for reproduction
The big requirement here is a FIPS compliant system or at least a Python install compiled to be FIPS compliant. Then the following code will reproduce the error.
To reproduce,
- Run
sudo fips-mode-setup --enable && sudo reboot
(there may be other methods) - After the reboot I confirmed FIPS mode had been enabled by running
fips-mode-setup --check
and it returned FIPS mode is enabled. python3 -m venv .venv
./.venv/bin/python -m pip install matplotlib==3.10.0
./.venv/bin/python fips_error.py
. The contents offips_error.py
is listed below.
import matplotlib.pyplot as plt
plt.rcParams['text.usetex'] = True
fig, ax = plt.subplots()
plt.text(0, 0, r'$\hat{\mathbf{x}}$')
plt.show()
Actual outcome
$ python fips_error.py
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib64/python3.11/tkinter/__init__.py", line 1967, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.11/tkinter/__init__.py", line 861, in callit
func(*args)
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/_backend_tk.py", line 274, in idle_draw
self.draw()
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_tkagg.py", line 10, in draw
super().draw()
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 382, in draw
self.figure.draw(self.renderer)
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 94, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/figure.py", line 3257, in draw
mimage._draw_list_compositing_images(
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/image.py", line 134, in _draw_list_compositing_images
a.draw(renderer)
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axes/_base.py", line 3181, in draw
mimage._draw_list_compositing_images(
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/image.py", line 134, in _draw_list_compositing_images
a.draw(renderer)
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1416, in draw
tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1343, in _get_ticklabel_bboxes
return ([tick.label1.get_window_extent(renderer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/axis.py", line 1343, in <listcomp>
return ([tick.label1.get_window_extent(renderer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 969, in get_window_extent
bbox, info, descent = self._get_layout(self._renderer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 373, in _get_layout
_, lp_h, lp_d = _get_text_metrics_with_cache(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 69, in _get_text_metrics_with_cache
return _get_text_metrics_with_cache_impl(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/text.py", line 77, in _get_text_metrics_with_cache_impl
return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backends/backend_agg.py", line 211, in get_text_width_height_descent
return super().get_text_width_height_descent(s, prop, ismath)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/backend_bases.py", line 566, in get_text_width_height_descent
return self.get_texmanager().get_text_width_height_descent(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 360, in get_text_width_height_descent
dvifile = cls.make_dvi(tex, fontsize)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 276, in make_dvi
basefile = cls.get_basefile(tex, fontsize)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/data/users/ktm/matplotlib_test/.venv/lib64/python3.11/site-packages/matplotlib/texmanager.py", line 171, in get_basefile
filehash = hashlib.md5(src.encode('utf-8')).hexdigest()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS
Expected outcome
No exception related to FIPS and the plot is created.
Additional information
$ .venv/bin/python -m pip list
Package Version
--------------- -----------
contourpy 1.3.1
cycler 0.12.1
fonttools 4.56.0
kiwisolver 1.4.8
matplotlib 3.10.0
numpy 2.2.2
packaging 24.2
pillow 11.1.0
pip 22.3.1
pyparsing 3.2.1
python-dateutil 2.9.0.post0
setuptools 65.5.1
six 1.17.0
Operating system
RHEL 8.10 (with FIPS enabled)
Matplotlib Version
3.10.0
Matplotlib Backend
tkagg
Python version
Python 3.11.9