Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ba83fb4

Browse filesBrowse files
committed
FIX: account for changes to cpython with copy/deepcopy to super()
See python/cpython#126817 for upstream discussion. This works around the change by using (private) methods from the copy module to re-implement the path though copy/deepcopy that we would like to use but avoid the special-casing for `super()` objects that is breaking us. We could vendor the current versions of `_keep_alive` (weakref work to manage lifecycles) and `_reconstruct` (where the recursion happens) to superficially avoid using private functions from CPython. However, if these functions do change significantly I worry that our copies would not inter-operate anyway. Closes #29157
1 parent 9ec6cb7 commit ba83fb4
Copy full SHA for ba83fb4

File tree

3 files changed

+20
-3
lines changed
Filter options

3 files changed

+20
-3
lines changed

‎lib/matplotlib/path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/path.py
+12-1Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import copy
1313
from functools import lru_cache
14+
import sys
1415
from weakref import WeakValueDictionary
1516

1617
import numpy as np
@@ -282,7 +283,17 @@ def __deepcopy__(self, memo=None):
282283
readonly, even if the source `Path` is.
283284
"""
284285
# Deepcopying arrays (vertices, codes) strips the writeable=False flag.
285-
p = copy.deepcopy(super(), memo)
286+
if sys.version_info >= (3, 14):
287+
from copy import _reconstruct, _keep_alive
288+
rv = super().__reduce_ex__(4)
289+
assert memo is not None
290+
p = _reconstruct(self, memo, *rv)
291+
if memo is not None:
292+
memo[id(self)] = p
293+
_keep_alive(self, memo)
294+
295+
else:
296+
p = copy.deepcopy(super(), memo)
286297
p._readonly = False
287298
return p
288299

‎lib/matplotlib/path.pyi

Copy file name to clipboardExpand all lines: lib/matplotlib/path.pyi
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Path:
4545
def readonly(self) -> bool: ...
4646
def copy(self) -> Path: ...
4747
def __deepcopy__(self, memo: dict[int, Any] | None = ...) -> Path: ...
48-
deepcopy = __deepcopy__
48+
def deepcopy(self) -> Path: ...
4949

5050
@classmethod
5151
def make_compound_path_from_polys(cls, XY: ArrayLike) -> Path: ...

‎lib/matplotlib/transforms.py

Copy file name to clipboardExpand all lines: lib/matplotlib/transforms.py
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import copy
3939
import functools
4040
import itertools
41+
import sys
4142
import textwrap
4243
import weakref
4344
import math
@@ -141,7 +142,12 @@ def __setstate__(self, data_dict):
141142
for k, v in self._parents.items() if v is not None}
142143

143144
def __copy__(self):
144-
other = copy.copy(super())
145+
if sys.version_info >= (3, 14):
146+
from copy import _reconstruct
147+
rv = super().__reduce_ex__(4)
148+
other = _reconstruct(self, None, *rv)
149+
else:
150+
other = copy.copy(super())
145151
# If `c = a + b; a1 = copy(a)`, then modifications to `a1` do not
146152
# propagate back to `c`, i.e. we need to clear the parents of `a1`.
147153
other._parents = {}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.