Line data Source code
1 : #include "Python.h" 2 : #include "pycore_ast.h" // _PyAST_GetDocString() 3 : 4 : #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" 5 : #define ERR_LATE_FUTURE \ 6 : "from __future__ imports must occur at the beginning of the file" 7 : 8 : static int 9 1043 : future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) 10 : { 11 : int i; 12 : 13 1043 : assert(s->kind == ImportFrom_kind); 14 : 15 1043 : asdl_alias_seq *names = s->v.ImportFrom.names; 16 2718 : for (i = 0; i < asdl_seq_LEN(names); i++) { 17 1683 : alias_ty name = (alias_ty)asdl_seq_GET(names, i); 18 1683 : const char *feature = PyUnicode_AsUTF8(name->name); 19 1683 : if (!feature) 20 0 : return 0; 21 1683 : if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) { 22 15 : continue; 23 1668 : } else if (strcmp(feature, FUTURE_GENERATORS) == 0) { 24 3 : continue; 25 1665 : } else if (strcmp(feature, FUTURE_DIVISION) == 0) { 26 330 : continue; 27 1335 : } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) { 28 656 : continue; 29 679 : } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) { 30 1 : continue; 31 678 : } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) { 32 105 : continue; 33 573 : } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { 34 311 : continue; 35 262 : } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { 36 1 : ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; 37 261 : } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) { 38 2 : continue; 39 259 : } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) { 40 251 : ff->ff_features |= CO_FUTURE_ANNOTATIONS; 41 8 : } else if (strcmp(feature, "braces") == 0) { 42 3 : PyErr_SetString(PyExc_SyntaxError, 43 : "not a chance"); 44 3 : PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); 45 3 : return 0; 46 : } else { 47 5 : PyErr_Format(PyExc_SyntaxError, 48 : UNDEFINED_FUTURE_FEATURE, feature); 49 5 : PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset + 1); 50 5 : return 0; 51 : } 52 : } 53 1035 : return 1; 54 : } 55 : 56 : static int 57 114701 : future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) 58 : { 59 114701 : int i, done = 0, prev_line = 0; 60 : 61 114701 : if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) 62 72424 : return 1; 63 : 64 42277 : if (asdl_seq_LEN(mod->v.Module.body) == 0) 65 678 : return 1; 66 : 67 : /* A subsequent pass will detect future imports that don't 68 : appear at the beginning of the file. There's one case, 69 : however, that is easier to handle here: A series of imports 70 : joined by semi-colons, where the first import is a future 71 : statement but some subsequent import has the future form 72 : but is preceded by a regular import. 73 : */ 74 : 75 41599 : i = 0; 76 41599 : if (_PyAST_GetDocString(mod->v.Module.body) != NULL) 77 4945 : i++; 78 : 79 86440 : for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { 80 56750 : stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); 81 : 82 56750 : if (done && s->lineno > prev_line) 83 11899 : return 1; 84 44851 : prev_line = s->lineno; 85 : 86 : /* The tests below will return from this function unless it is 87 : still possible to find a future statement. The only things 88 : that can precede a future statement are another future 89 : statement and a doc string. 90 : */ 91 : 92 44851 : if (s->kind == ImportFrom_kind) { 93 4635 : identifier modname = s->v.ImportFrom.module; 94 9092 : if (modname && 95 4457 : _PyUnicode_EqualToASCIIString(modname, "__future__")) { 96 1045 : if (done) { 97 2 : PyErr_SetString(PyExc_SyntaxError, 98 : ERR_LATE_FUTURE); 99 2 : PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); 100 2 : return 0; 101 : } 102 1043 : if (!future_check_features(ff, s, filename)) 103 8 : return 0; 104 1035 : ff->ff_lineno = s->lineno; 105 : } 106 : else { 107 3590 : done = 1; 108 : } 109 : } 110 : else { 111 40216 : done = 1; 112 : } 113 : } 114 29690 : return 1; 115 : } 116 : 117 : 118 : PyFutureFeatures * 119 114701 : _PyFuture_FromAST(mod_ty mod, PyObject *filename) 120 : { 121 : PyFutureFeatures *ff; 122 : 123 114701 : ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); 124 114701 : if (ff == NULL) { 125 0 : PyErr_NoMemory(); 126 0 : return NULL; 127 : } 128 114701 : ff->ff_features = 0; 129 114701 : ff->ff_lineno = -1; 130 : 131 114701 : if (!future_parse(ff, mod, filename)) { 132 10 : PyObject_Free(ff); 133 10 : return NULL; 134 : } 135 114691 : return ff; 136 : }