🌐 AI搜索 & 代理 主页
Skip to content

Commit 60903f0

Browse 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 c9c90c4 commit 60903f0

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

lib/matplotlib/path.py

Lines 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/transforms.py

Lines 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)