Skip to content

Commit

Permalink
Backport PR #25230: BUG: Fix regression in DataFrame.apply causing Re…
Browse files Browse the repository at this point in the history
…cursionError (#25245)
  • Loading branch information
meeseeksmachine authored and jreback committed Feb 9, 2019
1 parent 5eb761e commit b134253
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 9 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.24.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Fixed Regressions
^^^^^^^^^^^^^^^^^

- Fixed regression in :meth:`DataFrame.all` and :meth:`DataFrame.any` where ``bool_only=True`` was ignored (:issue:`25101`)

- Fixed issue in ``DataFrame`` construction with passing a mixed list of mixed types could segfault. (:issue:`25075`)
- Fixed regression in :meth:`DataFrame.apply` causing ``RecursionError`` when ``dict``-like classes were passed as argument. (:issue:`25196`)

.. _whatsnew_0242.enhancements:

Expand Down
13 changes: 8 additions & 5 deletions pandas/core/dtypes/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,15 @@ def is_dict_like(obj):
True
>>> is_dict_like([1, 2, 3])
False
>>> is_dict_like(dict)
False
>>> is_dict_like(dict())
True
"""
for attr in ("__getitem__", "keys", "__contains__"):
if not hasattr(obj, attr):
return False

return True
dict_like_attrs = ("__getitem__", "keys", "__contains__")
return (all(hasattr(obj, attr) for attr in dict_like_attrs)
# [GH 25196] exclude classes
and not isinstance(obj, type))


def is_named_tuple(obj):
Expand Down
8 changes: 5 additions & 3 deletions pandas/tests/dtypes/test_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,15 @@ def test_is_nested_list_like_fails(obj):


@pytest.mark.parametrize(
"ll", [{}, {'A': 1}, Series([1])])
"ll", [{}, {'A': 1}, Series([1]), collections.defaultdict()])
def test_is_dict_like_passes(ll):
assert inference.is_dict_like(ll)


@pytest.mark.parametrize(
"ll", ['1', 1, [1, 2], (1, 2), range(2), Index([1])])
@pytest.mark.parametrize("ll", [
'1', 1, [1, 2], (1, 2), range(2), Index([1]),
dict, collections.defaultdict, Series
])
def test_is_dict_like_fails(ll):
assert not inference.is_dict_like(ll)

Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/frame/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,13 @@ def test_apply_reduce_Series(self, float_frame):
result = float_frame.apply(np.mean, axis=1)
assert_series_equal(result, expected)

def test_apply_reduce_rows_to_dict(self):
# GH 25196
data = pd.DataFrame([[1, 2], [3, 4]])
expected = pd.Series([{0: 1, 1: 3}, {0: 2, 1: 4}])
result = data.apply(dict)
assert_series_equal(result, expected)

def test_apply_differently_indexed(self):
df = DataFrame(np.random.randn(20, 10))

Expand Down

0 comments on commit b134253

Please sign in to comment.