ยปCore Development>Code coverage>Python/future.c

Python code coverage for Python/future.c

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