Skip to content

Commit 1e35ce5

Browse files
committed
Fix SF bug [ #450245 ] Error in parsing future stmts
Check return value from future_parse() in for loop for file_input to accomodate multiple future statements on separate lines. Add several comments explaining how the code works. Remove out-dated XXX comment.
1 parent 07d8d64 commit 1e35ce5

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

Python/future.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
99
#define FUTURE_IMPORT_STAR "future statement does not support import *"
1010

11+
/* FUTURE_POSSIBLE() is provided to accomodate doc strings, which is
12+
the only statement that can occur before a future statement.
13+
*/
1114
#define FUTURE_POSSIBLE(FF) ((FF)->ff_last_lineno == -1)
1215

1316
static int
@@ -57,7 +60,6 @@ future_error(node *n, char *filename)
5760
"from __future__ imports must occur at the "
5861
"beginning of the file");
5962
PyErr_SyntaxLocation(filename, n->n_lineno);
60-
/* XXX set filename and lineno */
6163
}
6264

6365
/* Relevant portions of the grammar:
@@ -75,7 +77,12 @@ dotted_as_name: dotted_name [NAME NAME]
7577
dotted_name: NAME ('.' NAME)*
7678
*/
7779

78-
/* future_parse() return values:
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
83+
different routines.
84+
85+
Return values:
7986
-1 indicates an error occurred, e.g. unknown feature name
8087
0 indicates no feature was found
8188
1 indicates a feature was found
@@ -97,11 +104,19 @@ future_parse(PyFutureFeatures *ff, node *n, char *filename)
97104
return 0;
98105

99106
case file_input:
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.
110+
*/
100111
for (i = 0; i < NCH(n); i++) {
101112
node *ch = CHILD(n, i);
102113
if (TYPE(ch) == stmt) {
103114
r = future_parse(ff, ch, filename);
104-
if (!FUTURE_POSSIBLE(ff))
115+
/* Need to check both conditions below
116+
to accomodate doc strings, which
117+
causes r < 0.
118+
*/
119+
if (r < 1 && !FUTURE_POSSIBLE(ff))
105120
return r;
106121
}
107122
}

0 commit comments

Comments
 (0)