diff options
author | Victor Stinner <vstinner@python.org> | 2022-01-22 20:48:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-22 20:48:56 (GMT) |
commit | f1bcdeaca6e912a2bec1fbcff76cc49e7f761d38 (patch) | |
tree | 21cf3d580c398760d89d22242b11a890a831a552 /Objects/exceptions.c | |
parent | a941e5927f7f2540946813606c61c6aea38db426 (diff) | |
download | cpython-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.c | 302 |
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 |