88from matplotlib .cbook import iterable
99
1010class ProxyDelegate (object ):
11- def __init__ (self , fn_name , proxy_type ):
12- self .proxy_type = proxy_type
13- self .fn_name = fn_name
14- def __get__ (self , obj , objtype = None ):
15- return self .proxy_type (self .fn_name , obj )
11+ def __init__ (self , fn_name , proxy_type ):
12+ self .proxy_type = proxy_type
13+ self .fn_name = fn_name
14+ def __get__ (self , obj , objtype = None ):
15+ return self .proxy_type (self .fn_name , obj )
1616
1717class TaggedValueMeta (type ):
18- def __init__ (cls , name , bases , dict ):
19- for fn_name in cls ._proxies .keys ():
20- try :
21- dummy = getattr (cls , fn_name )
22- except AttributeError :
23- setattr (cls , fn_name , ProxyDelegate (fn_name , cls ._proxies [fn_name ]))
18+ def __init__ (cls , name , bases , dict ):
19+ for fn_name in cls ._proxies .keys ():
20+ try :
21+ dummy = getattr (cls , fn_name )
22+ except AttributeError :
23+ setattr (cls , fn_name , ProxyDelegate (fn_name , cls ._proxies [fn_name ]))
2424
2525class PassThroughProxy (object ):
26- def __init__ (self , fn_name , obj ):
27- self .fn_name = fn_name
28- self .target = obj .proxy_target
29- def __call__ (self , * args ):
30- fn = getattr (self .target , self .fn_name )
31- ret = fn (* args )
32- return ret
26+ def __init__ (self , fn_name , obj ):
27+ self .fn_name = fn_name
28+ self .target = obj .proxy_target
29+ def __call__ (self , * args ):
30+ fn = getattr (self .target , self .fn_name )
31+ ret = fn (* args )
32+ return ret
3333
3434class ConvertArgsProxy (PassThroughProxy ):
35- def __init__ (self , fn_name , obj ):
36- PassThroughProxy .__init__ (self , fn_name , obj )
37- self .unit = obj .unit
38- def __call__ (self , * args ):
39- converted_args = []
40- for a in args :
41- try :
42- converted_args .append (a .convert_to (self .unit ))
43- except AttributeError :
44- converted_args .append (TaggedValue (a , self .unit ))
45- converted_args = tuple ([c .get_value () for c in converted_args ])
46- return PassThroughProxy .__call__ (self , * converted_args )
35+ def __init__ (self , fn_name , obj ):
36+ PassThroughProxy .__init__ (self , fn_name , obj )
37+ self .unit = obj .unit
38+ def __call__ (self , * args ):
39+ converted_args = []
40+ for a in args :
41+ try :
42+ converted_args .append (a .convert_to (self .unit ))
43+ except AttributeError :
44+ converted_args .append (TaggedValue (a , self .unit ))
45+ converted_args = tuple ([c .get_value () for c in converted_args ])
46+ return PassThroughProxy .__call__ (self , * converted_args )
4747
4848class ConvertReturnProxy (PassThroughProxy ):
49- def __init__ (self , fn_name , obj ):
50- PassThroughProxy .__init__ (self , fn_name , obj )
51- self .unit = obj .unit
52- def __call__ (self , * args ):
53- ret = PassThroughProxy .__call__ (self , * args )
54- if (type (ret ) == type (NotImplemented )):
55- return NotImplemented
56- return TaggedValue (ret , self .unit )
49+ def __init__ (self , fn_name , obj ):
50+ PassThroughProxy .__init__ (self , fn_name , obj )
51+ self .unit = obj .unit
52+ def __call__ (self , * args ):
53+ ret = PassThroughProxy .__call__ (self , * args )
54+ if (type (ret ) == type (NotImplemented )):
55+ return NotImplemented
56+ return TaggedValue (ret , self .unit )
5757
5858class ConvertAllProxy (PassThroughProxy ):
59- def __init__ (self , fn_name , obj ):
60- PassThroughProxy .__init__ (self , fn_name , obj )
61- self .unit = obj .unit
62- def __call__ (self , * args ):
63- converted_args = []
64- arg_units = [self .unit ]
65- for a in args :
66- if hasattr (a , 'get_unit' ) and not hasattr (a , 'convert_to' ):
67- # if this arg has a unit type but no conversion ability,
68- # this operation is prohibited
69- return NotImplemented
70-
71- if hasattr (a , 'convert_to' ):
72- try :
73- a = a .convert_to (self .unit )
74- except :
75- pass
76- arg_units .append (a .get_unit ())
77- converted_args .append (a .get_value ())
78- else :
79- converted_args .append (a )
80- if hasattr (a , 'get_unit' ):
81- arg_units .append (a .get_unit ())
82- else :
83- arg_units .append (None )
84- converted_args = tuple (converted_args )
85- ret = PassThroughProxy .__call__ (self , * converted_args )
86- if (type (ret ) == type (NotImplemented )):
87- return NotImplemented
88- ret_unit = unit_resolver (self .fn_name , arg_units )
89- if (ret_unit == NotImplemented ):
90- return NotImplemented
91- return TaggedValue (ret , ret_unit )
59+ def __init__ (self , fn_name , obj ):
60+ PassThroughProxy .__init__ (self , fn_name , obj )
61+ self .unit = obj .unit
62+
63+ def __call__ (self , * args ):
64+ converted_args = []
65+ arg_units = [self .unit ]
66+ for a in args :
67+ if hasattr (a , 'get_unit' ) and not hasattr (a , 'convert_to' ):
68+ # if this arg has a unit type but no conversion ability,
69+ # this operation is prohibited
70+ return NotImplemented
71+
72+ if hasattr (a , 'convert_to' ):
73+ try :
74+ a = a .convert_to (self .unit )
75+ except :
76+ pass
77+ arg_units .append (a .get_unit ())
78+ converted_args .append (a .get_value ())
79+ else :
80+ converted_args .append (a )
81+ if hasattr (a , 'get_unit' ):
82+ arg_units .append (a .get_unit ())
83+ else :
84+ arg_units .append (None )
85+ converted_args = tuple (converted_args )
86+ ret = PassThroughProxy .__call__ (self , * converted_args )
87+ if (type (ret ) == type (NotImplemented )):
88+ return NotImplemented
89+ ret_unit = unit_resolver (self .fn_name , arg_units )
90+ if (ret_unit == NotImplemented ):
91+ return NotImplemented
92+ return TaggedValue (ret , ret_unit )
9293
9394class TaggedValue (object ):
9495
@@ -102,11 +103,15 @@ def __new__(cls, value, unit):
102103 # generate a new subclass for value
103104 value_class = type (value )
104105 try :
105- subcls = type ('TaggedValue_of_%s' % (` value_class.__name__` ),
106+ subcls = type ('TaggedValue_of_%s' % (value_class .__name__ ),
106107 tuple ([cls , value_class ]),
107108 {})
109+ if subcls not in units .registry :
110+ units .registry [subcls ] = basicConverter
108111 return object .__new__ (subcls , value , unit )
109- except :
112+ except TypeError :
113+ if cls not in units .registry :
114+ units .registry [cls ] = basicConverter
110115 return object .__new__ (cls , value , unit )
111116
112117 def __init__ (self , value , unit ):
@@ -177,7 +182,7 @@ def __init__(self, name, fullname=None):
177182
178183
179184 def __repr__ (self ):
180- return 'BasicUnit(' + ` self.name` + ')'
185+ return 'BasicUnit(%s)' % self .name
181186
182187 def __str__ (self ):
183188 return self .fullname
@@ -314,15 +319,23 @@ def axisinfo(unit):
314319 axisinfo = staticmethod (axisinfo )
315320
316321 def convert (val , unit ):
322+ if units .ConversionInterface .is_numlike (val ):
323+ return val
324+
317325 if iterable (val ):
318- return [thisval .convert_to (unit ).get_value () for thisval in val ]
326+ return [thisval .convert_to (unit ).get_value () for thisval in val ]
319327 else :
320- return val .convert_to (unit ).get_value ()
328+ return val .convert_to (unit ).get_value ()
321329 convert = staticmethod (convert )
322330
323331 def default_units (x ):
324332 'return the default unit for x or None'
333+ if iterable (x ):
334+ for thisx in x :
335+ return thisx .unit
325336 return x .unit
326337 default_units = staticmethod (default_units )
327338
328- units .registry [TaggedValue ] = BasicUnitConverter ()
339+
340+ basicConverter = BasicUnitConverter ()
341+ units .registry [TaggedValue ] = basicConverter
0 commit comments