summaryrefslogtreecommitdiffstats
path: root/Objects/exceptions.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-01-22 20:48:56 (GMT)
committerGitHub <noreply@github.com>2022-01-22 20:48:56 (GMT)
commitf1bcdeaca6e912a2bec1fbcff76cc49e7f761d38 (patch)
tree21cf3d580c398760d89d22242b11a890a831a552 /Objects/exceptions.c
parenta941e5927f7f2540946813606c61c6aea38db426 (diff)
downloadcpython-f1bcdeaca6e912a2bec1fbcff76cc49e7f761d38.zip
cpython-f1bcdeaca6e912a2bec1fbcff76cc49e7f761d38.tar.gz
cpython-f1bcdeaca6e912a2bec1fbcff76cc49e7f761d38.tar.bz2
bpo-46417: Factorize _PyExc_InitTypes() code (GH-30804)
Add 'static_exceptions' list to factorize code between _PyExc_InitTypes() and _PyBuiltins_AddExceptions(). _PyExc_InitTypes() does nothing if it's not the main interpreter. Sort exceptions in Lib/test/exception_hierarchy.txt.
Diffstat (limited to 'Objects/exceptions.c')
-rw-r--r--Objects/exceptions.c302
1 files changed, 132 insertions, 170 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 22a4713..f8f727c 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -3421,92 +3421,121 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning,
#endif
#endif /* MS_WINDOWS */
-PyStatus
+struct static_exception {
+ PyTypeObject *exc;
+ const char *name;
+};
+
+static struct static_exception static_exceptions[] = {
+#define ITEM(NAME) {&_PyExc_##NAME, #NAME}
+ // Level 1
+ ITEM(BaseException),
+
+ // Level 2: BaseException subclasses
+ ITEM(BaseExceptionGroup),
+ ITEM(Exception),
+ ITEM(GeneratorExit),
+ ITEM(KeyboardInterrupt),
+ ITEM(SystemExit),
+
+ // Level 3: Exception(BaseException) subclasses
+ ITEM(ArithmeticError),
+ ITEM(AssertionError),
+ ITEM(AttributeError),
+ ITEM(BufferError),
+ ITEM(EOFError),
+ //ITEM(ExceptionGroup),
+ ITEM(ImportError),
+ ITEM(LookupError),
+ ITEM(MemoryError),
+ ITEM(NameError),
+ ITEM(OSError),
+ ITEM(ReferenceError),
+ ITEM(RuntimeError),
+ ITEM(StopAsyncIteration),
+ ITEM(StopIteration),
+ ITEM(SyntaxError),
+ ITEM(SystemError),
+ ITEM(TypeError),
+ ITEM(ValueError),
+ ITEM(Warning),
+
+ // Level 4: ArithmeticError(Exception) subclasses
+ ITEM(FloatingPointError),
+ ITEM(OverflowError),
+ ITEM(ZeroDivisionError),
+
+ // Level 4: Warning(Exception) subclasses
+ ITEM(BytesWarning),
+ ITEM(DeprecationWarning),
+ ITEM(EncodingWarning),
+ ITEM(FutureWarning),
+ ITEM(ImportWarning),
+ ITEM(PendingDeprecationWarning),
+ ITEM(ResourceWarning),
+ ITEM(RuntimeWarning),
+ ITEM(SyntaxWarning),
+ ITEM(UnicodeWarning),
+ ITEM(UserWarning),
+
+ // Level 4: OSError(Exception) subclasses
+ ITEM(BlockingIOError),
+ ITEM(ChildProcessError),
+ ITEM(ConnectionError),
+ ITEM(FileExistsError),
+ ITEM(FileNotFoundError),
+ ITEM(InterruptedError),
+ ITEM(IsADirectoryError),
+ ITEM(NotADirectoryError),
+ ITEM(PermissionError),
+ ITEM(ProcessLookupError),
+ ITEM(TimeoutError),
+
+ // Level 4: Other subclasses
+ ITEM(IndentationError), // base: SyntaxError(Exception)
+ ITEM(IndexError), // base: LookupError(Exception)
+ ITEM(KeyError), // base: LookupError(Exception)
+ ITEM(ModuleNotFoundError), // base: ImportError(Exception)
+ ITEM(NotImplementedError), // base: RuntimeError(Exception)
+ ITEM(RecursionError), // base: RuntimeError(Exception)
+ ITEM(UnboundLocalError), // base: NameError(Exception)
+ ITEM(UnicodeError), // base: ValueError(Exception)
+
+ // Level 5: ConnectionError(OSError) subclasses
+ ITEM(BrokenPipeError),
+ ITEM(ConnectionAbortedError),
+ ITEM(ConnectionRefusedError),
+ ITEM(ConnectionResetError),
+
+ // Level 5: IndentationError(SyntaxError) subclasses
+ ITEM(TabError), // base: IndentationError
+
+ // Level 5: UnicodeError(ValueError) subclasses
+ ITEM(UnicodeDecodeError),
+ ITEM(UnicodeEncodeError),
+ ITEM(UnicodeTranslateError),
+#undef ITEM
+};
+
+
+int
_PyExc_InitTypes(PyInterpreterState *interp)
{
-#define PRE_INIT(TYPE) \
- if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
- if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
- return _PyStatus_ERR("exceptions bootstrapping error."); \
- } \
- Py_INCREF(PyExc_ ## TYPE); \
+ if (!_Py_IsMainInterpreter(interp)) {
+ return 0;
}
- PRE_INIT(BaseException);
- PRE_INIT(BaseExceptionGroup);
- PRE_INIT(Exception);
- PRE_INIT(TypeError);
- PRE_INIT(StopAsyncIteration);
- PRE_INIT(StopIteration);
- PRE_INIT(GeneratorExit);
- PRE_INIT(SystemExit);
- PRE_INIT(KeyboardInterrupt);
- PRE_INIT(ImportError);
- PRE_INIT(ModuleNotFoundError);
- PRE_INIT(OSError);
- PRE_INIT(EOFError);
- PRE_INIT(RuntimeError);
- PRE_INIT(RecursionError);
- PRE_INIT(NotImplementedError);
- PRE_INIT(NameError);
- PRE_INIT(UnboundLocalError);
- PRE_INIT(AttributeError);
- PRE_INIT(SyntaxError);
- PRE_INIT(IndentationError);
- PRE_INIT(TabError);
- PRE_INIT(LookupError);
- PRE_INIT(IndexError);
- PRE_INIT(KeyError);
- PRE_INIT(ValueError);
- PRE_INIT(UnicodeError);
- PRE_INIT(UnicodeEncodeError);
- PRE_INIT(UnicodeDecodeError);
- PRE_INIT(UnicodeTranslateError);
- PRE_INIT(AssertionError);
- PRE_INIT(ArithmeticError);
- PRE_INIT(FloatingPointError);
- PRE_INIT(OverflowError);
- PRE_INIT(ZeroDivisionError);
- PRE_INIT(SystemError);
- PRE_INIT(ReferenceError);
- PRE_INIT(MemoryError);
- PRE_INIT(BufferError);
- PRE_INIT(Warning);
- PRE_INIT(UserWarning);
- PRE_INIT(EncodingWarning);
- PRE_INIT(DeprecationWarning);
- PRE_INIT(PendingDeprecationWarning);
- PRE_INIT(SyntaxWarning);
- PRE_INIT(RuntimeWarning);
- PRE_INIT(FutureWarning);
- PRE_INIT(ImportWarning);
- PRE_INIT(UnicodeWarning);
- PRE_INIT(BytesWarning);
- PRE_INIT(ResourceWarning);
-
- /* OSError subclasses */
- PRE_INIT(ConnectionError);
-
- PRE_INIT(BlockingIOError);
- PRE_INIT(BrokenPipeError);
- PRE_INIT(ChildProcessError);
- PRE_INIT(ConnectionAbortedError);
- PRE_INIT(ConnectionRefusedError);
- PRE_INIT(ConnectionResetError);
- PRE_INIT(FileExistsError);
- PRE_INIT(FileNotFoundError);
- PRE_INIT(IsADirectoryError);
- PRE_INIT(NotADirectoryError);
- PRE_INIT(InterruptedError);
- PRE_INIT(PermissionError);
- PRE_INIT(ProcessLookupError);
- PRE_INIT(TimeoutError);
+ for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
+ PyTypeObject *exc = static_exceptions[i].exc;
- return _PyStatus_OK();
-
-#undef PRE_INIT
+ if (PyType_Ready(exc) < 0) {
+ return -1;
+ }
+ }
+ return 0;
}
+
PyStatus
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
{
@@ -3569,12 +3598,28 @@ _PyExc_InitState(PyInterpreterState *interp)
/* Add exception types to the builtins module */
-PyStatus
+int
_PyBuiltins_AddExceptions(PyObject *bltinmod)
{
-#define POST_INIT(TYPE) \
- if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \
- return _PyStatus_ERR("Module dictionary insertion problem."); \
+ PyObject *mod_dict = PyModule_GetDict(bltinmod);
+ if (mod_dict == NULL) {
+ return -1;
+ }
+
+ for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
+ struct static_exception item = static_exceptions[i];
+
+ if (PyDict_SetItemString(mod_dict, item.name, (PyObject*)item.exc)) {
+ return -1;
+ }
+ }
+
+ PyObject *PyExc_ExceptionGroup = create_exception_group_class();
+ if (!PyExc_ExceptionGroup) {
+ return -1;
+ }
+ if (PyDict_SetItemString(mod_dict, "ExceptionGroup", PyExc_ExceptionGroup)) {
+ return -1;
}
#define INIT_ALIAS(NAME, TYPE) \
@@ -3582,103 +3627,20 @@ _PyBuiltins_AddExceptions(PyObject *bltinmod)
Py_INCREF(PyExc_ ## TYPE); \
Py_XDECREF(PyExc_ ## NAME); \
PyExc_ ## NAME = PyExc_ ## TYPE; \
- if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \
- return _PyStatus_ERR("Module dictionary insertion problem."); \
+ if (PyDict_SetItemString(mod_dict, # NAME, PyExc_ ## NAME)) { \
+ return -1; \
} \
} while (0)
- PyObject *bdict;
-
- bdict = PyModule_GetDict(bltinmod);
- if (bdict == NULL) {
- return _PyStatus_ERR("exceptions bootstrapping error.");
- }
-
- PyObject *PyExc_ExceptionGroup = create_exception_group_class();
- if (!PyExc_ExceptionGroup) {
- return _PyStatus_ERR("exceptions bootstrapping error.");
- }
-
- POST_INIT(BaseException);
- POST_INIT(Exception);
- POST_INIT(BaseExceptionGroup);
- POST_INIT(ExceptionGroup);
- POST_INIT(TypeError);
- POST_INIT(StopAsyncIteration);
- POST_INIT(StopIteration);
- POST_INIT(GeneratorExit);
- POST_INIT(SystemExit);
- POST_INIT(KeyboardInterrupt);
- POST_INIT(ImportError);
- POST_INIT(ModuleNotFoundError);
- POST_INIT(OSError);
INIT_ALIAS(EnvironmentError, OSError);
INIT_ALIAS(IOError, OSError);
#ifdef MS_WINDOWS
INIT_ALIAS(WindowsError, OSError);
#endif
- POST_INIT(EOFError);
- POST_INIT(RuntimeError);
- POST_INIT(RecursionError);
- POST_INIT(NotImplementedError);
- POST_INIT(NameError);
- POST_INIT(UnboundLocalError);
- POST_INIT(AttributeError);
- POST_INIT(SyntaxError);
- POST_INIT(IndentationError);
- POST_INIT(TabError);
- POST_INIT(LookupError);
- POST_INIT(IndexError);
- POST_INIT(KeyError);
- POST_INIT(ValueError);
- POST_INIT(UnicodeError);
- POST_INIT(UnicodeEncodeError);
- POST_INIT(UnicodeDecodeError);
- POST_INIT(UnicodeTranslateError);
- POST_INIT(AssertionError);
- POST_INIT(ArithmeticError);
- POST_INIT(FloatingPointError);
- POST_INIT(OverflowError);
- POST_INIT(ZeroDivisionError);
- POST_INIT(SystemError);
- POST_INIT(ReferenceError);
- POST_INIT(MemoryError);
- POST_INIT(BufferError);
- POST_INIT(Warning);
- POST_INIT(UserWarning);
- POST_INIT(EncodingWarning);
- POST_INIT(DeprecationWarning);
- POST_INIT(PendingDeprecationWarning);
- POST_INIT(SyntaxWarning);
- POST_INIT(RuntimeWarning);
- POST_INIT(FutureWarning);
- POST_INIT(ImportWarning);
- POST_INIT(UnicodeWarning);
- POST_INIT(BytesWarning);
- POST_INIT(ResourceWarning);
-
- /* OSError subclasses */
- POST_INIT(ConnectionError);
-
- POST_INIT(BlockingIOError);
- POST_INIT(BrokenPipeError);
- POST_INIT(ChildProcessError);
- POST_INIT(ConnectionAbortedError);
- POST_INIT(ConnectionRefusedError);
- POST_INIT(ConnectionResetError);
- POST_INIT(FileExistsError);
- POST_INIT(FileNotFoundError);
- POST_INIT(IsADirectoryError);
- POST_INIT(NotADirectoryError);
- POST_INIT(InterruptedError);
- POST_INIT(PermissionError);
- POST_INIT(ProcessLookupError);
- POST_INIT(TimeoutError);
-
- return _PyStatus_OK();
-#undef POST_INIT
#undef INIT_ALIAS
+
+ return 0;
}
void