From bf4ac2d2fd520c61306b2676db488adab9b5d8c5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 22 Jan 2019 17:39:03 +0100 Subject: 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(). --- Doc/whatsnew/3.8.rst | 4 + Include/cpython/pylifecycle.h | 27 -- Include/internal/pycore_pylifecycle.h | 39 +- .../C API/2019-01-22-17-04-10.bpo-35713.fmehdG.rst | 3 + Objects/bytearrayobject.c | 11 - Objects/exceptions.c | 395 +++++++++++---------- Objects/unicodeobject.c | 32 +- Python/pylifecycle.c | 35 +- Python/sysmodule.c | 16 - 9 files changed, 290 insertions(+), 272 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-01-22-17-04-10.bpo-35713.fmehdG.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 0360be6..8b38cce 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -328,6 +328,10 @@ Optimizations Build and C API Changes ======================= +* The :c:func:`PyByteArray_Init` and :c:func:`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. + * The result of :c:func:`PyExceptionClass_Name` is now of type ``const char *`` rather of ``char *``. (Contributed by Serhiy Storchaka in :issue:`33818`.) diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index 3009c4f..a3fdeef 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -56,33 +56,6 @@ PyAPI_FUNC(void) _Py_SetProgramFullPath(const wchar_t *); PyAPI_FUNC(const char *) _Py_gitidentifier(void); PyAPI_FUNC(const char *) _Py_gitversion(void); -/* Internal -- various one-time initializations */ -PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); -PyAPI_FUNC(_PyInitError) _PySys_BeginInit(PyObject **sysmod); -PyAPI_FUNC(int) _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp); -PyAPI_FUNC(_PyInitError) _PyImport_Init(PyInterpreterState *interp); -PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); -PyAPI_FUNC(_PyInitError) _PyImportHooks_Init(void); -PyAPI_FUNC(int) _PyFloat_Init(void); -PyAPI_FUNC(int) PyByteArray_Init(void); -PyAPI_FUNC(_PyInitError) _Py_HashRandomization_Init(const _PyCoreConfig *); - -/* Various internal finalizers */ - -PyAPI_FUNC(void) PyMethod_Fini(void); -PyAPI_FUNC(void) PyFrame_Fini(void); -PyAPI_FUNC(void) PyCFunction_Fini(void); -PyAPI_FUNC(void) PyDict_Fini(void); -PyAPI_FUNC(void) PyTuple_Fini(void); -PyAPI_FUNC(void) PyList_Fini(void); -PyAPI_FUNC(void) PySet_Fini(void); -PyAPI_FUNC(void) PyBytes_Fini(void); -PyAPI_FUNC(void) PyByteArray_Fini(void); -PyAPI_FUNC(void) PyFloat_Fini(void); -PyAPI_FUNC(void) PyOS_FiniInterrupts(void); -PyAPI_FUNC(void) PySlice_Fini(void); -PyAPI_FUNC(void) PyAsyncGen_Fini(void); - PyAPI_FUNC(int) _Py_IsFinalizing(void); /* Random */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index e104316..de70199 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -19,20 +19,45 @@ PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void); PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); -extern int _PyUnicode_Init(void); +/* Various one-time initializers */ + +extern _PyInitError _PyUnicode_Init(void); extern int _PyStructSequence_Init(void); extern int _PyLong_Init(void); extern _PyInitError _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); +extern PyObject * _PyBuiltin_Init(void); +extern _PyInitError _PySys_BeginInit(PyObject **sysmod); +extern int _PySys_EndInit(PyObject *sysdict, PyInterpreterState *interp); +extern _PyInitError _PyImport_Init(PyInterpreterState *interp); +extern _PyInitError _PyExc_Init(PyObject * bltinmod); +extern _PyInitError _PyImportHooks_Init(void); +extern int _PyFloat_Init(void); +extern _PyInitError _Py_HashRandomization_Init(const _PyCoreConfig *); extern void _Py_ReadyTypes(void); -PyAPI_FUNC(void) _PyExc_Fini(void); -PyAPI_FUNC(void) _PyImport_Fini(void); -PyAPI_FUNC(void) _PyImport_Fini2(void); -PyAPI_FUNC(void) _PyGC_Fini(void); -PyAPI_FUNC(void) _PyType_Fini(void); -PyAPI_FUNC(void) _Py_HashRandomization_Fini(void); +/* Various internal finalizers */ + +extern void PyMethod_Fini(void); +extern void PyFrame_Fini(void); +extern void PyCFunction_Fini(void); +extern void PyDict_Fini(void); +extern void PyTuple_Fini(void); +extern void PyList_Fini(void); +extern void PySet_Fini(void); +extern void PyBytes_Fini(void); +extern void PyFloat_Fini(void); +extern void PyOS_FiniInterrupts(void); +extern void PySlice_Fini(void); +extern void PyAsyncGen_Fini(void); + +extern void _PyExc_Fini(void); +extern void _PyImport_Fini(void); +extern void _PyImport_Fini2(void); +extern void _PyGC_Fini(void); +extern void _PyType_Fini(void); +extern void _Py_HashRandomization_Fini(void); extern void _PyUnicode_Fini(void); extern void PyLong_Fini(void); extern void _PyFaulthandler_Fini(void); diff --git a/Misc/NEWS.d/next/C API/2019-01-22-17-04-10.bpo-35713.fmehdG.rst b/Misc/NEWS.d/next/C API/2019-01-22-17-04-10.bpo-35713.fmehdG.rst new file mode 100644 index 0000000..f95ceca --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-01-22-17-04-10.bpo-35713.fmehdG.rst @@ -0,0 +1,3 @@ +The :c:func:`PyByteArray_Init` and :c:func:`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. 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 /* 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 */ diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 37ecc51..f0e00ea 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -608,9 +608,6 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, if (!_PyLong_Init()) return _Py_INIT_ERR("can't init longs"); - if (!PyByteArray_Init()) - return _Py_INIT_ERR("can't init bytearray"); - if (!_PyFloat_Init()) return _Py_INIT_ERR("can't init float"); @@ -634,9 +631,10 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, PyDict_SetItemString(interp->sysdict, "modules", modules); _PyImport_FixupBuiltin(sysmod, "sys", modules); - /* Init Unicode implementation; relies on the codec registry */ - if (_PyUnicode_Init() < 0) - return _Py_INIT_ERR("can't initialize unicode"); + err = _PyUnicode_Init(); + if (_Py_INIT_FAILED(err)) { + return err; + } if (_PyStructSequence_Init() < 0) return _Py_INIT_ERR("can't initialize structseq"); @@ -651,7 +649,10 @@ _Py_InitializeCore_impl(PyInterpreterState **interp_p, Py_INCREF(interp->builtins); /* initialize builtin exceptions */ - _PyExc_Init(bimod); + err = _PyExc_Init(bimod); + if (_Py_INIT_FAILED(err)) { + return err; + } /* Set up a preliminary stderr printer until we have enough infrastructure for the io module in place. */ @@ -1146,7 +1147,6 @@ Py_FinalizeEx(void) PyList_Fini(); PySet_Fini(); PyBytes_Fini(); - PyByteArray_Fini(); PyLong_Fini(); PyFloat_Fini(); PyDict_Fini(); @@ -1302,7 +1302,10 @@ new_interpreter(PyThreadState **tstate_p) } /* initialize builtin exceptions */ - _PyExc_Init(bimod); + err = _PyExc_Init(bimod); + if (_Py_INIT_FAILED(err)) { + return err; + } if (bimod != NULL && sysmod != NULL) { PyObject *pstderr; @@ -1682,6 +1685,20 @@ init_sys_streams(PyInterpreterState *interp) _PyInitError res = _Py_INIT_OK(); _PyCoreConfig *config = &interp->core_config; + /* Check that stdin is not a directory + Using shell redirection, you can redirect stdin to a directory, + crashing the Python interpreter. Catch this common mistake here + and output a useful error message. Note that under MS Windows, + the shell already prevents that. */ +#ifndef MS_WINDOWS + struct _Py_stat_struct sb; + if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && + S_ISDIR(sb.st_mode)) { + return _Py_INIT_USER_ERR(" is a directory, " + "cannot continue"); + } +#endif + char *codec_name = get_codec_name(config->stdio_encoding); if (codec_name == NULL) { return _Py_INIT_ERR("failed to get the Python codec name " diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 5ea3772..8efe169 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -2381,22 +2381,6 @@ _PySys_BeginInit(PyObject **sysmod) } sysdict = PyModule_GetDict(m); - /* Check that stdin is not a directory - Using shell redirection, you can redirect stdin to a directory, - crashing the Python interpreter. Catch this common mistake here - and output a useful error message. Note that under MS Windows, - the shell already prevents that. */ -#ifndef MS_WINDOWS - { - struct _Py_stat_struct sb; - if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && - S_ISDIR(sb.st_mode)) { - return _Py_INIT_USER_ERR(" is a directory, " - "cannot continue"); - } - } -#endif - /* stdin/stdout/stderr are set in pylifecycle.c */ SET_SYS_FROM_STRING_BORROW("__displayhook__", -- cgit v0.12