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 2aa4b7d

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

File tree

Expand file treeCollapse file tree

2 files changed

+25
-3
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+25
-3
lines changed

‎lib/matplotlib/colors.py

Copy file name to clipboardExpand all lines: lib/matplotlib/colors.py
+20-3Lines 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

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_pickle.py
+5Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.