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().
This commit is contained in:
Victor Stinner 2019-01-22 17:39:03 +01:00 committed by GitHub
parent 35ca1820e1
commit bf4ac2d2fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 286 additions and 268 deletions

View file

@ -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 */

View file

@ -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(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(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.");
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)
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(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(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)
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();
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

View file

@ -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(&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");
}
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");
return 0;
return _Py_INIT_OK();
}
/* Finalize the Unicode implementation */