Python-2.7.3/Python/future.c

No issues found

  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     static PyObject *future;
 63     if (!future) {
 64         future = PyString_InternFromString("__future__");
 65         if (!future)
 66             return 0;
 67     }
 68 
 69     if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
 70         return 1;
 71 
 72     /* A subsequent pass will detect future imports that don't
 73        appear at the beginning of the file.  There's one case,
 74        however, that is easier to handle here: A series of imports
 75        joined by semi-colons, where the first import is a future
 76        statement but some subsequent import has the future form
 77        but is preceded by a regular import.
 78     */
 79 
 80 
 81     for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
 82         stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
 83 
 84         if (done && s->lineno > prev_line)
 85             return 1;
 86         prev_line = s->lineno;
 87 
 88         /* The tests below will return from this function unless it is
 89            still possible to find a future statement.  The only things
 90            that can precede a future statement are another future
 91            statement and a doc string.
 92         */
 93 
 94         if (s->kind == ImportFrom_kind) {
 95             if (s->v.ImportFrom.module == future) {
 96                 if (done) {
 97                     PyErr_SetString(PyExc_SyntaxError,
 98                                     ERR_LATE_FUTURE);
 99                     PyErr_SyntaxLocation(filename,
100                                          s->lineno);
101                     return 0;
102                 }
103                 if (!future_check_features(ff, s, filename))
104                     return 0;
105                 ff->ff_lineno = s->lineno;
106             }
107             else
108                 done = 1;
109         }
110         else if (s->kind == Expr_kind && !found_docstring) {
111             expr_ty e = s->v.Expr.value;
112             if (e->kind != Str_kind)
113                 done = 1;
114             else
115                 found_docstring = 1;
116         }
117         else
118             done = 1;
119     }
120     return 1;
121 }
122 
123 
124 PyFutureFeatures *
125 PyFuture_FromAST(mod_ty mod, const char *filename)
126 {
127     PyFutureFeatures *ff;
128 
129     ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
130     if (ff == NULL) {
131         PyErr_NoMemory();
132         return NULL;
133     }
134     ff->ff_features = 0;
135     ff->ff_lineno = -1;
136 
137     if (!future_parse(ff, mod, filename)) {
138         PyObject_Free(ff);
139         return NULL;
140     }
141     return ff;
142 }