Skip to content

Commit

Permalink
REF: avoid catching all exceptions in libreduction (#38285)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored Dec 17, 2020
1 parent baeacad commit 9ee8674
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
35 changes: 25 additions & 10 deletions pandas/_libs/reduction.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,6 @@ cdef class Slider:
self.buf.shape[0] = 0


class InvalidApply(Exception):
pass


def apply_frame_axis0(object frame, object f, object names,
const int64_t[:] starts, const int64_t[:] ends):
cdef:
Expand All @@ -365,11 +361,7 @@ def apply_frame_axis0(object frame, object f, object names,
chunk = slider.dummy
object.__setattr__(chunk, 'name', names[i])

try:
piece = f(chunk)
except Exception as err:
# We can't be more specific without knowing something about `f`
raise InvalidApply("Let this error raise above us") from err
piece = f(chunk)

# Need to infer if low level index slider will cause segfaults
require_slow_apply = i == 0 and piece is chunk
Expand Down Expand Up @@ -406,7 +398,8 @@ cdef class BlockSlider:
"""
cdef:
object frame, dummy, index, block
list blk_values
list blocks, blk_values
ndarray orig_blklocs, orig_blknos
ndarray values
Slider idx_slider
char **base_ptrs
Expand All @@ -418,6 +411,13 @@ cdef class BlockSlider:
self.dummy = frame[:0]
self.index = self.dummy.index

# GH#35417 attributes we need to restore at each step in case
# the function modified them.
mgr = self.dummy._mgr
self.orig_blklocs = mgr.blklocs
self.orig_blknos = mgr.blknos
self.blocks = [x for x in self.dummy._mgr.blocks]

self.blk_values = [block.values for block in self.dummy._mgr.blocks]

for values in self.blk_values:
Expand All @@ -441,6 +441,9 @@ cdef class BlockSlider:
cdef:
ndarray arr
Py_ssize_t i

self._restore_blocks()

# move blocks
for i in range(self.nblocks):
arr = self.blk_values[i]
Expand All @@ -460,9 +463,21 @@ cdef class BlockSlider:
cdef:
ndarray arr
Py_ssize_t i

self._restore_blocks()

for i in range(self.nblocks):
arr = self.blk_values[i]

# axis=1 is the frame's axis=0
arr.data = self.base_ptrs[i]
arr.shape[1] = 0

cdef _restore_blocks(self):
"""
Ensure that we have the original blocks, blknos, and blklocs.
"""
mgr = self.dummy._mgr
mgr.blocks = self.blocks
mgr._blklocs = self.orig_blklocs
mgr._blknos = self.orig_blknos
11 changes: 4 additions & 7 deletions pandas/core/groupby/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,10 @@ def apply(self, f: F, data: FrameOrSeries, axis: int = 0):
try:
result_values, mutated = splitter.fast_apply(f, sdata, group_keys)

except libreduction.InvalidApply as err:
# This Exception is raised if `f` triggers an exception
# but it is preferable to raise the exception in Python.
if "Let this error raise above us" not in str(err):
# TODO: can we infer anything about whether this is
# worth-retrying in pure-python?
raise
except IndexError:
# This is a rare case in which re-running in python-space may
# make a difference, see test_apply_mutate.test_mutate_groups
pass

else:
# If the fast apply path could be used we can return here.
Expand Down

0 comments on commit 9ee8674

Please sign in to comment.