|
16 | 16 | import numpy as np
|
17 | 17 |
|
18 | 18 | import matplotlib as mpl
|
| 19 | + |
19 | 20 | from . import _api, _path
|
20 | 21 | from .cbook import _to_unmasked_float_array, simple_linear_interpolation
|
21 | 22 | from .bezier import BezierSegment
|
22 | 23 |
|
23 | 24 |
|
24 |
| -class Path: |
| 25 | +class _HideDeepcopyMeta(type): |
| 26 | + """Metaclass that allows conditionally hiding the __deepcopy__ method. |
| 27 | +
|
| 28 | + Set __hide_deepcopy__ to True to hide the __deepcopy__ method, |
| 29 | + which will then be looked up in the usual method resolution order. |
| 30 | + """ |
| 31 | + |
| 32 | + def __new__(cls, name, bases, namespace): |
| 33 | + orig_ga = namespace.get("__getattribute__") or object.__getattribute__ |
| 34 | + |
| 35 | + def __getattribute__(self, attr_name): |
| 36 | + if attr_name == "__deepcopy__" and orig_ga(self, "__hide_deepcopy__"): |
| 37 | + for base in type(self).__mro__[1:]: |
| 38 | + if attr_name in base.__dict__: |
| 39 | + method = base.__dict__[attr_name] |
| 40 | + return method.__get__(self, type(self)) |
| 41 | + raise AttributeError( |
| 42 | + f"'{type(self).__name__}' object has no attribute '{attr_name}'" |
| 43 | + ) |
| 44 | + return orig_ga(self, attr_name) |
| 45 | + |
| 46 | + namespace["__getattribute__"] = __getattribute__ |
| 47 | + return super().__new__(cls, name, bases, namespace) |
| 48 | + |
| 49 | + |
| 50 | +class Path(metaclass=_HideDeepcopyMeta): |
25 | 51 | """
|
26 | 52 | A series of possibly disconnected, possibly closed, line and curve
|
27 | 53 | segments.
|
@@ -281,9 +307,13 @@ def __deepcopy__(self, memo=None):
|
281 | 307 | readonly, even if the source `Path` is.
|
282 | 308 | """
|
283 | 309 | # Deepcopying arrays (vertices, codes) strips the writeable=False flag.
|
284 |
| - p = copy.deepcopy(super(), memo) |
285 |
| - p._readonly = False |
286 |
| - return p |
| 310 | + self.__hide_deepcopy__ = True |
| 311 | + try: |
| 312 | + p = copy.deepcopy(self, memo) |
| 313 | + p._readonly = False |
| 314 | + return p |
| 315 | + finally: |
| 316 | + self.__hide_deepcopy__ = False |
287 | 317 |
|
288 | 318 | deepcopy = __deepcopy__
|
289 | 319 |
|
|
0 commit comments