PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/interpreter/pyparser/future.py

https://bitbucket.org/pypy/pypy/
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
  1. from pypy.tool import stdlib___future__ as future
  2. class FutureFlags(object):
  3. def __init__(self, version):
  4. compiler_flags = 0
  5. self.compiler_features = {}
  6. self.mandatory_flags = 0
  7. for fname in future.all_feature_names:
  8. feature = getattr(future, fname)
  9. if version >= feature.getOptionalRelease():
  10. flag = feature.compiler_flag
  11. compiler_flags |= flag
  12. self.compiler_features[fname] = flag
  13. if version >= feature.getMandatoryRelease():
  14. self.mandatory_flags |= feature.compiler_flag
  15. self.allowed_flags = compiler_flags
  16. def get_flag_names(self, space, flags):
  17. flag_names = []
  18. for name, value in self.compiler_features.items():
  19. if flags & value:
  20. flag_names.append(name)
  21. return flag_names
  22. def get_compiler_feature(self, name):
  23. return self.compiler_features.get(name, 0)
  24. futureFlags_2_4 = FutureFlags((2, 4, 4, 'final', 0))
  25. futureFlags_2_5 = FutureFlags((2, 5, 0, 'final', 0))
  26. futureFlags_2_7 = FutureFlags((2, 7, 0, 'final', 0))
  27. class TokenIterator:
  28. def __init__(self, tokens):
  29. self.tokens = tokens
  30. self.index = 0
  31. self.next()
  32. def next(self):
  33. index = self.index
  34. self.index = index + 1
  35. self.tok = self.tokens[index]
  36. def skip(self, n):
  37. if self.tok[0] == n:
  38. self.next()
  39. return True
  40. else:
  41. return False
  42. def skip_name(self, name):
  43. from pypy.interpreter.pyparser import pygram
  44. if self.tok[0] == pygram.tokens.NAME and self.tok[1] == name:
  45. self.next()
  46. return True
  47. else:
  48. return False
  49. def next_feature_name(self):
  50. from pypy.interpreter.pyparser import pygram
  51. if self.tok[0] == pygram.tokens.NAME:
  52. name = self.tok[1]
  53. self.next()
  54. if self.skip_name("as"):
  55. self.skip(pygram.tokens.NAME)
  56. return name
  57. else:
  58. return ''
  59. def skip_newlines(self):
  60. from pypy.interpreter.pyparser import pygram
  61. while self.skip(pygram.tokens.NEWLINE):
  62. pass
  63. def add_future_flags(future_flags, tokens):
  64. from pypy.interpreter.pyparser import pygram
  65. it = TokenIterator(tokens)
  66. result = 0
  67. #
  68. # The only things that can precede a future statement are another
  69. # future statement and a doc string (only one). This is a very
  70. # permissive parsing of the given list of tokens; it relies on
  71. # the real parsing done afterwards to give errors.
  72. it.skip_newlines()
  73. it.skip_name("r") or it.skip_name("u") or it.skip_name("ru")
  74. if it.skip(pygram.tokens.STRING):
  75. it.skip_newlines()
  76. while (it.skip_name("from") and
  77. it.skip_name("__future__") and
  78. it.skip_name("import")):
  79. it.skip(pygram.tokens.LPAR) # optionally
  80. result |= future_flags.get_compiler_feature(it.next_feature_name())
  81. while it.skip(pygram.tokens.COMMA):
  82. result |= future_flags.get_compiler_feature(it.next_feature_name())
  83. it.skip(pygram.tokens.RPAR) # optionally
  84. it.skip(pygram.tokens.SEMI) # optionally
  85. it.skip_newlines()
  86. position = (it.tok[2], it.tok[3])
  87. return result, position