mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	Some incompatible changes had gone in, and the "ignore" lists weren't properly undated. This change fixes that. It's necessary prior to enabling test_check_c_globals, which I hope to do soon. Note that this does include moving last_resort_memory_error to PyInterpreterState. https://github.com/python/cpython/issues/90110
		
			
				
	
	
		
			228 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#define _PY_INTERPRETER
 | 
						|
 | 
						|
#include "Python.h"
 | 
						|
#include "pycore_frame.h"
 | 
						|
#include "pycore_runtime.h"
 | 
						|
#include "pycore_global_objects.h"
 | 
						|
#include "pycore_intrinsics.h"
 | 
						|
#include "pycore_pyerrors.h"
 | 
						|
 | 
						|
 | 
						|
/******** Unary functions ********/
 | 
						|
 | 
						|
static PyObject *
 | 
						|
no_intrinsic(PyThreadState* tstate, PyObject *unused)
 | 
						|
{
 | 
						|
    _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
print_expr(PyThreadState* tstate, PyObject *value)
 | 
						|
{
 | 
						|
    PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
 | 
						|
    // Can't use ERROR_IF here.
 | 
						|
    if (hook == NULL) {
 | 
						|
        _PyErr_SetString(tstate, PyExc_RuntimeError,
 | 
						|
                            "lost sys.displayhook");
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    return PyObject_CallOneArg(hook, value);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
 | 
						|
{
 | 
						|
    PyObject *all, *dict, *name, *value;
 | 
						|
    int skip_leading_underscores = 0;
 | 
						|
    int pos, err;
 | 
						|
 | 
						|
    if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) {
 | 
						|
        return -1; /* Unexpected error */
 | 
						|
    }
 | 
						|
    if (all == NULL) {
 | 
						|
        if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) {
 | 
						|
            return -1;
 | 
						|
        }
 | 
						|
        if (dict == NULL) {
 | 
						|
            _PyErr_SetString(tstate, PyExc_ImportError,
 | 
						|
                    "from-import-* object has no __dict__ and no __all__");
 | 
						|
            return -1;
 | 
						|
        }
 | 
						|
        all = PyMapping_Keys(dict);
 | 
						|
        Py_DECREF(dict);
 | 
						|
        if (all == NULL)
 | 
						|
            return -1;
 | 
						|
        skip_leading_underscores = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    for (pos = 0, err = 0; ; pos++) {
 | 
						|
        name = PySequence_GetItem(all, pos);
 | 
						|
        if (name == NULL) {
 | 
						|
            if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
 | 
						|
                err = -1;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                _PyErr_Clear(tstate);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        if (!PyUnicode_Check(name)) {
 | 
						|
            PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
 | 
						|
            if (modname == NULL) {
 | 
						|
                Py_DECREF(name);
 | 
						|
                err = -1;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            if (!PyUnicode_Check(modname)) {
 | 
						|
                _PyErr_Format(tstate, PyExc_TypeError,
 | 
						|
                              "module __name__ must be a string, not %.100s",
 | 
						|
                              Py_TYPE(modname)->tp_name);
 | 
						|
            }
 | 
						|
            else {
 | 
						|
                _PyErr_Format(tstate, PyExc_TypeError,
 | 
						|
                              "%s in %U.%s must be str, not %.100s",
 | 
						|
                              skip_leading_underscores ? "Key" : "Item",
 | 
						|
                              modname,
 | 
						|
                              skip_leading_underscores ? "__dict__" : "__all__",
 | 
						|
                              Py_TYPE(name)->tp_name);
 | 
						|
            }
 | 
						|
            Py_DECREF(modname);
 | 
						|
            Py_DECREF(name);
 | 
						|
            err = -1;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        if (skip_leading_underscores) {
 | 
						|
            if (PyUnicode_READY(name) == -1) {
 | 
						|
                Py_DECREF(name);
 | 
						|
                err = -1;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            if (PyUnicode_READ_CHAR(name, 0) == '_') {
 | 
						|
                Py_DECREF(name);
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        value = PyObject_GetAttr(v, name);
 | 
						|
        if (value == NULL)
 | 
						|
            err = -1;
 | 
						|
        else if (PyDict_CheckExact(locals))
 | 
						|
            err = PyDict_SetItem(locals, name, value);
 | 
						|
        else
 | 
						|
            err = PyObject_SetItem(locals, name, value);
 | 
						|
        Py_DECREF(name);
 | 
						|
        Py_XDECREF(value);
 | 
						|
        if (err < 0)
 | 
						|
            break;
 | 
						|
    }
 | 
						|
    Py_DECREF(all);
 | 
						|
    return err;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
import_star(PyThreadState* tstate, PyObject *from)
 | 
						|
{
 | 
						|
    _PyInterpreterFrame *frame = tstate->cframe->current_frame;
 | 
						|
    if (_PyFrame_FastToLocalsWithError(frame) < 0) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    PyObject *locals = frame->f_locals;
 | 
						|
    if (locals == NULL) {
 | 
						|
        _PyErr_SetString(tstate, PyExc_SystemError,
 | 
						|
                            "no locals found during 'import *'");
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    int err = import_all_from(tstate, locals, from);
 | 
						|
    _PyFrame_LocalsToFast(frame, 0);
 | 
						|
    if (err < 0) {
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
    Py_RETURN_NONE;
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
stopiteration_error(PyThreadState* tstate, PyObject *exc)
 | 
						|
{
 | 
						|
    _PyInterpreterFrame *frame = tstate->cframe->current_frame;
 | 
						|
    assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
 | 
						|
    assert(PyExceptionInstance_Check(exc));
 | 
						|
    const char *msg = NULL;
 | 
						|
    if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
 | 
						|
        msg = "generator raised StopIteration";
 | 
						|
        if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
 | 
						|
            msg = "async generator raised StopIteration";
 | 
						|
        }
 | 
						|
        else if (frame->f_code->co_flags & CO_COROUTINE) {
 | 
						|
            msg = "coroutine raised StopIteration";
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) &&
 | 
						|
            PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
 | 
						|
    {
 | 
						|
        /* code in `gen` raised a StopAsyncIteration error:
 | 
						|
        raise a RuntimeError.
 | 
						|
        */
 | 
						|
        msg = "async generator raised StopAsyncIteration";
 | 
						|
    }
 | 
						|
    if (msg != NULL) {
 | 
						|
        PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
 | 
						|
        if (message == NULL) {
 | 
						|
            return NULL;
 | 
						|
        }
 | 
						|
        PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
 | 
						|
        if (error == NULL) {
 | 
						|
            Py_DECREF(message);
 | 
						|
            return NULL;
 | 
						|
        }
 | 
						|
        assert(PyExceptionInstance_Check(error));
 | 
						|
        PyException_SetCause(error, Py_NewRef(exc));
 | 
						|
        // Steal exc reference, rather than Py_NewRef+Py_DECREF
 | 
						|
        PyException_SetContext(error, Py_NewRef(exc));
 | 
						|
        Py_DECREF(message);
 | 
						|
        return error;
 | 
						|
    }
 | 
						|
    return Py_NewRef(exc);
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
unary_pos(PyThreadState* unused, PyObject *value)
 | 
						|
{
 | 
						|
    return PyNumber_Positive(value);
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
list_to_tuple(PyThreadState* unused, PyObject *v)
 | 
						|
{
 | 
						|
    assert(PyList_Check(v));
 | 
						|
    return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
 | 
						|
}
 | 
						|
 | 
						|
const instrinsic_func1
 | 
						|
_PyIntrinsics_UnaryFunctions[] = {
 | 
						|
    [0] = no_intrinsic,
 | 
						|
    [INTRINSIC_PRINT] = print_expr,
 | 
						|
    [INTRINSIC_IMPORT_STAR] = import_star,
 | 
						|
    [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error,
 | 
						|
    [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew,
 | 
						|
    [INTRINSIC_UNARY_POSITIVE] = unary_pos,
 | 
						|
    [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple,
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/******** Binary functions ********/
 | 
						|
 | 
						|
 | 
						|
static PyObject *
 | 
						|
prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
 | 
						|
{
 | 
						|
    assert(PyList_Check(excs));
 | 
						|
    return _PyExc_PrepReraiseStar(orig, excs);
 | 
						|
}
 | 
						|
 | 
						|
const instrinsic_func2
 | 
						|
_PyIntrinsics_BinaryFunctions[] = {
 | 
						|
    [INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star,
 | 
						|
};
 | 
						|
 |