[pypy-svn] r66507 - in pypy/branch/parser-compiler/pypy/interpreter: . astcompiler pyparser
benjamin at codespeak.net
benjamin at codespeak.net
Wed Jul 22 20:25:44 CEST 2009
Author: benjamin
Date: Wed Jul 22 20:25:43 2009
New Revision: 66507
Modified:
pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py
pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py
pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py
pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py
Log:
lots of checking for __future__ syntax errors
Modified: pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py (original)
+++ pypy/branch/parser-compiler/pypy/interpreter/astcompiler/codegen.py Wed Jul 22 20:25:43 2009
@@ -6,6 +6,7 @@
consts, misc)
from pypy.interpreter.pyparser.error import SyntaxError
from pypy.tool import stdlib_opcode as ops
+from pypy.interpreter.pyparser import future
from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX
@@ -118,8 +119,8 @@
self.symbols = symbols
self.frame_blocks = []
self.interactive = False
- self.temporary_name_counter = 1
self.done_with_future = False
+ self.temporary_name_counter = 1
self._compile(tree)
def _compile(self, tree):
@@ -551,6 +552,7 @@
def visit_Import(self, imp):
self.update_position(imp.lineno, True)
+ self.done_with_future = True
for alias in imp.names:
assert isinstance(alias, ast.alias)
if self.compile_info.flags & consts.CO_FUTURE_ABSOLUTE_IMPORT:
@@ -573,10 +575,21 @@
def visit_ImportFrom(self, imp):
self.update_position(imp.lineno, True)
space = self.space
+ first = imp.names[0]
+ assert isinstance(first, ast.alias)
+ star_import = len(imp.names) == 1 and first.name == "*"
if imp.module == "__future__":
- if self.done_with_future:
- self.error("__future__ statements must appear before other " \
- "imports", imp)
+ if self.done_with_future or \
+ imp.lineno > self.compile_info.last_future_import:
+ self.error("__future__ statements must appear at beginning " \
+ "of file", imp)
+ if star_import:
+ self.error("* not valid in __future__ imports", imp)
+ for alias in imp.names:
+ assert isinstance(alias, ast.alias)
+ if alias.name not in future.futureFlags_2_5.compiler_features:
+ self.error("future feature %s is not defined" %
+ (alias.name,), imp)
else:
self.done_with_future = True
if imp.level == 0 and \
@@ -596,9 +609,7 @@
else:
mod_name = ""
self.emit_op_name(ops.IMPORT_NAME, self.names, mod_name)
- first = imp.names[0]
- assert isinstance(first, ast.alias)
- if len(imp.names) == 1 and first.name == "*":
+ if star_import:
self.emit_op(ops.IMPORT_STAR)
else:
for alias in imp.names:
Modified: pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py (original)
+++ pypy/branch/parser-compiler/pypy/interpreter/pycompiler.py Wed Jul 22 20:25:43 2009
@@ -242,8 +242,9 @@
space.timer.start("PythonAST compile")
try:
- flags |= getFutures(self.futureFlags, source)
- info = CompileInfo(filename, mode, flags)
+ f_flags, future_lineno = getFutures(self.futureFlags, source)
+ flags |= f_flags
+ info = CompileInfo(filename, mode, flags, future_lineno)
parse_tree = self.parser.parse_source(source, info)
module = ast_from_node(space, parse_tree, info)
code = compile_ast(space, module, info)
Modified: pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py (original)
+++ pypy/branch/parser-compiler/pypy/interpreter/pyparser/future.py Wed Jul 22 20:25:43 2009
@@ -33,7 +33,7 @@
futures.start()
except DoneException, e:
pass
- return futures.flags
+ return futures.flags, futures.lineno
class DoneException(Exception):
pass
@@ -67,6 +67,7 @@
self.futureFlags = futureFlags
self.s = string
self.pos = 0
+ self.lineno = 1
self.docstringConsumed = False
self.flags = 0
@@ -98,15 +99,23 @@
while 1: # Deal with a triple quoted docstring
if self.getc() == '\\':
self.pos += 2
- elif self.getc() != endchar:
- self.pos += 1
else:
- self.pos += 1
- if (self.getc() == endchar and
- self.getc(+1) == endchar):
- self.pos += 2
- self.consumeEmptyLine()
- break
+ c = self.getc()
+ if c != endchar:
+ self.pos += 1
+ if c == '\n':
+ self.lineno += 1
+ elif c == '\r':
+ if self.getc() == '\n':
+ self.pos += 1
+ self.lineno += 1
+ else:
+ self.pos += 1
+ if (self.getc() == endchar and
+ self.getc(+1) == endchar):
+ self.pos += 2
+ self.consumeEmptyLine()
+ break
else: # Deal with a single quoted docstring
self.pos += 1
@@ -142,11 +151,16 @@
self.consumeWhitespace()
self.start()
elif self.getc() in '\r\n':
+ c = self.getc()
self.pos += 1
- if self.getc() == '\n':
- self.pos += 1
+ if c == '\r':
+ if self.getc() == '\n':
+ self.pos += 1
+ self.lineno += 1
+ else:
+ self.lineno += 1
self.start()
-
+
def consumeComment(self):
self.pos += 1
while self.getc() not in '\r\n':
@@ -196,11 +210,13 @@
c = self.getc()
if c == '\n':
self.pos += 1
+ self.lineno += 1
continue
elif c == '\r':
self.pos += 1
if self.getc() == '\n':
self.pos += 1
+ self.lineno += 1
else:
raise DoneException
else:
Modified: pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py
==============================================================================
--- pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py (original)
+++ pypy/branch/parser-compiler/pypy/interpreter/pyparser/pyparse.py Wed Jul 22 20:25:43 2009
@@ -58,11 +58,12 @@
class CompileInfo(object):
- def __init__(self, filename, mode="exec", flags=0):
+ def __init__(self, filename, mode="exec", flags=0, future_lineno=0):
self.filename = filename
self.mode = mode
self.encoding = None
self.flags = flags
+ self.last_future_import = future_lineno
_targets = {
More information about the Pypy-commit
mailing list