Home | History | Annotate | Download | only in Python
      1 #include "Python.h"
      2 #include "Python-ast.h"
      3 #include "node.h"
      4 #include "token.h"
      5 #include "graminit.h"
      6 #include "code.h"
      7 #include "compile.h"
      8 #include "symtable.h"
      9 
     10 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
     11 #define ERR_LATE_FUTURE \
     12 "from __future__ imports must occur at the beginning of the file"
     13 
     14 static int
     15 future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
     16 {
     17     int i;
     18     asdl_seq *names;
     19 
     20     assert(s->kind == ImportFrom_kind);
     21 
     22     names = s->v.ImportFrom.names;
     23     for (i = 0; i < asdl_seq_LEN(names); i++) {
     24         alias_ty name = (alias_ty)asdl_seq_GET(names, i);
     25         const char *feature = PyString_AsString(name->name);
     26         if (!feature)
     27             return 0;
     28         if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
     29             continue;
     30         } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
     31             continue;
     32         } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
     33             ff->ff_features |= CO_FUTURE_DIVISION;
     34         } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
     35             ff->ff_features |= CO_FUTURE_ABSOLUTE_IMPORT;
     36         } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
     37             ff->ff_features |= CO_FUTURE_WITH_STATEMENT;
     38         } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
     39             ff->ff_features |= CO_FUTURE_PRINT_FUNCTION;
     40         } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
     41             ff->ff_features |= CO_FUTURE_UNICODE_LITERALS;
     42         } else if (strcmp(feature, "braces") == 0) {
     43             PyErr_SetString(PyExc_SyntaxError,
     44                             "not a chance");
     45             PyErr_SyntaxLocation(filename, s->lineno);
     46             return 0;
     47         } else {
     48             PyErr_Format(PyExc_SyntaxError,
     49                          UNDEFINED_FUTURE_FEATURE, feature);
     50             PyErr_SyntaxLocation(filename, s->lineno);
     51             return 0;
     52         }
     53     }
     54     return 1;
     55 }
     56 
     57 static int
     58 future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
     59 {
     60     int i, found_docstring = 0, done = 0, prev_line = 0;
     61 
     62     if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
     63         return 1;
     64 
     65     /* A subsequent pass will detect future imports that don't
     66        appear at the beginning of the file.  There's one case,
     67        however, that is easier to handle here: A series of imports
     68        joined by semi-colons, where the first import is a future
     69        statement but some subsequent import has the future form
     70        but is preceded by a regular import.
     71     */
     72 
     73 
     74     for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
     75         stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
     76 
     77         if (done && s->lineno > prev_line)
     78             return 1;
     79         prev_line = s->lineno;
     80 
     81         /* The tests below will return from this function unless it is
     82            still possible to find a future statement.  The only things
     83            that can precede a future statement are another future
     84            statement and a doc string.
     85         */
     86 
     87         if (s->kind == ImportFrom_kind) {
     88             identifier modname = s->v.ImportFrom.module;
     89             if (modname && PyString_GET_SIZE(modname) == 10 &&
     90                 !strcmp(PyString_AS_STRING(modname), "__future__")) {
     91                 if (done) {
     92                     PyErr_SetString(PyExc_SyntaxError,
     93                                     ERR_LATE_FUTURE);
     94                     PyErr_SyntaxLocation(filename,
     95                                          s->lineno);
     96                     return 0;
     97                 }
     98                 if (!future_check_features(ff, s, filename))
     99                     return 0;
    100                 ff->ff_lineno = s->lineno;
    101             }
    102             else
    103                 done = 1;
    104         }
    105         else if (s->kind == Expr_kind && !found_docstring) {
    106             expr_ty e = s->v.Expr.value;
    107             if (e->kind != Str_kind)
    108                 done = 1;
    109             else
    110                 found_docstring = 1;
    111         }
    112         else
    113             done = 1;
    114     }
    115     return 1;
    116 }
    117 
    118 
    119 PyFutureFeatures *
    120 PyFuture_FromAST(mod_ty mod, const char *filename)
    121 {
    122     PyFutureFeatures *ff;
    123 
    124     ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
    125     if (ff == NULL) {
    126         PyErr_NoMemory();
    127         return NULL;
    128     }
    129     ff->ff_features = 0;
    130     ff->ff_lineno = -1;
    131 
    132     if (!future_parse(ff, mod, filename)) {
    133         PyObject_Free(ff);
    134         return NULL;
    135     }
    136     return ff;
    137 }
    138