Branch data 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 : : 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 : 113681 : future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) 58 : : { 59 : 113681 : int i, done = 0, prev_line = 0; 60 : : 61 [ + + + + ]: 113681 : if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) 62 : 71342 : return 1; 63 : : 64 [ + + - + ]: 42339 : 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 : 41661 : i = 0; 76 [ + + ]: 41661 : if (_PyAST_GetDocString(mod->v.Module.body) != NULL) 77 : 4852 : i++; 78 : : 79 [ + - + + ]: 86640 : for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { 80 : 56757 : stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); 81 : : 82 [ + + + + ]: 56757 : if (done && s->lineno > prev_line) 83 : 11768 : return 1; 84 : 44989 : 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 [ + + ]: 44989 : if (s->kind == ImportFrom_kind) { 93 : 4610 : identifier modname = s->v.ImportFrom.module; 94 [ + + + + ]: 9042 : if (modname && 95 : 4432 : _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 : 3565 : done = 1; 108 : : } 109 : : } 110 : : else { 111 : 40379 : done = 1; 112 : : } 113 : : } 114 : 29883 : return 1; 115 : : } 116 : : 117 : : 118 : : PyFutureFeatures * 119 : 113681 : _PyFuture_FromAST(mod_ty mod, PyObject *filename) 120 : : { 121 : : PyFutureFeatures *ff; 122 : : 123 : 113681 : ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); 124 [ - + ]: 113681 : if (ff == NULL) { 125 : : PyErr_NoMemory(); 126 : 0 : return NULL; 127 : : } 128 : 113681 : ff->ff_features = 0; 129 : 113681 : ff->ff_lineno = -1; 130 : : 131 [ + + ]: 113681 : if (!future_parse(ff, mod, filename)) { 132 : 10 : PyObject_Free(ff); 133 : 10 : return NULL; 134 : : } 135 : 113671 : return ff; 136 : : }