/pypy/interpreter/pyparser/future.py
Python | 103 lines | 92 code | 11 blank | 0 comment | 13 complexity | 05570de666bfde30a4936420c7a9909c MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
- from pypy.tool import stdlib___future__ as future
- class FutureFlags(object):
- def __init__(self, version):
- compiler_flags = 0
- self.compiler_features = {}
- self.mandatory_flags = 0
- for fname in future.all_feature_names:
- feature = getattr(future, fname)
- if version >= feature.getOptionalRelease():
- flag = feature.compiler_flag
- compiler_flags |= flag
- self.compiler_features[fname] = flag
- if version >= feature.getMandatoryRelease():
- self.mandatory_flags |= feature.compiler_flag
- self.allowed_flags = compiler_flags
- def get_flag_names(self, space, flags):
- flag_names = []
- for name, value in self.compiler_features.items():
- if flags & value:
- flag_names.append(name)
- return flag_names
- def get_compiler_feature(self, name):
- return self.compiler_features.get(name, 0)
- futureFlags_2_4 = FutureFlags((2, 4, 4, 'final', 0))
- futureFlags_2_5 = FutureFlags((2, 5, 0, 'final', 0))
- futureFlags_2_7 = FutureFlags((2, 7, 0, 'final', 0))
- class TokenIterator:
- def __init__(self, tokens):
- self.tokens = tokens
- self.index = 0
- self.next()
- def next(self):
- index = self.index
- self.index = index + 1
- self.tok = self.tokens[index]
- def skip(self, n):
- if self.tok[0] == n:
- self.next()
- return True
- else:
- return False
- def skip_name(self, name):
- from pypy.interpreter.pyparser import pygram
- if self.tok[0] == pygram.tokens.NAME and self.tok[1] == name:
- self.next()
- return True
- else:
- return False
- def next_feature_name(self):
- from pypy.interpreter.pyparser import pygram
- if self.tok[0] == pygram.tokens.NAME:
- name = self.tok[1]
- self.next()
- if self.skip_name("as"):
- self.skip(pygram.tokens.NAME)
- return name
- else:
- return ''
- def skip_newlines(self):
- from pypy.interpreter.pyparser import pygram
- while self.skip(pygram.tokens.NEWLINE):
- pass
- def add_future_flags(future_flags, tokens):
- from pypy.interpreter.pyparser import pygram
- it = TokenIterator(tokens)
- result = 0
- #
- # The only things that can precede a future statement are another
- # future statement and a doc string (only one). This is a very
- # permissive parsing of the given list of tokens; it relies on
- # the real parsing done afterwards to give errors.
- it.skip_newlines()
- it.skip_name("r") or it.skip_name("u") or it.skip_name("ru")
- if it.skip(pygram.tokens.STRING):
- it.skip_newlines()
- while (it.skip_name("from") and
- it.skip_name("__future__") and
- it.skip_name("import")):
- it.skip(pygram.tokens.LPAR) # optionally
- result |= future_flags.get_compiler_feature(it.next_feature_name())
- while it.skip(pygram.tokens.COMMA):
- result |= future_flags.get_compiler_feature(it.next_feature_name())
- it.skip(pygram.tokens.RPAR) # optionally
- it.skip(pygram.tokens.SEMI) # optionally
- it.skip_newlines()
- position = (it.tok[2], it.tok[3])
- return result, position