8000 Re-fix exception caching in dviread. · matplotlib/matplotlib@fbd78fe · GitHub
[go: up one dir, main page]

Skip to content

Commit fbd78fe

Browse files
committed
Re-fix exception caching in dviread.
The original solution using with_traceback didn't actually work because with_traceback doesn't return a new exception instance but rather modifies the original one in place, and the traceback will then be attached to it by the raise statement. Instead, we actually need to build a new instance, so reuse the _ExceptionProxy machinery from font_manager (slightly expanded).
1 parent bb68469 commit fbd78fe

File tree

3 files changed

+18
-12
lines changed

3 files changed

+18
-12
lines changed

lib/matplotlib/cbook.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@
3232
from matplotlib import _api, _c_internal_utils
3333

3434

35+
class _ExceptionProxy:
36+
def __init__(self, cls, *args):
37+
self._cls = cls
38+
self._args = args
39+
40+
def exception(self):
41+
return self._cls(*self._args)
42+
43+
3544
def _get_running_interactive_framework():
3645
"""
3746
Return the interactive framework whose event loop is currently running, if

lib/matplotlib/dviread.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def _read(self):
340340
byte = self.file.read(1)[0]
341341
self._dtable[byte](self, byte)
342342
if self._missing_font:
343-
raise self._missing_font
343+
raise self._missing_font.exception()
344344
name = self._dtable[byte].__name__
345345
if name == "_push":
346346
down_stack.append(down_stack[-1])
@@ -368,14 +368,14 @@ def _read_arg(self, nbytes, signed=False):
368368
@_dispatch(min=0, max=127, state=_dvistate.inpage)
369369
def _set_char_immediate(self, char):
370370
self._put_char_real(char)
371-
if isinstance(self.fonts[self.f], FileNotFoundError):
371+
if isinstance(self.fonts[self.f], cbook._ExceptionProxy):
372372
return
373373
self.h += self.fonts[self.f]._width_of(char)
374374

375375
@_dispatch(min=128, max=131, state=_dvistate.inpage, args=('olen1',))
376376
def _set_char(self, char):
377377
self._put_char_real(char)
378-
if isinstance(self.fonts[self.f], FileNotFoundError):
378+
if isinstance(self.fonts[self.f], cbook._ExceptionProxy):
379379
return
380380
self.h += self.fonts[self.f]._width_of(char)
381381

@@ -390,7 +390,7 @@ def _put_char(self, char):
390390

391391
def _put_char_real(self, char):
392392
font = self.fonts[self.f]
393-
if isinstance(font, FileNotFoundError):
393+
if isinstance(font, cbook._ExceptionProxy):
394394
self._missing_font = font
395395
elif font._vf is None:
396396
self.text.append(Text(self.h, self.v, font, char,
@@ -504,7 +504,7 @@ def _fnt_def_real(self, k, c, s, d, a, l):
504504
# and throw that error in Dvi._read. For Vf, _finalize_packet
505505
# checks whether a missing glyph has been used, and in that case
506506
# skips the glyph definition.
507-
self.fonts[k] = exc.with_traceback(None)
507+
self.fonts[k] = cbook._ExceptionProxy(type(exc), *exc.args)
508508
return
509509
if c != 0 and tfm.checksum != 0 and c != tfm.checksum:
510510
raise ValueError(f'tfm checksum mismatch: {n}')

lib/matplotlib/font_manager.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from __future__ import annotations
2929

3030
from base64 import b64encode
31-
from collections import namedtuple
3231
import copy
3332
import dataclasses
3433
from functools import lru_cache
@@ -133,8 +132,6 @@
133132
'sans',
134133
}
135134

136-
_ExceptionProxy = namedtuple('_ExceptionProxy', ['klass', 'message'])
137-
138135
# OS Font paths
139136
try:
140137
_HOME = Path.home()
@@ -1355,8 +1352,8 @@ def findfont(self, prop, fontext='ttf', directory=None,
13551352
ret = self._findfont_cached(
13561353
prop, fontext, directory, fallback_to_default, rebuild_if_missing,
13571354
rc_params)
1358-
if isinstance(ret, _ExceptionProxy):
1359-
raise ret.klass(ret.message)
1355+
if isinstance(ret, cbook._ExceptionProxy):
1356+
raise ret.exception()
13601357
return ret
13611358

13621359
def get_font_names(self):
@@ -1509,7 +1506,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
15091506
# This return instead of raise is intentional, as we wish to
15101507
# cache that it was not found, which will not occur if it was
15111508
# actually raised.
1512-
return _ExceptionProxy(
1509+
return cbook._ExceptionProxy(
15131510
ValueError,
15141511
f"Failed to find font {prop}, and fallback to the default font was "
15151512
f"disabled"
@@ -1535,7 +1532,7 @@ def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
15351532
# This return instead of raise is intentional, as we wish to
15361533
# cache that it was not found, which will not occur if it was
15371534
# actually raised.
1538-
return _ExceptionProxy(ValueError, "No valid font could be found")
1535+
return cbook._ExceptionProxy(ValueError, "No valid font could be found")
15391536

15401537
return _cached_realpath(result)
15411538

0 commit comments

Comments
 (0)
0