Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2aa4b7d

Browse files
authored
Merge pull request #22815 from anntzer/normpickle
Fix pickling of globally available, dynamically generated norm classes.
2 parents 1999228 + 80d0959 commit 2aa4b7d

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

lib/matplotlib/colors.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from collections.abc import Sized, Sequence
4444
import copy
4545
import functools
46+
import importlib
4647
import inspect
4748
import io
4849
import itertools
@@ -1528,9 +1529,22 @@ def _make_norm_from_scale(scale_cls, base_norm_cls, bound_init_signature):
15281529

15291530
class Norm(base_norm_cls):
15301531
def __reduce__(self):
1532+
cls = type(self)
1533+
# If the class is toplevel-accessible, it is possible to directly
1534+
# pickle it "by name". This is required to support norm classes
1535+
# defined at a module's toplevel, as the inner base_norm_cls is
1536+
# otherwise unpicklable (as it gets shadowed by the generated norm
1537+
# class). If either import or attribute access fails, fall back to
1538+
# the general path.
1539+
try:
1540+
if cls is getattr(importlib.import_module(cls.__module__),
1541+
cls.__qualname__):
1542+
return (_create_empty_object_of_class, (cls,), vars(self))
1543+
except (ImportError, AttributeError):
1544+
pass
15311545
return (_picklable_norm_constructor,
15321546
(scale_cls, base_norm_cls, bound_init_signature),
1533-
self.__dict__)
1547+
vars(self))
15341548

15351549
def __init__(self, *args, **kwargs):
15361550
ba = bound_init_signature.bind(*args, **kwargs)
@@ -1603,11 +1617,14 @@ def autoscale_None(self, A):
16031617
return Norm
16041618

16051619

1606-
def _picklable_norm_constructor(*args):
1607-
cls = _make_norm_from_scale(*args)
1620+
def _create_empty_object_of_class(cls):
16081621
return cls.__new__(cls)
16091622

16101623

1624+
def _picklable_norm_constructor(*args):
1625+
return _create_empty_object_of_class(_make_norm_from_scale(*args))
1626+
1627+
16111628
@make_norm_from_scale(
16121629
scale.FuncScale,
16131630
init=lambda functions, vmin=None, vmax=None, clip=False: None)

lib/matplotlib/tests/test_pickle.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ def test_mpl_toolkits():
221221
assert type(pickle.loads(pickle.dumps(ax))) == parasite_axes.HostAxes
222222

223223

224+
def test_standard_norm():
225+
assert type(pickle.loads(pickle.dumps(mpl.colors.LogNorm()))) \
226+
== mpl.colors.LogNorm
227+
228+
224229
def test_dynamic_norm():
225230
logit_norm_instance = mpl.colors.make_norm_from_scale(
226231
mpl.scale.LogitScale, mpl.colors.Normalize)()

0 commit comments

Comments
 (0)