Closed
Description
Bug report
If a bound method is used as the condition for BaseExceptionGroup.split the following exception is raised:
TypeError: expected a function, exception type or tuple of exception types
Consider the following example:
class HandleError: def __enter__(self): pass def __exit__(self, exc_type, exc_inst, exc_tb): if exc_type is None: return False if isinstance(exc_inst, ExceptionGroup): match, rest = exc_inst.split(self._log_and_ignore_error) if match is None: return False elif rest is None: return True raise rest else: return self._log_and_ignore_error(exc_inst) def _log_and_ignore_error(self, e: BaseException) -> bool: ... return True with HandleError(): raise ExceptionGroup('foo', [ValueError('bar')])
If we replace the bound method with a lambda (lambda e: self._log_and_ignore_error(e)
) then no exception is raised.
I think it would be useful to accept any callable here. I guess the code update would be simple too, just replace PyFunction_Check with PyCallable_Check in
if (PyFunction_Check(value)) { *type = EXCEPTION_GROUP_MATCH_BY_PREDICATE; return 0; }
Update the exception message to allow callables, and change the assert in
case EXCEPTION_GROUP_MATCH_BY_PREDICATE: { assert(PyFunction_Check(matcher_value)); PyObject *exc_matches = PyObject_CallOneArg(matcher_value, exc);
to call PyCallable_Check again.
Your environment
- CPython versions tested on: 3.11.2
The c code snippets are from origin/main.