sys.stderr.write("Sorry, Cython requires Python 2.2 or later\n")
sys.exit(1)
+try:
+ set
+except NameError:
+ # Python 2.3
+ from sets import Set as set
+
from time import time
import Version
from Scanning import PyrexScanner
#
# modules {string : ModuleScope}
# include_directories [string]
+ # future_directives [object]
def __init__(self, include_directories):
#self.modules = {"__builtin__" : BuiltinScope()}
import Builtin
self.modules = {"__builtin__" : Builtin.builtin_scope}
self.include_directories = include_directories
+ self.future_directives = set()
def find_module(self, module_name,
relative_to = None, pos = None, need_pxd = 1):
from ModuleNode import ModuleNode
from Errors import error, InternalError
from Cython import Utils
+import Future
def p_ident(s, message = "Expected an identifier"):
if s.sy == 'IDENT':
kind = s.systring[:1].lower()
if kind not in "cru":
kind = ''
+ if Future.unicode_literals in s.context.future_directives:
+ if kind == '':
+ kind = 'u'
+ elif kind == 'u':
+ s.error("string literal must not start with 'u' when importing __future__.unicode_literals")
+ return ('u', '')
chars = []
while 1:
s.next()
stats.append(stat)
return Nodes.StatListNode(pos, stats = stats)
-def p_from_import_statement(s):
+def p_from_import_statement(s, first_statement = 0):
# s.sy == 'from'
pos = s.position()
s.next()
while s.sy == ',':
s.next()
imported_names.append(p_imported_name(s))
- if kind == 'cimport':
+ if dotted_name == '__future__':
+ if not first_statement:
+ s.error("from __future__ imports must occur at the beginning of the file")
+ else:
+ for (name_pos, name, as_name) in imported_names:
+ try:
+ directive = getattr(Future, name)
+ except AttributeError:
+ s.error("future feature %s is not defined" % name)
+ break
+ s.context.future_directives.add(directive)
+ return Nodes.PassStatNode(pos)
+ elif kind == 'cimport':
for (name_pos, name, as_name) in imported_names:
local_name = as_name or name
s.add_type_name(local_name)
s.error("Only 'with gil' and 'with nogil' implemented",
pos = pos)
-def p_simple_statement(s):
+def p_simple_statement(s, first_statement = 0):
#print "p_simple_statement:", s.sy, s.systring ###
if s.sy == 'global':
node = p_global_statement(s)
elif s.sy in ('import', 'cimport'):
node = p_import_statement(s)
elif s.sy == 'from':
- node = p_from_import_statement(s)
+ node = p_from_import_statement(s, first_statement = first_statement)
elif s.sy == 'assert':
node = p_assert_statement(s)
elif s.sy == 'pass':
node = p_expression_or_assignment(s)
return node
-def p_simple_statement_list(s):
+def p_simple_statement_list(s, first_statement = 0):
# Parse a series of simple statements on one line
# separated by semicolons.
- stat = p_simple_statement(s)
+ stat = p_simple_statement(s, first_statement = first_statement)
if s.sy == ';':
stats = [stat]
while s.sy == ';':
s.compile_time_eval = saved_eval
return result
-def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0):
+def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0,
+ first_statement = 0):
if s.sy == 'ctypedef':
if level not in ('module', 'module_pxd'):
s.error("ctypedef statement not allowed here")
elif s.sy == 'with':
return p_with_statement(s)
else:
- return p_simple_statement_list(s)
+ return p_simple_statement_list(s, first_statement = first_statement)
def p_statement_list(s, level,
- cdef_flag = 0, visibility = 'private', api = 0):
+ cdef_flag = 0, visibility = 'private', api = 0, first_statement = 0):
# Parse a series of statements separated by newlines.
pos = s.position()
stats = []
while s.sy not in ('DEDENT', 'EOF'):
stats.append(p_statement(s, level,
- cdef_flag = cdef_flag, visibility = visibility, api = api))
+ cdef_flag = cdef_flag, visibility = visibility, api = api,
+ first_statement = first_statement))
+ first_statement = 0
if len(stats) == 1:
return stats[0]
else:
level = 'module_pxd'
else:
level = 'module'
- body = p_statement_list(s, level)
+ body = p_statement_list(s, level, first_statement = 1)
if s.sy != 'EOF':
s.error("Syntax error in statement [%s,%s]" % (
repr(s.sy), repr(s.systring)))