annotate Python/future.c @ 35752:47496e7dbf2f legacy-trunk

Fix SF bug #1167751, Argument genexp corner case Incorrect code was generated for: foo(a = i for i in range(10)) This should have generated a SyntaxError. Fix the Grammar so it raises a SyntaxError and test it. I'm uncertain whether this should be backported. It makes something that was Syntactically valid invalid. However, the code would either be completely broken or do the wrong thing.
author Neal Norwitz <nnorwitz@gmail.com>
date Fri, 21 Oct 2005 06:24:02 +0000
parents 1c4d192f1568
children 6867995a18a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
1 #include "Python.h"
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
2 #include "Python-ast.h"
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
3 #include "node.h"
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
4 #include "token.h"
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
5 #include "graminit.h"
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
6 #include "code.h"
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
7 #include "compile.h"
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
8 #include "symtable.h"
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
9
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
10 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
16838
09f6c1372056 Improve SyntaxErrors for bad future statements. Set file and location
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16824
diff changeset
11 #define FUTURE_IMPORT_STAR "future statement does not support import *"
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
12
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
13 static int
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
14 future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
15 {
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
16 int i;
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
17 const char *feature;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
18 asdl_seq *names;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
19
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
20 assert(s->kind == ImportFrom_kind);
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
21
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
22 names = s->v.ImportFrom.names;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
23 for (i = 0; i < asdl_seq_LEN(names); i++) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
24 alias_ty name = asdl_seq_GET(names, i);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
25 feature = PyString_AsString(name->name);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
26 if (!feature)
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
27 return 0;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
28 if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
19158
97a3d3d7029f Refactor future feature handling
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 19051
diff changeset
29 continue;
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 17018
diff changeset
30 } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
22968
ba0236f84318 Removed more hair in support of future-generator stmts.
Tim Peters <tim.peters@gmail.com>
parents: 19407
diff changeset
31 continue;
19051
f20727cc3d0f Implement PEP 238 in its (almost) full glory.
Guido van Rossum <guido@python.org>
parents: 18612
diff changeset
32 } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
19158
97a3d3d7029f Refactor future feature handling
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 19051
diff changeset
33 ff->ff_features |= CO_FUTURE_DIVISION;
16838
09f6c1372056 Improve SyntaxErrors for bad future statements. Set file and location
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16824
diff changeset
34 } else if (strcmp(feature, "braces") == 0) {
09f6c1372056 Improve SyntaxErrors for bad future statements. Set file and location
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16824
diff changeset
35 PyErr_SetString(PyExc_SyntaxError,
09f6c1372056 Improve SyntaxErrors for bad future statements. Set file and location
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16824
diff changeset
36 "not a chance");
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
37 PyErr_SyntaxLocation(filename, s->lineno);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
38 return 0;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
39 } else {
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
40 PyErr_Format(PyExc_SyntaxError,
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
41 UNDEFINED_FUTURE_FEATURE, feature);
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
42 PyErr_SyntaxLocation(filename, s->lineno);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
43 return 0;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
44 }
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
45 }
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
46 return 1;
16823
acbe74f3a786 Presumed correct compiler pass for future statements
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16799
diff changeset
47 }
acbe74f3a786 Presumed correct compiler pass for future statements
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16799
diff changeset
48
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
49 int
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
50 future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
51 {
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
52 int i, found_docstring = 0, done = 0, prev_line = 0;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
53
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
54 static PyObject *future;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
55 if (!future) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
56 future = PyString_InternFromString("__future__");
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
57 if (!future)
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
58 return 0;
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
59 }
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
60
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
61 if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
62 return 1;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
63
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
64 /* A subsequent pass will detect future imports that don't
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
65 appear at the beginning of the file. There's one case,
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
66 however, that is easier to handl here: A series of imports
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
67 joined by semi-colons, where the first import is a future
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
68 statement but some subsequent import has the future form
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
69 but is preceded by a regular import.
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
70 */
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
71
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
72
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
73 for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
74 stmt_ty s = asdl_seq_GET(mod->v.Module.body, i);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
75
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
76 if (done && s->lineno > prev_line)
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
77 return 1;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
78 prev_line = s->lineno;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
79
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
80 /* The tests below will return from this function unless it is
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
81 still possible to find a future statement. The only things
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
82 that can precede a future statement are another future
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
83 statement and a doc string.
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
84 */
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
85
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
86 if (s->kind == ImportFrom_kind) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
87 if (s->v.ImportFrom.module == future) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
88 if (done) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
89 PyErr_SetString(PyExc_SyntaxError,
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
90 ERR_LATE_FUTURE);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
91 PyErr_SyntaxLocation(filename,
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
92 s->lineno);
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
93 return 0;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
94 }
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
95 if (!future_check_features(ff, s, filename))
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
96 return 0;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
97 ff->ff_lineno = s->lineno;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
98 }
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
99 else
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
100 done = 1;
16823
acbe74f3a786 Presumed correct compiler pass for future statements
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16799
diff changeset
101 }
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
102 else if (s->kind == Expr_kind && !found_docstring) {
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
103 expr_ty e = s->v.Expr.value;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
104 if (e->kind != Str_kind)
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
105 done = 1;
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
106 else
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
107 found_docstring = 1;
16823
acbe74f3a786 Presumed correct compiler pass for future statements
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 16799
diff changeset
108 }
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
109 else
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
110 done = 1;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
111 }
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
112 return 1;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
113 }
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
114
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
115
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
116 PyFutureFeatures *
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
117 PyFuture_FromAST(mod_ty mod, const char *filename)
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
118 {
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
119 PyFutureFeatures *ff;
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
120
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
121 ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
122 if (ff == NULL)
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
123 return NULL;
19158
97a3d3d7029f Refactor future feature handling
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 19051
diff changeset
124 ff->ff_features = 0;
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
125 ff->ff_lineno = -1;
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
126
35742
1c4d192f1568 Merge ast-branch to head
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 34539
diff changeset
127 if (!future_parse(ff, mod, filename)) {
16799
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
128 PyMem_Free((void *)ff);
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
129 return NULL;
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
130 }
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
131 return ff;
08d937107fe6 Improved __future__ parser; still more to do
Jeremy Hylton <jeremy@alum.mit.edu>
parents:
diff changeset
132 }