(root)/
Python-3.12.0/
Python/
intrinsics.c
       1  
       2  #define _PY_INTERPRETER
       3  
       4  #include "Python.h"
       5  #include "pycore_frame.h"
       6  #include "pycore_function.h"
       7  #include "pycore_runtime.h"
       8  #include "pycore_global_objects.h"
       9  #include "pycore_intrinsics.h"
      10  #include "pycore_pyerrors.h"
      11  #include "pycore_typevarobject.h"
      12  
      13  
      14  /******** Unary functions ********/
      15  
      16  static PyObject *
      17  no_intrinsic(PyThreadState* tstate, PyObject *unused)
      18  {
      19      _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
      20      return NULL;
      21  }
      22  
      23  static PyObject *
      24  print_expr(PyThreadState* tstate, PyObject *value)
      25  {
      26      PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
      27      // Can't use ERROR_IF here.
      28      if (hook == NULL) {
      29          _PyErr_SetString(tstate, PyExc_RuntimeError,
      30                              "lost sys.displayhook");
      31          return NULL;
      32      }
      33      return PyObject_CallOneArg(hook, value);
      34  }
      35  
      36  static int
      37  import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
      38  {
      39      PyObject *all, *dict, *name, *value;
      40      int skip_leading_underscores = 0;
      41      int pos, err;
      42  
      43      if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) {
      44          return -1; /* Unexpected error */
      45      }
      46      if (all == NULL) {
      47          if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) {
      48              return -1;
      49          }
      50          if (dict == NULL) {
      51              _PyErr_SetString(tstate, PyExc_ImportError,
      52                      "from-import-* object has no __dict__ and no __all__");
      53              return -1;
      54          }
      55          all = PyMapping_Keys(dict);
      56          Py_DECREF(dict);
      57          if (all == NULL)
      58              return -1;
      59          skip_leading_underscores = 1;
      60      }
      61  
      62      for (pos = 0, err = 0; ; pos++) {
      63          name = PySequence_GetItem(all, pos);
      64          if (name == NULL) {
      65              if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
      66                  err = -1;
      67              }
      68              else {
      69                  _PyErr_Clear(tstate);
      70              }
      71              break;
      72          }
      73          if (!PyUnicode_Check(name)) {
      74              PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
      75              if (modname == NULL) {
      76                  Py_DECREF(name);
      77                  err = -1;
      78                  break;
      79              }
      80              if (!PyUnicode_Check(modname)) {
      81                  _PyErr_Format(tstate, PyExc_TypeError,
      82                                "module __name__ must be a string, not %.100s",
      83                                Py_TYPE(modname)->tp_name);
      84              }
      85              else {
      86                  _PyErr_Format(tstate, PyExc_TypeError,
      87                                "%s in %U.%s must be str, not %.100s",
      88                                skip_leading_underscores ? "Key" : "Item",
      89                                modname,
      90                                skip_leading_underscores ? "__dict__" : "__all__",
      91                                Py_TYPE(name)->tp_name);
      92              }
      93              Py_DECREF(modname);
      94              Py_DECREF(name);
      95              err = -1;
      96              break;
      97          }
      98          if (skip_leading_underscores) {
      99              if (PyUnicode_READY(name) == -1) {
     100                  Py_DECREF(name);
     101                  err = -1;
     102                  break;
     103              }
     104              if (PyUnicode_READ_CHAR(name, 0) == '_') {
     105                  Py_DECREF(name);
     106                  continue;
     107              }
     108          }
     109          value = PyObject_GetAttr(v, name);
     110          if (value == NULL)
     111              err = -1;
     112          else if (PyDict_CheckExact(locals))
     113              err = PyDict_SetItem(locals, name, value);
     114          else
     115              err = PyObject_SetItem(locals, name, value);
     116          Py_DECREF(name);
     117          Py_XDECREF(value);
     118          if (err < 0)
     119              break;
     120      }
     121      Py_DECREF(all);
     122      return err;
     123  }
     124  
     125  static PyObject *
     126  import_star(PyThreadState* tstate, PyObject *from)
     127  {
     128      _PyInterpreterFrame *frame = tstate->cframe->current_frame;
     129      if (_PyFrame_FastToLocalsWithError(frame) < 0) {
     130          return NULL;
     131      }
     132  
     133      PyObject *locals = frame->f_locals;
     134      if (locals == NULL) {
     135          _PyErr_SetString(tstate, PyExc_SystemError,
     136                              "no locals found during 'import *'");
     137          return NULL;
     138      }
     139      int err = import_all_from(tstate, locals, from);
     140      _PyFrame_LocalsToFast(frame, 0);
     141      if (err < 0) {
     142          return NULL;
     143      }
     144      Py_RETURN_NONE;
     145  }
     146  
     147  static PyObject *
     148  stopiteration_error(PyThreadState* tstate, PyObject *exc)
     149  {
     150      _PyInterpreterFrame *frame = tstate->cframe->current_frame;
     151      assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
     152      assert(PyExceptionInstance_Check(exc));
     153      const char *msg = NULL;
     154      if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
     155          msg = "generator raised StopIteration";
     156          if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) {
     157              msg = "async generator raised StopIteration";
     158          }
     159          else if (frame->f_code->co_flags & CO_COROUTINE) {
     160              msg = "coroutine raised StopIteration";
     161          }
     162      }
     163      else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) &&
     164              PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
     165      {
     166          /* code in `gen` raised a StopAsyncIteration error:
     167          raise a RuntimeError.
     168          */
     169          msg = "async generator raised StopAsyncIteration";
     170      }
     171      if (msg != NULL) {
     172          PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
     173          if (message == NULL) {
     174              return NULL;
     175          }
     176          PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
     177          if (error == NULL) {
     178              Py_DECREF(message);
     179              return NULL;
     180          }
     181          assert(PyExceptionInstance_Check(error));
     182          PyException_SetCause(error, Py_NewRef(exc));
     183          // Steal exc reference, rather than Py_NewRef+Py_DECREF
     184          PyException_SetContext(error, Py_NewRef(exc));
     185          Py_DECREF(message);
     186          return error;
     187      }
     188      return Py_NewRef(exc);
     189  }
     190  
     191  static PyObject *
     192  unary_pos(PyThreadState* unused, PyObject *value)
     193  {
     194      return PyNumber_Positive(value);
     195  }
     196  
     197  static PyObject *
     198  list_to_tuple(PyThreadState* unused, PyObject *v)
     199  {
     200      assert(PyList_Check(v));
     201      return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
     202  }
     203  
     204  static PyObject *
     205  make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v)
     206  {
     207      assert(PyUnicode_Check(v));
     208      return _Py_make_typevar(v, NULL, NULL);
     209  }
     210  
     211  const instrinsic_func1
     212  _PyIntrinsics_UnaryFunctions[] = {
     213      [0] = no_intrinsic,
     214      [INTRINSIC_PRINT] = print_expr,
     215      [INTRINSIC_IMPORT_STAR] = import_star,
     216      [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error,
     217      [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew,
     218      [INTRINSIC_UNARY_POSITIVE] = unary_pos,
     219      [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple,
     220      [INTRINSIC_TYPEVAR] = make_typevar,
     221      [INTRINSIC_PARAMSPEC] = _Py_make_paramspec,
     222      [INTRINSIC_TYPEVARTUPLE] = _Py_make_typevartuple,
     223      [INTRINSIC_SUBSCRIPT_GENERIC] = _Py_subscript_generic,
     224      [INTRINSIC_TYPEALIAS] = _Py_make_typealias,
     225  };
     226  
     227  
     228  /******** Binary functions ********/
     229  
     230  
     231  static PyObject *
     232  prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
     233  {
     234      assert(PyList_Check(excs));
     235      return _PyExc_PrepReraiseStar(orig, excs);
     236  }
     237  
     238  static PyObject *
     239  make_typevar_with_bound(PyThreadState* Py_UNUSED(ignored), PyObject *name,
     240                          PyObject *evaluate_bound)
     241  {
     242      assert(PyUnicode_Check(name));
     243      return _Py_make_typevar(name, evaluate_bound, NULL);
     244  }
     245  
     246  static PyObject *
     247  make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name,
     248                                PyObject *evaluate_constraints)
     249  {
     250      assert(PyUnicode_Check(name));
     251      return _Py_make_typevar(name, NULL, evaluate_constraints);
     252  }
     253  
     254  const instrinsic_func2
     255  _PyIntrinsics_BinaryFunctions[] = {
     256      [INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star,
     257      [INTRINSIC_TYPEVAR_WITH_BOUND] = make_typevar_with_bound,
     258      [INTRINSIC_TYPEVAR_WITH_CONSTRAINTS] = make_typevar_with_constraints,
     259      [INTRINSIC_SET_FUNCTION_TYPE_PARAMS] = _Py_set_function_type_params,
     260  };