Bug report
Bug description:
In Modules/_csv.c, the DIALECT_GETATTR macro in dialect_new() calls PyErr_Clear() unconditionally when PyObject_GetAttrString() fails. This silently swallows all exception types including MemoryError, KeyboardInterrupt, RuntimeError, etc.
https://github.com/python/cpython/blob/main/Modules/_csv.c#L500-L507
#define DIALECT_GETATTR(v, n) \ do { \ if (v == NULL) { \ v = PyObject_GetAttrString(dialect, n); \ if (v == NULL) \ PyErr_Clear(); \ } \ } while (0)
Only AttributeError (attribute not found) should be cleared. Other exceptions should propagate.
Reproducer
import csv, io class MyDialect: @property def delimiter(self): raise MemoryError("OOM") quotechar = '"' escapechar = None doublequote = True skipinitialspace = False quoting = csv.QUOTE_MINIMAL lineterminator = '\r\n' strict = False # Expected: raises MemoryError (was swallowed) w = csv.writer(io.StringIO(), dialect=MyDialect()) w.writerow(['a', 'b']) print(w.dialect.delimiter) # ','
All 8 dialect attributes are affected: delimiter, doublequote, escapechar, lineterminator, quotechar, quoting, skipinitialspace, strict.
Fix
#define DIALECT_GETATTR(v, n) \ do { \ if (v == NULL) { \ v = PyObject_GetAttrString(dialect, n); \ if (v == NULL) { \ if (PyErr_ExceptionMatches(PyExc_AttributeError)) \ PyErr_Clear(); \ else \ goto err; \ } \ } \ } while (0)
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux