Skip to content

Commit 9ee8674

Browse files
authored
REF: avoid catching all exceptions in libreduction (#38285)
1 parent baeacad commit 9ee8674

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

pandas/_libs/reduction.pyx

+25-10
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,6 @@ cdef class Slider:
335335
self.buf.shape[0] = 0
336336

337337

338-
class InvalidApply(Exception):
339-
pass
340-
341-
342338
def apply_frame_axis0(object frame, object f, object names,
343339
const int64_t[:] starts, const int64_t[:] ends):
344340
cdef:
@@ -365,11 +361,7 @@ def apply_frame_axis0(object frame, object f, object names,
365361
chunk = slider.dummy
366362
object.__setattr__(chunk, 'name', names[i])
367363

368-
try:
369-
piece = f(chunk)
370-
except Exception as err:
371-
# We can't be more specific without knowing something about `f`
372-
raise InvalidApply("Let this error raise above us") from err
364+
piece = f(chunk)
373365

374366
# Need to infer if low level index slider will cause segfaults
375367
require_slow_apply = i == 0 and piece is chunk
@@ -406,7 +398,8 @@ cdef class BlockSlider:
406398
"""
407399
cdef:
408400
object frame, dummy, index, block
409-
list blk_values
401+
list blocks, blk_values
402+
ndarray orig_blklocs, orig_blknos
410403
ndarray values
411404
Slider idx_slider
412405
char **base_ptrs
@@ -418,6 +411,13 @@ cdef class BlockSlider:
418411
self.dummy = frame[:0]
419412
self.index = self.dummy.index
420413

414+
# GH#35417 attributes we need to restore at each step in case
415+
# the function modified them.
416+
mgr = self.dummy._mgr
417+
self.orig_blklocs = mgr.blklocs
418+
self.orig_blknos = mgr.blknos
419+
self.blocks = [x for x in self.dummy._mgr.blocks]
420+
421421
self.blk_values = [block.values for block in self.dummy._mgr.blocks]
422422

423423
for values in self.blk_values:
@@ -441,6 +441,9 @@ cdef class BlockSlider:
441441
cdef:
442442
ndarray arr
443443
Py_ssize_t i
444+
445+
self._restore_blocks()
446+
444447
# move blocks
445448
for i in range(self.nblocks):
446449
arr = self.blk_values[i]
@@ -460,9 +463,21 @@ cdef class BlockSlider:
460463
cdef:
461464
ndarray arr
462465
Py_ssize_t i
466+
467+
self._restore_blocks()
468+
463469
for i in range(self.nblocks):
464470
arr = self.blk_values[i]
465471

466472
# axis=1 is the frame's axis=0
467473
arr.data = self.base_ptrs[i]
468474
arr.shape[1] = 0
475+
476+
cdef _restore_blocks(self):
477+
"""
478+
Ensure that we have the original blocks, blknos, and blklocs.
479+
"""
480+
mgr = self.dummy._mgr
481+
mgr.blocks = self.blocks
482+
mgr._blklocs = self.orig_blklocs
483+
mgr._blknos = self.orig_blknos

pandas/core/groupby/ops.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,10 @@ def apply(self, f: F, data: FrameOrSeries, axis: int = 0):
202202
try:
203203
result_values, mutated = splitter.fast_apply(f, sdata, group_keys)
204204

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

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

0 commit comments

Comments
 (0)