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

Skip to content

Commit 7308486

Browse files
committed
Simplify units.Registry.get_converter.
The caching of the converter was disabled 10 years ago (be73ef4) and is unlikely to ever work as the correct converter for ndarrays depends on the type of the contents, not on the container, so just drop the cache-related code. When a masked array is passed, it's OK to just get the first underlying data, even if it is masked (as it should have the same type as the unmasked entries), for the purpose of getting the converter.
1 parent cc7de70 commit 7308486

File tree

1 file changed

+26
-58
lines changed

1 file changed

+26
-58
lines changed

lib/matplotlib/units.py

Lines changed: 26 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ def default_units(x, axis):
5151

5252

5353
class AxisInfo(object):
54-
"""information to support default axis labeling and tick labeling, and
55-
default limits"""
54+
"""Information to support default axis labeling, tick labeling, and limits.
55+
"""
5656
def __init__(self, majloc=None, minloc=None,
5757
majfmt=None, minfmt=None, label=None,
5858
default_limits=None):
@@ -78,20 +78,21 @@ class ConversionInterface(object):
7878
"""
7979
@staticmethod
8080
def axisinfo(unit, axis):
81-
'return an units.AxisInfo instance for axis with the specified units'
81+
"""Return an `AxisInfo` instance for *axis* with the specified *unit*.
82+
"""
8283
return None
8384

8485
@staticmethod
8586
def default_units(x, axis):
86-
'return the default unit for x or None for the given axis'
87+
"""Return the default unit for *x* or ``None`` for the given *axis*."""
8788
return None
8889

8990
@staticmethod
9091
def convert(obj, unit, axis):
91-
"""
92-
convert obj using unit for the specified axis. If obj is a sequence,
93-
return the converted sequence. The output must be a sequence of
94-
scalars that can be used by the numpy array layer
92+
"""Convert *obj* using *unit* for the specified *axis*.
93+
94+
If *obj* is a sequence, return the converted sequence. The output must
95+
be a sequence of scalars that can be used by the numpy array layer
9596
"""
9697
return obj
9798

@@ -102,7 +103,7 @@ def is_numlike(x):
102103
scalars which are the units converted to floats given the
103104
current unit. The converter may be passed these floats, or
104105
arrays of them, even when units are set. Derived conversion
105-
interfaces may opt to pass plain-ol unitless numbers through
106+
interfaces may opt to pass plain-old unitless numbers through
106107
the conversion interface and this is a helper function for
107108
them.
108109
"""
@@ -114,61 +115,28 @@ def is_numlike(x):
114115

115116

116117
class Registry(dict):
117-
"""
118-
register types with conversion interface
119-
"""
120-
def __init__(self):
121-
dict.__init__(self)
122-
self._cached = {}
118+
"""Register types with conversion interface."""
123119

124120
def get_converter(self, x):
125-
'get the converter interface instance for x, or None'
126-
127-
if not len(self):
128-
return None # nothing registered
129-
# DISABLED idx = id(x)
130-
# DISABLED cached = self._cached.get(idx)
131-
# DISABLED if cached is not None: return cached
132-
133-
converter = None
134-
classx = getattr(x, '__class__', None)
135-
136-
if classx is not None:
137-
converter = self.get(classx)
138-
139-
if isinstance(x, np.ndarray) and x.size:
140-
xravel = x.ravel()
121+
"""Get the converter interface instance for *x*, or None."""
122+
if isinstance(x, np.ndarray):
123+
# In case x in a masked array, access the underlying data (only its
124+
# type matters). If x is a regular ndarray, getdata() just returns
125+
# the array itself.
126+
x = np.ma.getdata(x).ravel()
127+
try:
128+
return self[type(x)]
129+
except KeyError:
141130
try:
142-
# pass the first value of x that is not masked back to
143-
# get_converter
144-
if not np.all(xravel.mask):
145-
# some elements are not masked
146-
converter = self.get_converter(
147-
xravel[np.argmin(xravel.mask)])
148-
return converter
149-
except AttributeError:
150-
# not a masked_array
151-
# Make sure we don't recurse forever -- it's possible for
152-
# ndarray subclasses to continue to return subclasses and
153-
# not ever return a non-subclass for a single element.
154-
next_item = xravel[0]
155-
if (not isinstance(next_item, np.ndarray) or
156-
next_item.shape != x.shape):
157-
converter = self.get_converter(next_item)
158-
return converter
159-
160-
if converter is None:
161-
try:
162-
thisx = safe_first_element(x)
131+
first = safe_first_element(x)
163132
except (TypeError, StopIteration):
164133
pass
165134
else:
166-
if classx and classx != getattr(thisx, '__class__', None):
167-
converter = self.get_converter(thisx)
168-
return converter
169-
170-
# DISABLED self._cached[idx] = converter
171-
return converter
135+
# Avoid infinite recursion for pathological iterables for which
136+
# indexing returns instances of the same iterable class.
137+
if type(first) is not type(x):
138+
return self.get_converter(first)
139+
return None
172140

173141

174142
registry = Registry()

0 commit comments

Comments
 (0)