@@ -1507,9 +1507,26 @@ class norm_cls(Normalize):
1507
1507
1508
1508
if init is None :
1509
1509
def init (vmin = None , vmax = None , clip = False ): pass
1510
- bound_init_signature = inspect .signature (init )
1510
+
1511
+ return _make_norm_from_scale (
1512
+ scale_cls , base_norm_cls , inspect .signature (init ))
1513
+
1514
+
1515
+ @functools .lru_cache (None )
1516
+ def _make_norm_from_scale (scale_cls , base_norm_cls , bound_init_signature ):
1517
+ """
1518
+ Helper for `make_norm_from_scale`.
1519
+
1520
+ This function is split out so that it takes a signature object as third
1521
+ argument (as signatures are picklable, contrary to arbitrary lambdas);
1522
+ caching is also used so that different unpickles reuse the same class.
1523
+ """
1511
1524
1512
1525
class Norm (base_norm_cls ):
1526
+ def __reduce__ (self ):
1527
+ return (_picklable_norm_constructor ,
1528
+ (scale_cls , base_norm_cls , bound_init_signature ),
1529
+ self .__dict__ )
1513
1530
1514
1531
def __init__ (self , * args , ** kwargs ):
1515
1532
ba = bound_init_signature .bind (* args , ** kwargs )
@@ -1519,6 +1536,10 @@ def __init__(self, *args, **kwargs):
1519
1536
self ._scale = scale_cls (axis = None , ** ba .arguments )
1520
1537
self ._trf = self ._scale .get_transform ()
1521
1538
1539
+ __init__ .__signature__ = bound_init_signature .replace (parameters = [
1540
+ inspect .Parameter ("self" , inspect .Parameter .POSITIONAL_OR_KEYWORD ),
1541
+ * bound_init_signature .parameters .values ()])
1542
+
1522
1543
def __call__ (self , value , clip = None ):
1523
1544
value , is_scalar = self .process_value (value )
1524
1545
if self .vmin is None or self .vmax is None :
@@ -1566,17 +1587,23 @@ def autoscale_None(self, A):
1566
1587
in_trf_domain = np .extract (np .isfinite (self ._trf .transform (A )), A )
1567
1588
return super ().autoscale_None (in_trf_domain )
1568
1589
1569
- Norm .__name__ = (f"{ scale_cls .__name__ } Norm" if base_norm_cls is Normalize
1570
- else base_norm_cls .__name__ )
1571
- Norm .__qualname__ = base_norm_cls .__qualname__
1590
+ Norm .__name__ = (
1591
+ f"{ scale_cls .__name__ } Norm" if base_norm_cls is Normalize
1592
+ else base_norm_cls .__name__ )
1593
+ Norm .__qualname__ = (
1594
+ f"{ scale_cls .__qualname__ } Norm" if base_norm_cls is Normalize
1595
+ else base_norm_cls .__qualname__ )
1572
1596
Norm .__module__ = base_norm_cls .__module__
1573
1597
Norm .__doc__ = base_norm_cls .__doc__
1574
- Norm .__init__ .__signature__ = bound_init_signature .replace (parameters = [
1575
- inspect .Parameter ("self" , inspect .Parameter .POSITIONAL_OR_KEYWORD ),
1576
- * bound_init_signature .parameters .values ()])
1598
+
1577
1599
return Norm
1578
1600
1579
1601
1602
+ def _picklable_norm_constructor (* args , ** kwargs ):
1603
+ cls = _make_norm_from_scale (* args , ** kwargs )
1604
+ return cls .__new__ (cls )
1605
+
1606
+
1580
1607
@make_norm_from_scale (
1581
1608
scale .FuncScale ,
1582
1609
init = lambda functions , vmin = None , vmax = None , clip = False : None )
0 commit comments