mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
a941e5927f
commit
f1bcdeaca6
|
@ -13,7 +13,7 @@ extern "C" {
|
|||
|
||||
extern PyStatus _PyExc_InitState(PyInterpreterState *);
|
||||
extern PyStatus _PyExc_InitGlobalObjects(PyInterpreterState *);
|
||||
extern PyStatus _PyExc_InitTypes(PyInterpreterState *);
|
||||
extern int _PyExc_InitTypes(PyInterpreterState *);
|
||||
extern void _PyExc_Fini(PyInterpreterState *);
|
||||
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
|
|||
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
|
||||
extern int _PySys_UpdateConfig(PyThreadState *tstate);
|
||||
extern void _PySys_Fini(PyInterpreterState *interp);
|
||||
extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
||||
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
|
||||
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
|
||||
|
||||
extern PyStatus _PyImportZip_Init(PyThreadState *tstate);
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
BaseException
|
||||
├── SystemExit
|
||||
├── KeyboardInterrupt
|
||||
├── GeneratorExit
|
||||
├── BaseExceptionGroup
|
||||
├── GeneratorExit
|
||||
├── KeyboardInterrupt
|
||||
├── SystemExit
|
||||
└── Exception
|
||||
├── ExceptionGroup [BaseExceptionGroup]
|
||||
├── StopIteration
|
||||
├── StopAsyncIteration
|
||||
├── ArithmeticError
|
||||
│ ├── FloatingPointError
|
||||
│ ├── OverflowError
|
||||
|
@ -15,6 +12,7 @@ BaseException
|
|||
├── AttributeError
|
||||
├── BufferError
|
||||
├── EOFError
|
||||
├── ExceptionGroup [BaseExceptionGroup]
|
||||
├── ImportError
|
||||
│ └── ModuleNotFoundError
|
||||
├── LookupError
|
||||
|
@ -43,6 +41,8 @@ BaseException
|
|||
├── RuntimeError
|
||||
│ ├── NotImplementedError
|
||||
│ └── RecursionError
|
||||
├── StopAsyncIteration
|
||||
├── StopIteration
|
||||
├── SyntaxError
|
||||
│ └── IndentationError
|
||||
│ └── TabError
|
||||
|
@ -54,14 +54,14 @@ BaseException
|
|||
│ ├── UnicodeEncodeError
|
||||
│ └── UnicodeTranslateError
|
||||
└── Warning
|
||||
├── BytesWarning
|
||||
├── DeprecationWarning
|
||||
├── PendingDeprecationWarning
|
||||
├── RuntimeWarning
|
||||
├── SyntaxWarning
|
||||
├── UserWarning
|
||||
├── EncodingWarning
|
||||
├── FutureWarning
|
||||
├── ImportWarning
|
||||
├── PendingDeprecationWarning
|
||||
├── ResourceWarning
|
||||
├── RuntimeWarning
|
||||
├── SyntaxWarning
|
||||
├── UnicodeWarning
|
||||
├── BytesWarning
|
||||
├── EncodingWarning
|
||||
└── ResourceWarning
|
||||
└── UserWarning
|
||||
|
|
|
@ -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);
|
||||
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
|
||||
PyTypeObject *exc = static_exceptions[i].exc;
|
||||
|
||||
/* 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);
|
||||
|
||||
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
|
||||
|
|
|
@ -740,9 +740,8 @@ pycore_init_types(PyInterpreterState *interp)
|
|||
return status;
|
||||
}
|
||||
|
||||
status = _PyExc_InitTypes(interp);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
if (_PyExc_InitTypes(interp) < 0) {
|
||||
return _PyStatus_ERR("failed to initialize an exception type");
|
||||
}
|
||||
|
||||
status = _PyExc_InitGlobalObjects(interp);
|
||||
|
@ -790,9 +789,8 @@ pycore_init_builtins(PyThreadState *tstate)
|
|||
Py_INCREF(builtins_dict);
|
||||
interp->builtins = builtins_dict;
|
||||
|
||||
PyStatus status = _PyBuiltins_AddExceptions(bimod);
|
||||
if (_PyStatus_EXCEPTION(status)) {
|
||||
return status;
|
||||
if (_PyBuiltins_AddExceptions(bimod) < 0) {
|
||||
return _PyStatus_ERR("failed to add exceptions to builtins");
|
||||
}
|
||||
|
||||
interp->builtins_copy = PyDict_Copy(interp->builtins);
|
||||
|
|
Loading…
Reference in New Issue