(root)/
Python-3.12.0/
Python/
future.c
       1  #include "Python.h"
       2  #include "pycore_ast.h"           // _PyAST_GetDocString()
       3  
       4  #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
       5  
       6  static int
       7  future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
       8  {
       9      int i;
      10  
      11      assert(s->kind == ImportFrom_kind);
      12  
      13      asdl_alias_seq *names = s->v.ImportFrom.names;
      14      for (i = 0; i < asdl_seq_LEN(names); i++) {
      15          alias_ty name = (alias_ty)asdl_seq_GET(names, i);
      16          const char *feature = PyUnicode_AsUTF8(name->name);
      17          if (!feature)
      18              return 0;
      19          if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
      20              continue;
      21          } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
      22              continue;
      23          } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
      24              continue;
      25          } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
      26              continue;
      27          } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
      28              continue;
      29          } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
      30              continue;
      31          } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
      32              continue;
      33          } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) {
      34              ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL;
      35          } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) {
      36              continue;
      37          } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) {
      38              ff->ff_features |= CO_FUTURE_ANNOTATIONS;
      39          } else if (strcmp(feature, "braces") == 0) {
      40              PyErr_SetString(PyExc_SyntaxError,
      41                              "not a chance");
      42              PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1);
      43              return 0;
      44          } else {
      45              PyErr_Format(PyExc_SyntaxError,
      46                           UNDEFINED_FUTURE_FEATURE, feature);
      47              PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1);
      48              return 0;
      49          }
      50      }
      51      return 1;
      52  }
      53  
      54  static int
      55  future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
      56  {
      57      if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) {
      58          return 1;
      59      }
      60  
      61      Py_ssize_t n = asdl_seq_LEN(mod->v.Module.body);
      62      if (n == 0) {
      63          return 1;
      64      }
      65  
      66      Py_ssize_t i = 0;
      67      if (_PyAST_GetDocString(mod->v.Module.body) != NULL) {
      68          i++;
      69      }
      70  
      71      for (; i < n; i++) {
      72          stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
      73  
      74          /* The only things that can precede a future statement
      75           *  are another future statement and a doc string.
      76           */
      77  
      78          if (s->kind == ImportFrom_kind) {
      79              identifier modname = s->v.ImportFrom.module;
      80              if (modname &&
      81                  _PyUnicode_EqualToASCIIString(modname, "__future__")) {
      82                  if (!future_check_features(ff, s, filename)) {
      83                      return 0;
      84                  }
      85                  ff->ff_location = SRC_LOCATION_FROM_AST(s);
      86              }
      87              else {
      88                  return 1;
      89              }
      90          }
      91          else {
      92              return 1;
      93          }
      94      }
      95      return 1;
      96  }
      97  
      98  
      99  int
     100  _PyFuture_FromAST(mod_ty mod, PyObject *filename, PyFutureFeatures *ff)
     101  {
     102      ff->ff_features = 0;
     103      ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1};
     104  
     105      if (!future_parse(ff, mod, filename)) {
     106          return 0;
     107      }
     108      return 1;
     109  }