Skip to content

Commit a69d628

Browse files
committed
API: correctly provide __name__ for cum functions
closes #12021 Author: Jeff Reback <[email protected]> Closes #12372 from jreback/closure and squashes the following commits: 2630345 [Jeff Reback] CLN: remove pandas.util.misc CLN: move _fill_zeros -> missing.py CLN: rename missing.* methods w/o leading _ 0f754b0 [Jeff Reback] API: correctly provide __name__, __qualname__ for cum functions
1 parent fded942 commit a69d628

File tree

15 files changed

+164
-171
lines changed

15 files changed

+164
-171
lines changed

doc/source/whatsnew/v0.18.1.txt

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ API changes
103103
- ``CParserError`` is now a ``ValueError`` instead of just an ``Exception`` (:issue:`12551`)
104104

105105
- ``pd.show_versions()`` now includes ``pandas_datareader`` version (:issue:`12740`)
106+
- Provide a proper ``__name__`` and ``__qualname__`` attributes for generic functions (:issue:`12021`)
106107

107108
.. _whatsnew_0181.apply_resample:
108109

@@ -170,6 +171,7 @@ Performance Improvements
170171

171172

172173

174+
- Bug in ``__name__`` of ``.cum*`` functions (:issue:`12021`)
173175

174176

175177

pandas/compat/__init__.py

+18
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@ def import_lzma():
242242
import lzma
243243
return lzma
244244

245+
def set_function_name(f, name, cls):
246+
""" Bind the name/qualname attributes of the function """
247+
f.__name__ = name
248+
f.__qualname__ = '{klass}.{name}'.format(
249+
klass=cls.__name__,
250+
name=name)
251+
f.__module__ = cls.__module__
252+
return f
253+
245254
else:
246255
string_types = basestring,
247256
integer_types = (int, long)
@@ -284,6 +293,11 @@ def import_lzma():
284293
from backports import lzma
285294
return lzma
286295

296+
def set_function_name(f, name, cls):
297+
""" Bind the name attributes of the function """
298+
f.__name__ = name
299+
return f
300+
287301
string_and_binary_types = string_types + (binary_type,)
288302

289303

@@ -369,6 +383,10 @@ def __reduce__(self): # optional, for pickle support
369383

370384

371385
# https://github.com/pydata/pandas/pull/9123
386+
def is_platform_little_endian():
387+
""" am I little endian """
388+
return sys.byteorder == 'little'
389+
372390
def is_platform_windows():
373391
return sys.platform == 'win32' or sys.platform == 'cygwin'
374392

pandas/core/common.py

-80
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import re
66
import collections
77
import numbers
8-
import types
98
from datetime import datetime, timedelta
109
from functools import partial
1110

@@ -130,31 +129,6 @@ def __instancecheck__(cls, inst):
130129
ABCGeneric = _ABCGeneric("ABCGeneric", tuple(), {})
131130

132131

133-
def bind_method(cls, name, func):
134-
"""Bind a method to class, python 2 and python 3 compatible.
135-
136-
Parameters
137-
----------
138-
139-
cls : type
140-
class to receive bound method
141-
name : basestring
142-
name of method on class instance
143-
func : function
144-
function to be bound as method
145-
146-
147-
Returns
148-
-------
149-
None
150-
"""
151-
# only python 2 has bound/unbound method issue
152-
if not compat.PY3:
153-
setattr(cls, name, types.MethodType(func, None, cls))
154-
else:
155-
setattr(cls, name, func)
156-
157-
158132
def isnull(obj):
159133
"""Detect missing values (NaN in numeric arrays, None/NaN in object arrays)
160134
@@ -1466,60 +1440,6 @@ def _lcd_dtypes(a_dtype, b_dtype):
14661440
return np.object
14671441

14681442

1469-
def _fill_zeros(result, x, y, name, fill):
1470-
"""
1471-
if this is a reversed op, then flip x,y
1472-
1473-
if we have an integer value (or array in y)
1474-
and we have 0's, fill them with the fill,
1475-
return the result
1476-
1477-
mask the nan's from x
1478-
"""
1479-
if fill is None or is_float_dtype(result):
1480-
return result
1481-
1482-
if name.startswith(('r', '__r')):
1483-
x, y = y, x
1484-
1485-
is_typed_variable = (hasattr(y, 'dtype') or hasattr(y, 'type'))
1486-
is_scalar = lib.isscalar(y)
1487-
1488-
if not is_typed_variable and not is_scalar:
1489-
return result
1490-
1491-
if is_scalar:
1492-
y = np.array(y)
1493-
1494-
if is_integer_dtype(y):
1495-
1496-
if (y == 0).any():
1497-
1498-
# GH 7325, mask and nans must be broadcastable (also: PR 9308)
1499-
# Raveling and then reshaping makes np.putmask faster
1500-
mask = ((y == 0) & ~np.isnan(result)).ravel()
1501-
1502-
shape = result.shape
1503-
result = result.astype('float64', copy=False).ravel()
1504-
1505-
np.putmask(result, mask, fill)
1506-
1507-
# if we have a fill of inf, then sign it correctly
1508-
# (GH 6178 and PR 9308)
1509-
if np.isinf(fill):
1510-
signs = np.sign(y if name.startswith(('r', '__r')) else x)
1511-
negative_inf_mask = (signs.ravel() < 0) & mask
1512-
np.putmask(result, negative_inf_mask, -fill)
1513-
1514-
if "floordiv" in name: # (PR 9308)
1515-
nan_mask = ((y == 0) & (x == 0)).ravel()
1516-
np.putmask(result, nan_mask, np.nan)
1517-
1518-
result = result.reshape(shape)
1519-
1520-
return result
1521-
1522-
15231443
def _consensus_name_attr(objs):
15241444
name = objs[0].name
15251445
for obj in objs[1:]:

0 commit comments

Comments
 (0)