gh-145966: Fix _csv DIALECT_GETATTR macro silently masking non-AttributeError exceptions (GH-145974)

The DIALECT_GETATTR macro in dialect_new() unconditionally called
PyErr_Clear() when PyObject_GetAttrString() failed, which suppressed
all exceptions including MemoryError, KeyboardInterrupt, and
RuntimeError. Now only AttributeError is cleared; other exceptions
propagate via the existing error handling path.

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Ramin Farajpour Cami 2026-03-17 18:38:53 +03:30 committed by GitHub
parent 1efd9939c8
commit dc24b8a6d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 7 deletions

View file

@ -1280,6 +1280,19 @@ class mydialect(csv.Dialect):
self.assertRaises(ValueError, create_invalid, field_name, " ",
skipinitialspace=True)
def test_dialect_getattr_non_attribute_error_propagates(self):
# gh-145966: non-AttributeError exceptions raised by __getattr__
# during dialect attribute lookup must propagate, not be silenced.
class BadDialect:
def __getattr__(self, name):
raise RuntimeError("boom")
with self.assertRaises(RuntimeError):
csv.reader([], dialect=BadDialect())
with self.assertRaises(RuntimeError):
csv.writer(StringIO(), dialect=BadDialect())
class TestSniffer(unittest.TestCase):
sample1 = """\

View file

@ -0,0 +1,2 @@
Non-:exc:`AttributeError` exceptions raised during dialect attribute lookup
in :mod:`csv` are no longer silently suppressed.

View file

@ -497,13 +497,13 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Py_XINCREF(skipinitialspace);
Py_XINCREF(strict);
if (dialect != NULL) {
#define DIALECT_GETATTR(v, n) \
do { \
if (v == NULL) { \
v = PyObject_GetAttrString(dialect, n); \
if (v == NULL) \
PyErr_Clear(); \
} \
#define DIALECT_GETATTR(v, n) \
do { \
if (v == NULL) { \
if (PyObject_GetOptionalAttrString(dialect, n, &v) < 0) { \
goto err; \
} \
} \
} while (0)
DIALECT_GETATTR(delimiter, "delimiter");
DIALECT_GETATTR(doublequote, "doublequote");