mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 11:49:12 +00:00 
			
		
		
		
	Move the following private functions and structures to pycore_modsupport.h internal C API: * _PyArg_BadArgument() * _PyArg_CheckPositional() * _PyArg_NoKeywords() * _PyArg_NoPositional() * _PyArg_ParseStack() * _PyArg_ParseStackAndKeywords() * _PyArg_Parser structure * _PyArg_UnpackKeywords() * _PyArg_UnpackKeywordsWithVararg() * _PyArg_UnpackStack() * _Py_ANY_VARARGS() Changes: * Python/getargs.h now includes pycore_modsupport.h to export functions. * clinic.py now adds pycore_modsupport.h when one of these functions is used. * Add pycore_modsupport.h includes when a C extension uses one of these functions. * Define Py_BUILD_CORE_MODULE in C extensions which now include directly or indirectly (via code generated by Argument Clinic) pycore_modsupport.h: * _csv * _curses_panel * _dbm * _gdbm * _multiprocessing.posixshmem * _sqlite.row * _statistics * grp * resource * syslog * _testcapi: bad_get() no longer uses METH_FASTCALL calling convention but METH_VARARGS. Replace _PyArg_UnpackStack() with PyArg_ParseTuple(). * _testcapi: add PYTESTCAPI_NEED_INTERNAL_API macro which is defined by _testcapi sub-modules which need the internal C API (pycore_modsupport.h): exceptions.c, float.c, vectorcall.c, watchers.c. * Remove Include/cpython/modsupport.h header file. Include/modsupport.h no longer includes the removed header file. * Fix mypy clinic.py
		
			
				
	
	
		
			385 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			385 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// clinic/exceptions.c.h uses internal pycore_modsupport.h API
 | 
						|
#define PYTESTCAPI_NEED_INTERNAL_API
 | 
						|
 | 
						|
#include "parts.h"
 | 
						|
#include "util.h"
 | 
						|
#include "clinic/exceptions.c.h"
 | 
						|
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
module _testcapi
 | 
						|
[clinic start generated code]*/
 | 
						|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.err_set_raised
 | 
						|
    exception as exc: object
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_err_set_raised(PyObject *module, PyObject *exc)
 | 
						|
