8 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
9 #define FUTURE_IMPORT_STAR "future statement does not support import *"
11 /* FUTURE_POSSIBLE() is provided to accomodate doc strings, which is
12 the only statement that can occur before a future statement.
14 #define FUTURE_POSSIBLE(FF) ((FF)->ff_last_lineno == -1)
17 future_check_features(PyFutureFeatures
*ff
, node
*n
, const char *filename
)
23 REQ(n
, import_stmt
); /* must by from __future__ import ... */
25 for (i
= 3; i
< NCH(n
); i
+= 2) {
27 if (TYPE(ch
) == STAR
) {
28 PyErr_SetString(PyExc_SyntaxError
,
30 PyErr_SyntaxLocation(filename
, ch
->n_lineno
);
33 REQ(ch
, import_as_name
);
34 feature
= STR(CHILD(ch
, 0));
35 if (strcmp(feature
, FUTURE_NESTED_SCOPES
) == 0) {
37 } else if (strcmp(feature
, FUTURE_GENERATORS
) == 0) {
39 } else if (strcmp(feature
, FUTURE_DIVISION
) == 0) {
40 ff
->ff_features
|= CO_FUTURE_DIVISION
;
41 } else if (strcmp(feature
, "braces") == 0) {
42 PyErr_SetString(PyExc_SyntaxError
,
44 PyErr_SyntaxLocation(filename
, CHILD(ch
, 0)->n_lineno
);
47 PyErr_Format(PyExc_SyntaxError
,
48 UNDEFINED_FUTURE_FEATURE
, feature
);
49 PyErr_SyntaxLocation(filename
, CHILD(ch
, 0)->n_lineno
);
57 future_error(node
*n
, const char *filename
)
59 PyErr_SetString(PyExc_SyntaxError
,
60 "from __future__ imports must occur at the "
61 "beginning of the file");
62 PyErr_SyntaxLocation(filename
, n
->n_lineno
);
65 /* Relevant portions of the grammar:
67 single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
68 file_input: (NEWLINE | stmt)* ENDMARKER
69 stmt: simple_stmt | compound_stmt
70 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
71 small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt
72 | import_stmt | global_stmt | exec_stmt | assert_stmt
73 import_stmt: 'import' dotted_as_name (',' dotted_as_name)*
74 | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
75 import_as_name: NAME [NAME NAME]
76 dotted_as_name: dotted_name [NAME NAME]
77 dotted_name: NAME ('.' NAME)*
80 /* future_parse() finds future statements at the beginnning of a
81 module. The function calls itself recursively, rather than
82 factoring out logic for different kinds of statements into
86 -1 indicates an error occurred, e.g. unknown feature name
87 0 indicates no feature was found
88 1 indicates a feature was found
92 future_parse(PyFutureFeatures
*ff
, node
*n
, const char *filename
)
100 if (TYPE(CHILD(n
, 0)) == simple_stmt
) {
107 /* Check each statement in the file, starting with the
108 first, and continuing until the first statement
109 that isn't a future statement.
111 for (i
= 0; i
< NCH(n
); i
++) {
112 node
*ch
= CHILD(n
, i
);
113 if (TYPE(ch
) == stmt
) {
114 r
= future_parse(ff
, ch
, filename
);
115 /* Need to check both conditions below
116 to accomodate doc strings, which
119 if (r
< 1 && !FUTURE_POSSIBLE(ff
))
127 REQ(CHILD(n
, 0), small_stmt
);
131 /* Deal with the special case of a series of
132 small statements on a single line. If a
133 future statement follows some other
134 statement, the SyntaxError is raised here.
135 In all other cases, the symtable pass
136 raises the exception.
138 int found
= 0, end_of_future
= 0;
140 for (i
= 0; i
< NCH(n
); i
+= 2) {
141 if (TYPE(CHILD(n
, i
)) == small_stmt
) {
142 r
= future_parse(ff
, CHILD(n
, i
),
157 /* If we found one and only one, then the
158 current lineno is legal.
161 ff
->ff_last_lineno
= n
->n_lineno
+ 1;
163 ff
->ff_last_lineno
= n
->n_lineno
;
165 if (end_of_future
&& found
)
172 if (TYPE(CHILD(n
, 0)) == simple_stmt
) {
175 } else if (TYPE(CHILD(n
, 0)) == expr_stmt
) {
179 REQ(CHILD(n
, 0), compound_stmt
);
180 ff
->ff_last_lineno
= n
->n_lineno
;
191 if (STR(CHILD(n
, 0))[0] != 'f') { /* from */
192 ff
->ff_last_lineno
= n
->n_lineno
;
196 if (strcmp(STR(CHILD(name
, 0)), "__future__") != 0)
198 if (future_check_features(ff
, n
, filename
) < 0)
200 ff
->ff_last_lineno
= n
->n_lineno
+ 1;
204 /* The cases below -- all of them! -- are necessary to find
205 and skip doc strings. */
227 if (TYPE(CHILD(n
, 0)) == STRING
228 && ff
->ff_found_docstring
== 0) {
229 ff
->ff_found_docstring
= 1;
232 ff
->ff_last_lineno
= n
->n_lineno
;
236 ff
->ff_last_lineno
= n
->n_lineno
;
243 PyNode_Future(node
*n
, const char *filename
)
245 PyFutureFeatures
*ff
;
247 ff
= (PyFutureFeatures
*)PyMem_Malloc(sizeof(PyFutureFeatures
));
250 ff
->ff_found_docstring
= 0;
251 ff
->ff_last_lineno
= -1;
254 if (future_parse(ff
, n
, filename
) < 0) {
255 PyMem_Free((void *)ff
);