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 "symtable.h" 8 9 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" 10 #define ERR_LATE_FUTURE \ 11 "from __future__ imports must occur at the beginning of the file" 12 13 static int 14 future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) 15 { 16 int i; 17 asdl_seq *names; 18 19 assert(s->kind == ImportFrom_kind); 20 21 names = s->v.ImportFrom.names; 22 for (i = 0; i < asdl_seq_LEN(names); i++) { 23 alias_ty name = (alias_ty)asdl_seq_GET(names, i); 24 const char *feature = PyUnicode_AsUTF8(name->name); 25 if (!feature) 26 return 0; 27 if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { 28 continue; 29 } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { 30 continue; 31 } else if (strcmp(feature, FUTURE_DIVISION) == 0) { 32 continue; 33 } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) { 34 continue; 35 } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) { 36 continue; 37 } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) { 38 continue; 39 } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { 40 continue; 41 } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { 42 ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; 43 } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) { 44 ff->ff_features |= CO_FUTURE_GENERATOR_STOP; 45 } else if (strcmp(feature, "braces") == 0) { 46 PyErr_SetString(PyExc_SyntaxError, 47 "not a chance"); 48 PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); 49 return 0; 50 } else { 51 PyErr_Format(PyExc_SyntaxError, 52 UNDEFINED_FUTURE_FEATURE, feature); 53 PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); 54 return 0; 55 } 56 } 57 return 1; 58 } 59 60 static int 61 future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) 62 { 63 int i, done = 0, prev_line = 0; 64 stmt_ty first; 65 66 if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) 67 return 1; 68 69 if (asdl_seq_LEN(mod->v.Module.body) == 0) 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 i = 0; 81 first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); 82 if (first->kind == Expr_kind 83 && (first->v.Expr.value->kind == Str_kind 84 || (first->v.Expr.value->kind == Constant_kind 85 && PyUnicode_CheckExact(first->v.Expr.value->v.Constant.value)))) 86 i++; 87 88 89 for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { 90 stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); 91 92 if (done && s->lineno > prev_line) 93 return 1; 94 prev_line = s->lineno; 95 96 /* The tests below will return from this function unless it is 97 still possible to find a future statement. The only things 98 that can precede a future statement are another future 99 statement and a doc string. 100 */ 101 102 if (s->kind == ImportFrom_kind) { 103 identifier modname = s->v.ImportFrom.module; 104 if (modname && 105 _PyUnicode_EqualToASCIIString(modname, "__future__")) { 106 if (done) { 107 PyErr_SetString(PyExc_SyntaxError, 108 ERR_LATE_FUTURE); 109 PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); 110 return 0; 111 } 112 if (!future_check_features(ff, s, filename)) 113 return 0; 114 ff->ff_lineno = s->lineno; 115 } 116 else { 117 done = 1; 118 } 119 } 120 else { 121 done = 1; 122 } 123 } 124 return 1; 125 } 126 127 128 PyFutureFeatures * 129 PyFuture_FromASTObject(mod_ty mod, PyObject *filename) 130 { 131 PyFutureFeatures *ff; 132 133 ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); 134 if (ff == NULL) { 135 PyErr_NoMemory(); 136 return NULL; 137 } 138 ff->ff_features = 0; 139 ff->ff_lineno = -1; 140 141 if (!future_parse(ff, mod, filename)) { 142 PyObject_Free(ff); 143 return NULL; 144 } 145 return ff; 146 } 147 148 149 PyFutureFeatures * 150 PyFuture_FromAST(mod_ty mod, const char *filename_str) 151 { 152 PyFutureFeatures *ff; 153 PyObject *filename; 154 155 filename = PyUnicode_DecodeFSDefault(filename_str); 156 if (filename == NULL) 157 return NULL; 158 ff = PyFuture_FromASTObject(mod, filename); 159 Py_DECREF(filename); 160 return ff; 161 } 162