/*[clinic end generated code: output=0a0c7743961fcae5 input=c5f7331864a94df9]*/
 | 
						|
{
 | 
						|
    Py_INCREF(exc);
 | 
						|
    PyErr_SetRaisedException(exc);
 | 
						|
    assert(PyErr_Occurred());
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
err_restore(PyObject *self, PyObject *args) {
 | 
						|
    PyObject *type = NULL, *value = NULL, *traceback = NULL;
 | 
						|
    switch(PyTuple_Size(args)) {
 | 
						|
        case 3:
 | 
						|
            traceback = PyTuple_GetItem(args, 2);
 | 
						|
            Py_INCREF(traceback);
 | 
						|
            /* fall through */
 | 
						|
        case 2:
 | 
						|
            value = PyTuple_GetItem(args, 1);
 | 
						|
            Py_INCREF(value);
 | 
						|
            /* fall through */
 | 
						|
        case 1:
 | 
						|
            type = PyTuple_GetItem(args, 0);
 | 
						|
            Py_INCREF(type);
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            PyErr_SetString(PyExc_TypeError,
 | 
						|
                        "wrong number of arguments");
 | 
						|
            return NULL;
 | 
						|
    }
 | 
						|
    PyErr_Restore(type, value, traceback);
 | 
						|
    assert(PyErr_Occurred());
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.exception_print
 | 
						|
    exception as exc: object
 | 
						|
    legacy: bool = False
 | 
						|
    /
 | 
						|
 | 
						|
To test the format of exceptions as printed out.
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy)
 | 
						|
/*[clinic end generated code: output=3f04fe0c18412ae0 input=c76f42cb94136dbf]*/
 | 
						|
{
 | 
						|
    if (legacy) {
 | 
						|
        PyObject *tb = NULL;
 | 
						|
        if (PyExceptionInstance_Check(exc)) {
 | 
						|
            tb = PyException_GetTraceback(exc);
 | 
						|
        }
 | 
						|
        PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb);
 | 
						|
        Py_XDECREF(tb);
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        PyErr_DisplayException(exc);
 | 
						|
    }
 | 
						|
    Py_RETURN_NONE;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.make_exception_with_doc
 | 
						|
    name: str
 | 
						|
    doc: str = NULL
 | 
						|
    base: object = NULL
 | 
						|
    dict: object = NULL
 | 
						|
 | 
						|
Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_make_exception_with_doc_impl(PyObject *module, const char *name,
 | 
						|
                                       const char *doc, PyObject *base,
 | 
						|
                                       PyObject *dict)
 | 
						|
/*[clinic end generated code: output=439f0d963c1ce2c4 input=23a73013f8a8795a]*/
 | 
						|
{
 | 
						|
    return PyErr_NewExceptionWithDoc(name, doc, base, dict);
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.exc_set_object
 | 
						|
    exception as exc: object
 | 
						|
    obj: object
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj)
 | 
						|
/*[clinic end generated code: output=34c8c7c83e5c8463 input=fc530aafb1b0a360]*/
 | 
						|
{
 | 
						|
    PyErr_SetObject(exc, obj);
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.exc_set_object_fetch = _testcapi.exc_set_object
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc,
 | 
						|
                                    PyObject *obj)
 | 
						|
/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/
 | 
						|
{
 | 
						|
    PyObject *type = UNINITIALIZED_PTR;
 | 
						|
    PyObject *value = UNINITIALIZED_PTR;
 | 
						|
    PyObject *tb = UNINITIALIZED_PTR;
 | 
						|
 | 
						|
    PyErr_SetObject(exc, obj);
 | 
						|
    PyErr_Fetch(&type, &value, &tb);
 | 
						|
    assert(type != UNINITIALIZED_PTR);
 | 
						|
    assert(value != UNINITIALIZED_PTR);
 | 
						|
    assert(tb != UNINITIALIZED_PTR);
 | 
						|
    Py_XDECREF(type);
 | 
						|
    Py_XDECREF(tb);
 | 
						|
    return value;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.err_setstring
 | 
						|
    exc: object
 | 
						|
    value: str(zeroes=True, accept={robuffer, str, NoneType})
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_err_setstring_impl(PyObject *module, PyObject *exc,
 | 
						|
                             const char *value, Py_ssize_t value_length)
 | 
						|
/*[clinic end generated code: output=fba8705e5703dd3f input=e8a95fad66d9004b]*/
 | 
						|
{
 | 
						|
    NULLABLE(exc);
 | 
						|
    PyErr_SetString(exc, value);
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.err_setfromerrnowithfilename
 | 
						|
    error: int
 | 
						|
    exc: object
 | 
						|
    value: str(zeroes=True, accept={robuffer, str, NoneType})
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error,
 | 
						|
                                            PyObject *exc, const char *value,
 | 
						|
                                            Py_ssize_t value_length)
 | 
						|
/*[clinic end generated code: output=d02df5749a01850e input=ff7c384234bf097f]*/
 | 
						|
{
 | 
						|
    NULLABLE(exc);
 | 
						|
    errno = error;
 | 
						|
    PyErr_SetFromErrnoWithFilename(exc, value);
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.raise_exception
 | 
						|
    exception as exc: object
 | 
						|
    num_args: int
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args)
 | 
						|
/*[clinic end generated code: output=eb0a9c5d69e0542d input=83d6262c3829d088]*/
 | 
						|
{
 | 
						|
    PyObject *exc_args = PyTuple_New(num_args);
 | 
						|
    if (exc_args == NULL) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    for (int i = 0; i < num_args; ++i) {
 | 
						|
        PyObject *v = PyLong_FromLong(i);
 | 
						|
        if (v == NULL) {
 | 
						|
            Py_DECREF(exc_args);
 | 
						|
            return NULL;
 | 
						|
        }
 | 
						|
        PyTuple_SET_ITEM(exc_args, i, v);
 | 
						|
    }
 | 
						|
    PyErr_SetObject(exc, exc_args);
 | 
						|
    Py_DECREF(exc_args);
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.raise_memoryerror
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_raise_memoryerror_impl(PyObject *module)
 | 
						|
/*[clinic end generated code: output=dd057803fb0131e6 input=6ca521bd07fb73cb]*/
 | 
						|
{
 | 
						|
    return PyErr_NoMemory();
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.fatal_error
 | 
						|
    message: str(accept={robuffer})
 | 
						|
    release_gil: bool = False
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_fatal_error_impl(PyObject *module, const char *message,
 | 
						|
                           int release_gil)
 | 
						|
/*[clinic end generated code: output=9c3237116e6a03e8 input=1be357a2ccb04c8c]*/
 | 
						|
{
 | 
						|
    if (release_gil) {
 | 
						|
        Py_BEGIN_ALLOW_THREADS
 | 
						|
        Py_FatalError(message);
 | 
						|
        Py_END_ALLOW_THREADS
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        Py_FatalError(message);
 | 
						|
    }
 | 
						|
    // Py_FatalError() does not return, but exits the process.
 | 
						|
    Py_RETURN_NONE;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.set_exc_info
 | 
						|
    new_type: object
 | 
						|
    new_value: object
 | 
						|
    new_tb: object
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type,
 | 
						|
                            PyObject *new_value, PyObject *new_tb)
 | 
						|
/*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/
 | 
						|
{
 | 
						|
    PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR;
 | 
						|
    PyErr_GetExcInfo(&type, &value, &tb);
 | 
						|
 | 
						|
    Py_INCREF(new_type);
 | 
						|
    Py_INCREF(new_value);
 | 
						|
    Py_INCREF(new_tb);
 | 
						|
    PyErr_SetExcInfo(new_type, new_value, new_tb);
 | 
						|
 | 
						|
    PyObject *orig_exc = PyTuple_Pack(3,
 | 
						|
            type  ? type  : Py_None,
 | 
						|
            value ? value : Py_None,
 | 
						|
            tb    ? tb    : Py_None);
 | 
						|
    Py_XDECREF(type);
 | 
						|
    Py_XDECREF(value);
 | 
						|
    Py_XDECREF(tb);
 | 
						|
    return orig_exc;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.set_exception
 | 
						|
    new_exc: object
 | 
						|
    /
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_set_exception(PyObject *module, PyObject *new_exc)
 | 
						|
/*[clinic end generated code: output=8b969b35d029e96d input=c89d4ca966c69738]*/
 | 
						|
{
 | 
						|
    PyObject *exc = PyErr_GetHandledException();
 | 
						|
    assert(PyExceptionInstance_Check(exc) || exc == NULL);
 | 
						|
    PyErr_SetHandledException(new_exc);
 | 
						|
    return exc;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.traceback_print
 | 
						|
    traceback: object
 | 
						|
    file: object
 | 
						|
    /
 | 
						|
To test the format of tracebacks as printed out.
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_traceback_print_impl(PyObject *module, PyObject *traceback,
 | 
						|
                               PyObject *file)
 | 
						|
/*[clinic end generated code: output=17074ecf9d95cf30 input=9423f2857b008ca8]*/
 | 
						|
{
 | 
						|
    if (PyTraceBack_Print(traceback, file) < 0) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    Py_RETURN_NONE;
 | 
						|
}
 | 
						|
 | 
						|
/*[clinic input]
 | 
						|
_testcapi.unstable_exc_prep_reraise_star
 | 
						|
    orig: object
 | 
						|
    excs: object
 | 
						|
    /
 | 
						|
To test PyUnstable_Exc_PrepReraiseStar.
 | 
						|
[clinic start generated code]*/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
_testcapi_unstable_exc_prep_reraise_star_impl(PyObject *module,
 | 
						|
                                              PyObject *orig, PyObject *excs)
 | 
						|
/*[clinic end generated code: output=850cf008e0563c77 input=27fbcda2203eb301]*/
 | 
						|
{
 | 
						|
    return PyUnstable_Exc_PrepReraiseStar(orig, excs);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * Define the PyRecurdingInfinitelyError_Type
 | 
						|
 */
 | 
						|
 | 
						|
static PyTypeObject PyRecursingInfinitelyError_Type;
 | 
						|
 | 
						|
static int
 | 
						|
recurse_infinitely_error_init(PyObject *self, PyObject *args, PyObject *kwds)
 | 
						|
{
 | 
						|
    PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type;
 | 
						|
 | 
						|
    /* Instantiating this exception starts infinite recursion. */
 | 
						|
    Py_INCREF(type);
 | 
						|
    PyErr_SetObject(type, NULL);
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
static PyTypeObject PyRecursingInfinitelyError_Type = {
 | 
						|
    .tp_name = "RecursingInfinitelyError",
 | 
						|
    .tp_basicsize = sizeof(PyBaseExceptionObject),
 | 
						|
    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 | 
						|
    .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."),
 | 
						|
    .tp_init = (initproc)recurse_infinitely_error_init,
 | 
						|
};
 | 
						|
 | 
						|
static PyMethodDef test_methods[] = {
 | 
						|
    {"err_restore",             err_restore,                     METH_VARARGS},
 | 
						|
    _TESTCAPI_ERR_SET_RAISED_METHODDEF
 | 
						|
    _TESTCAPI_EXCEPTION_PRINT_METHODDEF
 | 
						|
    _TESTCAPI_FATAL_ERROR_METHODDEF
 | 
						|
    _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF
 | 
						|
    _TESTCAPI_EXC_SET_OBJECT_METHODDEF
 | 
						|
    _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF
 | 
						|
    _TESTCAPI_ERR_SETSTRING_METHODDEF
 | 
						|
    _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF
 | 
						|
    _TESTCAPI_RAISE_EXCEPTION_METHODDEF
 | 
						|
    _TESTCAPI_RAISE_MEMORYERROR_METHODDEF
 | 
						|
    _TESTCAPI_SET_EXC_INFO_METHODDEF
 | 
						|
    _TESTCAPI_SET_EXCEPTION_METHODDEF
 | 
						|
    _TESTCAPI_TRACEBACK_PRINT_METHODDEF
 | 
						|
    _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF
 | 
						|
    {NULL},
 | 
						|
};
 | 
						|
 | 
						|
int
 | 
						|
_PyTestCapi_Init_Exceptions(PyObject *mod)
 | 
						|
{
 | 
						|
    PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception;
 | 
						|
    if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
    if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError",
 | 
						|
                              (PyObject *)&PyRecursingInfinitelyError_Type) < 0)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (PyModule_AddFunctions(mod, test_methods) < 0) {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 |