diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-01-22 16:39:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-22 16:39:03 (GMT) |
commit | bf4ac2d2fd520c61306b2676db488adab9b5d8c5 (patch) | |
tree | 36b7680e9ac88256ba0f3beeb834c677a20914f8 /Objects | |
parent | 35ca1820e19f81f69073f294503cdcd708fe490f (diff) | |
download | cpython-bf4ac2d2fd520c61306b2676db488adab9b5d8c5.zip cpython-bf4ac2d2fd520c61306b2676db488adab9b5d8c5.tar.gz cpython-bf4ac2d2fd520c61306b2676db488adab9b5d8c5.tar.bz2 |
bpo-35713: Rework Python initialization (GH-11647)
* The PyByteArray_Init() and PyByteArray_Fini() functions have been
removed. They did nothing since Python 2.7.4 and Python 3.2.0, were
excluded from the limited API (stable ABI), and were not
documented.
* Move "_PyXXX_Init()" and "_PyXXX_Fini()" declarations from
Include/cpython/pylifecycle.h to
Include/internal/pycore_pylifecycle.h. Replace
"PyAPI_FUNC(TYPE)" with "extern TYPE".
* _PyExc_Init() now returns an error on failure rather than calling
Py_FatalError(). Move macros inside _PyExc_Init() and undefine them
when done. Rewrite macros to make them look more like statement:
add ";" when using them, add "do { ... } while (0)".
* _PyUnicode_Init() now returns a _PyInitError error rather than call
Py_FatalError().
* Move stdin check from _PySys_BeginInit() to init_sys_streams().
* _Py_ReadyTypes() now returns a _PyInitError error rather than
calling Py_FatalError().
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/bytearrayobject.c | 11 | ||||
-rw-r--r-- | Objects/exceptions.c | 395 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 32 |
3 files changed, 225 insertions, 213 deletions
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 3926095..6672136 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -17,17 +17,6 @@ class bytearray "PyByteArrayObject *" "&PyByteArray_Type" char _PyByteArray_empty_string[] = ""; -void -PyByteArray_Fini(void) -{ -} - -int -PyByteArray_Init(void) -{ - return 1; -} - /* end nullbytes support */ /* Helpers */ diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 002a602..8d81566 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2299,7 +2299,7 @@ MemoryError_dealloc(PyBaseExceptionObject *self) } } -static void +static int preallocate_memerrors(void) { /* We create enough MemoryErrors and then decref them, which will fill @@ -2309,12 +2309,14 @@ preallocate_memerrors(void) for (i = 0; i < MEMERRORS_SAVE; i++) { errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError, NULL, NULL); - if (!errors[i]) - Py_FatalError("Could not preallocate MemoryError object"); + if (!errors[i]) { + return -1; + } } for (i = 0; i < MEMERRORS_SAVE; i++) { Py_DECREF(errors[i]); } + return 0; } static void @@ -2433,31 +2435,6 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, -#define PRE_INIT(TYPE) \ - if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ - if (PyType_Ready(&_PyExc_ ## TYPE) < 0) \ - Py_FatalError("exceptions bootstrapping error."); \ - Py_INCREF(PyExc_ ## TYPE); \ - } - -#define POST_INIT(TYPE) \ - if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) \ - Py_FatalError("Module dictionary insertion problem."); - -#define INIT_ALIAS(NAME, TYPE) Py_INCREF(PyExc_ ## TYPE); \ - Py_XDECREF(PyExc_ ## NAME); \ - PyExc_ ## NAME = PyExc_ ## TYPE; \ - if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) \ - Py_FatalError("Module dictionary insertion problem."); - -#define ADD_ERRNO(TYPE, CODE) { \ - PyObject *_code = PyLong_FromLong(CODE); \ - assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \ - if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \ - Py_FatalError("errmap insertion problem."); \ - Py_DECREF(_code); \ - } - #ifdef MS_WINDOWS #include <winsock2.h> /* The following constants were added to errno.h in VS2010 but have @@ -2514,184 +2491,226 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, #endif #endif /* MS_WINDOWS */ -void +_PyInitError _PyExc_Init(PyObject *bltinmod) { +#define PRE_INIT(TYPE) \ + if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \ + if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \ + return _Py_INIT_ERR("exceptions bootstrapping error."); \ + } \ + Py_INCREF(PyExc_ ## TYPE); \ + } + +#define POST_INIT(TYPE) \ + if (PyDict_SetItemString(bdict, # TYPE, PyExc_ ## TYPE)) { \ + return _Py_INIT_ERR("Module dictionary insertion problem."); \ + } + +#define INIT_ALIAS(NAME, TYPE) \ + do { \ + Py_INCREF(PyExc_ ## TYPE); \ + Py_XDECREF(PyExc_ ## NAME); \ + PyExc_ ## NAME = PyExc_ ## TYPE; \ + if (PyDict_SetItemString(bdict, # NAME, PyExc_ ## NAME)) { \ + return _Py_INIT_ERR("Module dictionary insertion problem."); \ + } \ + } while (0) + +#define ADD_ERRNO(TYPE, CODE) \ + do { \ + PyObject *_code = PyLong_FromLong(CODE); \ + assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \ + if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \ + return _Py_INIT_ERR("errmap insertion problem."); \ + Py_DECREF(_code); \ + } while (0) + PyObject *bdict; - PRE_INIT(BaseException) - 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(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) + PRE_INIT(BaseException); + 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(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) + 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); bdict = PyModule_GetDict(bltinmod); - if (bdict == NULL) - Py_FatalError("exceptions bootstrapping error."); - - POST_INIT(BaseException) - POST_INIT(Exception) - 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) + if (bdict == NULL) { + return _Py_INIT_ERR("exceptions bootstrapping error."); + } + + POST_INIT(BaseException); + POST_INIT(Exception); + 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) + 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(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) + 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(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); if (!errnomap) { errnomap = PyDict_New(); - if (!errnomap) - Py_FatalError("Cannot allocate map from errnos to OSError subclasses"); + if (!errnomap) { + return _Py_INIT_ERR("Cannot allocate map from errnos to OSError subclasses"); + } } /* OSError subclasses */ - POST_INIT(ConnectionError) - - POST_INIT(BlockingIOError) - ADD_ERRNO(BlockingIOError, EAGAIN) - ADD_ERRNO(BlockingIOError, EALREADY) - ADD_ERRNO(BlockingIOError, EINPROGRESS) - ADD_ERRNO(BlockingIOError, EWOULDBLOCK) - POST_INIT(BrokenPipeError) - ADD_ERRNO(BrokenPipeError, EPIPE) + POST_INIT(ConnectionError); + + POST_INIT(BlockingIOError); + ADD_ERRNO(BlockingIOError, EAGAIN); + ADD_ERRNO(BlockingIOError, EALREADY); + ADD_ERRNO(BlockingIOError, EINPROGRESS); + ADD_ERRNO(BlockingIOError, EWOULDBLOCK); + POST_INIT(BrokenPipeError); + ADD_ERRNO(BrokenPipeError, EPIPE); #ifdef ESHUTDOWN - ADD_ERRNO(BrokenPipeError, ESHUTDOWN) + ADD_ERRNO(BrokenPipeError, ESHUTDOWN); #endif - POST_INIT(ChildProcessError) - ADD_ERRNO(ChildProcessError, ECHILD) - POST_INIT(ConnectionAbortedError) - ADD_ERRNO(ConnectionAbortedError, ECONNABORTED) - POST_INIT(ConnectionRefusedError) - ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED) - POST_INIT(ConnectionResetError) - ADD_ERRNO(ConnectionResetError, ECONNRESET) - POST_INIT(FileExistsError) - ADD_ERRNO(FileExistsError, EEXIST) - POST_INIT(FileNotFoundError) - ADD_ERRNO(FileNotFoundError, ENOENT) - POST_INIT(IsADirectoryError) - ADD_ERRNO(IsADirectoryError, EISDIR) - POST_INIT(NotADirectoryError) - ADD_ERRNO(NotADirectoryError, ENOTDIR) - POST_INIT(InterruptedError) - ADD_ERRNO(InterruptedError, EINTR) - POST_INIT(PermissionError) - ADD_ERRNO(PermissionError, EACCES) - ADD_ERRNO(PermissionError, EPERM) - POST_INIT(ProcessLookupError) - ADD_ERRNO(ProcessLookupError, ESRCH) - POST_INIT(TimeoutError) - ADD_ERRNO(TimeoutError, ETIMEDOUT) - - preallocate_memerrors(); + POST_INIT(ChildProcessError); + ADD_ERRNO(ChildProcessError, ECHILD); + POST_INIT(ConnectionAbortedError); + ADD_ERRNO(ConnectionAbortedError, ECONNABORTED); + POST_INIT(ConnectionRefusedError); + ADD_ERRNO(ConnectionRefusedError, ECONNREFUSED); + POST_INIT(ConnectionResetError); + ADD_ERRNO(ConnectionResetError, ECONNRESET); + POST_INIT(FileExistsError); + ADD_ERRNO(FileExistsError, EEXIST); + POST_INIT(FileNotFoundError); + ADD_ERRNO(FileNotFoundError, ENOENT); + POST_INIT(IsADirectoryError); + ADD_ERRNO(IsADirectoryError, EISDIR); + POST_INIT(NotADirectoryError); + ADD_ERRNO(NotADirectoryError, ENOTDIR); + POST_INIT(InterruptedError); + ADD_ERRNO(InterruptedError, EINTR); + POST_INIT(PermissionError); + ADD_ERRNO(PermissionError, EACCES); + ADD_ERRNO(PermissionError, EPERM); + POST_INIT(ProcessLookupError); + ADD_ERRNO(ProcessLookupError, ESRCH); + POST_INIT(TimeoutError); + ADD_ERRNO(TimeoutError, ETIMEDOUT); + + if (preallocate_memerrors() < 0) { + return _Py_INIT_ERR("Could not preallocate MemoryError object"); + } + return _Py_INIT_OK(); + +#undef PRE_INIT +#undef POST_INIT +#undef INIT_ALIAS +#undef ADD_ERRNO } void diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f1d23b6..ea7bcab 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15199,7 +15199,8 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -int _PyUnicode_Init(void) +_PyInitError +_PyUnicode_Init(void) { /* XXX - move this array to unicodectype.c ? */ Py_UCS2 linebreak[] = { @@ -15215,28 +15216,31 @@ int _PyUnicode_Init(void) /* Init the implementation */ _Py_INCREF_UNICODE_EMPTY(); - if (!unicode_empty) - Py_FatalError("Can't create empty string"); + if (!unicode_empty) { + return _Py_INIT_ERR("Can't create empty string"); + } Py_DECREF(unicode_empty); - if (PyType_Ready(&PyUnicode_Type) < 0) - Py_FatalError("Can't initialize 'unicode'"); + if (PyType_Ready(&PyUnicode_Type) < 0) { + return _Py_INIT_ERR("Can't initialize unicode type"); + } /* initialize the linebreak bloom filter */ bloom_linebreak = make_bloom_mask( PyUnicode_2BYTE_KIND, linebreak, Py_ARRAY_LENGTH(linebreak)); - if (PyType_Ready(&EncodingMapType) < 0) - Py_FatalError("Can't initialize encoding map type"); - - if (PyType_Ready(&PyFieldNameIter_Type) < 0) - Py_FatalError("Can't initialize field name iterator type"); - - if (PyType_Ready(&PyFormatterIter_Type) < 0) - Py_FatalError("Can't initialize formatter iter type"); + if (PyType_Ready(&EncodingMapType) < 0) { + return _Py_INIT_ERR("Can't initialize encoding map type"); + } + if (PyType_Ready(&PyFieldNameIter_Type) < 0) { + return _Py_INIT_ERR("Can't initialize field name iterator type"); + } + if (PyType_Ready(&PyFormatterIter_Type) < 0) { + return _Py_INIT_ERR("Can't initialize formatter iter type"); + } - return 0; + return _Py_INIT_OK(); } /* Finalize the Unicode implementation */ |