1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
from pypy.interpreter import gateway
from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib.unroll import unrolling_iterable
app = gateway.applevel("""
def syntax_warning(msg, fn, lineno, offset):
import warnings
try:
warnings.warn_explicit(msg, SyntaxWarning, fn, lineno)
except SyntaxWarning:
raise SyntaxError(msg, (fn, lineno, offset, msg))
""", filename=__file__)
_emit_syntax_warning = app.interphook("syntax_warning")
del app
def syntax_warning(space, msg, fn, lineno, offset):
"""Raise an applevel SyntaxWarning.
If the user has set this warning to raise an error, a SyntaxError will be
raised."""
w_msg = space.newtext(msg)
w_filename = space.newfilename(fn)
w_lineno = space.newint(lineno)
w_offset = space.newint(offset)
_emit_syntax_warning(space, w_msg, w_filename, w_lineno, w_offset)
def parse_future(tree, feature_flags):
from pypy.interpreter.astcompiler import ast
future_lineno = 0
future_column = 0
flags = 0
have_docstring = False
body = None
if isinstance(tree, ast.Module):
body = tree.body
elif isinstance(tree, ast.Interactive):
body = tree.body
if body is None:
return 0, 0, 0
for stmt in body:
if isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Str):
if have_docstring:
break
else:
have_docstring = True
elif isinstance(stmt, ast.ImportFrom):
if stmt.module == "__future__":
future_lineno = stmt.lineno
future_column = stmt.col_offset
for alias in stmt.names:
assert isinstance(alias, ast.alias)
# If this is an invalid flag, it will be caught later in
# codegen.py.
flags |= feature_flags.get(alias.name, 0)
else:
break
else:
break
return flags, future_lineno, future_column
class ForbiddenNameAssignment(Exception):
def __init__(self, name, node):
self.name = name
self.node = node
def check_forbidden_name(name, node=None):
"""Raise an error if the name cannot be assigned to."""
if name in ("None", "__debug__"):
raise ForbiddenNameAssignment(name, node)
# XXX Warn about using True and False
def dict_to_switch(d):
"""Convert of dictionary with integer keys to a switch statement."""
def lookup(query):
if we_are_translated():
for key, value in unrolling_iteritems:
if key == query:
return value
else:
raise KeyError
else:
return d[query]
lookup._always_inline_ = True
unrolling_iteritems = unrolling_iterable(d.iteritems())
return lookup
def mangle(name, klass):
if not name.startswith('__'):
return name
# Don't mangle __id__ or names with dots. The only time a name with a dot
# can occur is when we are compiling an import statement that has a package
# name.
if name.endswith('__') or '.' in name:
return name
try:
i = 0
while klass[i] == '_':
i = i + 1
except IndexError:
return name
return "_%s%s" % (klass[i:], name)
def intern_if_common_string(space, w_const):
# only intern identifier-like strings
from pypy.objspace.std.unicodeobject import _isidentifier
if (space.is_w(space.type(w_const), space.w_unicode) and
_isidentifier(space.unicode_w(w_const))):
return space.new_interned_w_str(w_const)
return w_const
def new_identifier(space, name):
# Check whether there are non-ASCII characters in the identifier; if
# so, normalize to NFKC
for c in name:
if ord(c) > 0x80:
break
else:
return name
from pypy.module.unicodedata.interp_ucd import ucd
w_name = space.newtext(name)
w_id = space.call_method(ucd, 'normalize', space.newtext('NFKC'), w_name)
return space.text_w(w_id)
|