[pypy-commit] pypy stdlib-unification/py3k: close broken merge branch
RonnyPfannschmidt
noreply at buildbot.pypy.org
Mon Apr 16 09:51:30 CEST 2012
Author: Ronny Pfannschmidt <Ronny.Pfannschmidt at gmx.de>
Branch: stdlib-unification/py3k
Changeset: r54382:21a2a3102d8c
Date: 2012-04-16 09:50 +0200
http://bitbucket.org/pypy/pypy/changeset/21a2a3102d8c/
Log: close broken merge branch
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -9,24 +9,35 @@
class Signature(object):
_immutable_ = True
- _immutable_fields_ = ["argnames[*]"]
- __slots__ = ("argnames", "varargname", "kwargname")
+ _immutable_fields_ = ["argnames[*]", "kwonlyargnames[*]"]
+ __slots__ = ("argnames", "kwonlyargnames", "varargname", "kwargname")
- def __init__(self, argnames, varargname=None, kwargname=None):
+ def __init__(self, argnames, varargname=None, kwargname=None, kwonlyargnames=None):
self.argnames = argnames
self.varargname = varargname
self.kwargname = kwargname
+ if kwonlyargnames is None:
+ kwonlyargnames = []
+ self.kwonlyargnames = kwonlyargnames
@jit.elidable
def find_argname(self, name):
try:
return self.argnames.index(name)
except ValueError:
- return -1
+ pass
+ try:
+ return len(self.argnames) + self.kwonlyargnames.index(name)
+ except ValueError:
+ pass
+ return -1
def num_argnames(self):
return len(self.argnames)
+ def num_kwonlyargnames(self):
+ return len(self.kwonlyargnames)
+
def has_vararg(self):
return self.varargname is not None
@@ -43,20 +54,22 @@
argnames = self.argnames
if self.varargname is not None:
argnames = argnames + [self.varargname]
+ argnames = argnames + self.kwonlyargnames
if self.kwargname is not None:
argnames = argnames + [self.kwargname]
return argnames
def __repr__(self):
- return "Signature(%r, %r, %r)" % (
- self.argnames, self.varargname, self.kwargname)
+ return "Signature(%r, %r, %r, %r)" % (
+ self.argnames, self.varargname, self.kwargname, self.kwonlyargnames)
def __eq__(self, other):
if not isinstance(other, Signature):
return NotImplemented
return (self.argnames == other.argnames and
self.varargname == other.varargname and
- self.kwargname == other.kwargname)
+ self.kwargname == other.kwargname and
+ self.kwonlyargnames == other.kwonlyargnames)
def __ne__(self, other):
if not isinstance(other, Signature):
@@ -169,11 +182,9 @@
def _combine_starstarargs_wrapped(self, w_starstararg):
# unpack the ** arguments
space = self.space
- keywords, values_w = space.view_as_kwargs(w_starstararg)
- if keywords is not None: # this path also taken for empty dicts
- self._add_keywordargs_no_unwrapping(keywords, values_w)
- return not jit.isconstant(len(self.keywords))
if space.isinstance_w(w_starstararg, space.w_dict):
+ if not space.is_true(w_starstararg):
+ return False # don't call unpackiterable - it's jit-opaque
keys_w = space.unpackiterable(w_starstararg)
else:
try:
@@ -188,8 +199,11 @@
"a mapping, not %s" % (typename,)))
raise
keys_w = space.unpackiterable(w_keys)
- self._do_combine_starstarargs_wrapped(keys_w, w_starstararg)
- return True
+ if keys_w:
+ self._do_combine_starstarargs_wrapped(keys_w, w_starstararg)
+ return True
+ else:
+ return False # empty dict; don't disable the JIT
def _do_combine_starstarargs_wrapped(self, keys_w, w_starstararg):
space = self.space
@@ -226,26 +240,6 @@
self.keywords_w = self.keywords_w + keywords_w
self.keyword_names_w = keys_w
- @jit.look_inside_iff(lambda self, keywords, keywords_w:
- jit.isconstant(len(keywords) and
- jit.isconstant(self.keywords)))
- def _add_keywordargs_no_unwrapping(self, keywords, keywords_w):
- if self.keywords is None:
- self.keywords = keywords[:] # copy to make non-resizable
- self.keywords_w = keywords_w[:]
- else:
- # looks quadratic, but the JIT should remove all of it nicely.
- # Also, all the lists should be small
- for key in keywords:
- for otherkey in self.keywords:
- if otherkey == key:
- raise operationerrfmt(self.space.w_TypeError,
- "got multiple values "
- "for keyword argument "
- "'%s'", key)
- self.keywords = self.keywords + keywords
- self.keywords_w = self.keywords_w + keywords_w
-
def fixedunpack(self, argcount):
"""The simplest argument parsing: get the 'argcount' arguments,
or raise a real ValueError if the length is wrong."""
@@ -268,7 +262,7 @@
# XXX: this should be @jit.look_inside_iff, but we need key word arguments,
# and it doesn't support them for now.
def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None,
- blindargs=0):
+ w_kw_defs=None, blindargs=0):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
Return the number of arguments filled in.
@@ -276,19 +270,19 @@
if jit.we_are_jitted() and self._dont_jit:
return self._match_signature_jit_opaque(w_firstarg, scope_w,
signature, defaults_w,
- blindargs)
+ w_kw_defs, blindargs)
return self._really_match_signature(w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults_w, w_kw_defs, blindargs)
@jit.dont_look_inside
def _match_signature_jit_opaque(self, w_firstarg, scope_w, signature,
- defaults_w, blindargs):
+ defaults_w, w_kw_defs, blindargs):
return self._really_match_signature(w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults_w, w_kw_defs, blindargs)
@jit.unroll_safe
def _really_match_signature(self, w_firstarg, scope_w, signature,
- defaults_w=None, blindargs=0):
+ defaults_w=None, w_kw_defs=None, blindargs=0):
#
# args_w = list of the normal actual parameters, wrapped
# kwds_w = real dictionary {'keyword': wrapped parameter}
@@ -300,6 +294,7 @@
# so all values coming from there can be assumed constant. It assumes
# that the length of the defaults_w does not vary too much.
co_argcount = signature.num_argnames() # expected formal arguments, without */**
+ co_kwonlyargcount = signature.num_kwonlyargnames()
has_vararg = signature.has_vararg()
has_kwarg = signature.has_kwarg()
extravarargs = None
@@ -351,11 +346,12 @@
starargs_w = args_w[args_left:]
else:
starargs_w = []
- scope_w[co_argcount] = self.space.newtuple(starargs_w)
+ loc = co_argcount + co_kwonlyargcount
+ scope_w[loc] = self.space.newtuple(starargs_w)
elif avail > co_argcount:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, 0)
+ defaults_w, w_kw_defs, 0)
# the code assumes that keywords can potentially be large, but that
# argnames is typically not too large
@@ -388,7 +384,7 @@
used_keywords[i] = True # mark as used
num_remainingkwds -= 1
missing = 0
- if input_argcount < co_argcount:
+ if input_argcount < co_argcount + co_kwonlyargcount:
def_first = co_argcount - (0 if defaults_w is None else len(defaults_w))
for i in range(input_argcount, co_argcount):
if scope_w[i] is not None:
@@ -401,10 +397,27 @@
# because it might be related to a problem with */** or
# keyword arguments, which will be checked for below.
missing += 1
+ for i in range(co_argcount, co_argcount + co_kwonlyargcount):
+ if scope_w[i] is not None:
+ continue
+ elif w_kw_defs is None:
+ missing += 1
+ continue
+ name = signature.kwonlyargnames[i - co_argcount]
+ w_name = self.space.wrap(name)
+ w_def = self.space.finditem(w_kw_defs, w_name)
+ if w_def is not None:
+ scope_w[i] = w_def
+ else:
+ missing += 1
+
+ # TODO: Put a nice error message
+ #if co_kwonlyargcount:
+ # assert co_kwonlyargcount == len(signature.kwonlyargnames)
# collect extra keyword arguments into the **kwarg
if has_kwarg:
- w_kwds = self.space.newdict(kwargs=True)
+ w_kwds = self.space.newdict()
if num_remainingkwds:
#
limit = len(keywords)
@@ -418,26 +431,27 @@
w_key = self.keyword_names_w[i - limit]
self.space.setitem(w_kwds, w_key, keywords_w[i])
#
- scope_w[co_argcount + has_vararg] = w_kwds
+ scope_w[co_argcount + co_kwonlyargcount + has_vararg] = w_kwds
elif num_remainingkwds:
if co_argcount == 0:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, missing)
+ defaults_w, w_kw_defs, missing)
raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords,
used_keywords, self.keyword_names_w)
if missing:
raise ArgErrCount(avail, num_kwds,
co_argcount, has_vararg, has_kwarg,
- defaults_w, missing)
+ defaults_w, w_kw_defs, missing)
- return co_argcount + has_vararg + has_kwarg
+ return co_argcount + has_vararg + has_kwarg + co_kwonlyargcount
def parse_into_scope(self, w_firstarg,
- scope_w, fnname, signature, defaults_w=None):
+ scope_w, fnname, signature, defaults_w=None,
+ w_kw_defs=None):
"""Parse args and kwargs to initialize a frame
according to the signature of code object.
Store the argumentvalues into scope_w.
@@ -445,29 +459,32 @@
"""
try:
return self._match_signature(w_firstarg,
- scope_w, signature, defaults_w, 0)
+ scope_w, signature, defaults_w,
+ w_kw_defs, 0)
except ArgErr, e:
raise operationerrfmt(self.space.w_TypeError,
"%s() %s", fnname, e.getmsg())
- def _parse(self, w_firstarg, signature, defaults_w, blindargs=0):
+ def _parse(self, w_firstarg, signature, defaults_w, w_kw_defs, blindargs=0):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
"""
scopelen = signature.scope_length()
scope_w = [None] * scopelen
self._match_signature(w_firstarg, scope_w, signature, defaults_w,
- blindargs)
+ w_kw_defs, blindargs)
return scope_w
def parse_obj(self, w_firstarg,
- fnname, signature, defaults_w=None, blindargs=0):
+ fnname, signature, defaults_w=None, w_kw_defs=None,
+ blindargs=0):
"""Parse args and kwargs to initialize a frame
according to the signature of code object.
"""
try:
- return self._parse(w_firstarg, signature, defaults_w, blindargs)
+ return self._parse(w_firstarg, signature, defaults_w, w_kw_defs,
+ blindargs)
except ArgErr, e:
raise operationerrfmt(self.space.w_TypeError,
"%s() %s", fnname, e.getmsg())
@@ -523,22 +540,22 @@
def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None,
- blindargs=0):
+ w_kw_defs=None, blindargs=0):
self.combine_if_necessary()
# _match_signature is destructive
return Arguments._match_signature(
self, w_firstarg, scope_w, signature,
- defaults_w, blindargs)
+ defaults_w, w_kw_defs, blindargs)
def unpack(self):
self.combine_if_necessary()
return Arguments.unpack(self)
- def match_signature(self, signature, defaults_w):
+ def match_signature(self, signature, defaults_w, w_kw_defs=None):
"""Parse args and kwargs according to the signature of a code object,
or raise an ArgErr in case of failure.
"""
- return self._parse(None, signature, defaults_w)
+ return self._parse(None, signature, defaults_w, w_kw_defs)
def unmatch_signature(self, signature, data_w):
"""kind of inverse of match_signature"""
@@ -651,7 +668,7 @@
class ArgErrCount(ArgErr):
def __init__(self, got_nargs, nkwds, expected_nargs, has_vararg, has_kwarg,
- defaults_w, missing_args):
+ defaults_w, w_kw_defs, missing_args):
self.expected_nargs = expected_nargs
self.has_vararg = has_vararg
self.has_kwarg = has_kwarg
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -10,6 +10,16 @@
from pypy.interpreter.astcompiler import ast, consts
+try:
+ all
+except NameError:
+ def all(iterable):
+ for x in iterable:
+ if not x:
+ return False
+ return True
+
+
class TestAstBuilder:
def setup_class(cls):
@@ -60,33 +70,6 @@
for stmt in mod.body:
assert isinstance(stmt, ast.Assign)
- def test_print(self):
- pri = self.get_first_stmt("print x")
- assert isinstance(pri, ast.Print)
- assert pri.dest is None
- assert pri.nl
- assert len(pri.values) == 1
- assert isinstance(pri.values[0], ast.Name)
- pri = self.get_first_stmt("print x, 34")
- assert len(pri.values) == 2
- assert isinstance(pri.values[0], ast.Name)
- assert isinstance(pri.values[1], ast.Num)
- pri = self.get_first_stmt("print")
- assert pri.nl
- assert pri.values is None
- pri = self.get_first_stmt("print x,")
- assert len(pri.values) == 1
- assert not pri.nl
- pri = self.get_first_stmt("print >> y, 4")
- assert isinstance(pri.dest, ast.Name)
- assert len(pri.values) == 1
- assert isinstance(pri.values[0], ast.Num)
- assert pri.nl
- pri = self.get_first_stmt("print >> y")
- assert isinstance(pri.dest, ast.Name)
- assert pri.values is None
- assert pri.nl
-
def test_del(self):
d = self.get_first_stmt("del x")
assert isinstance(d, ast.Delete)
@@ -125,21 +108,14 @@
def test_raise(self):
ra = self.get_first_stmt("raise")
- assert ra.type is None
- assert ra.inst is None
- assert ra.tback is None
+ assert ra.exc is None
+ assert ra.cause is None
ra = self.get_first_stmt("raise x")
- assert isinstance(ra.type, ast.Name)
- assert ra.inst is None
- assert ra.tback is None
- ra = self.get_first_stmt("raise x, 3")
- assert isinstance(ra.type, ast.Name)
- assert isinstance(ra.inst, ast.Num)
- assert ra.tback is None
- ra = self.get_first_stmt("raise x, 4, 'hi'")
- assert isinstance(ra.type, ast.Name)
- assert isinstance(ra.inst, ast.Num)
- assert isinstance(ra.tback, ast.Str)
+ assert isinstance(ra.exc, ast.Name)
+ assert ra.cause is None
+ ra = self.get_first_stmt("raise x from 3")
+ assert isinstance(ra.exc, ast.Name)
+ assert isinstance(ra.cause, ast.Num)
def test_import(self):
im = self.get_first_stmt("import x")
@@ -225,20 +201,12 @@
glob = self.get_first_stmt("global x, y")
assert glob.names == ["x", "y"]
- def test_exec(self):
- exc = self.get_first_stmt("exec x")
- assert isinstance(exc, ast.Exec)
- assert isinstance(exc.body, ast.Name)
- assert exc.globals is None
- assert exc.locals is None
- exc = self.get_first_stmt("exec 'hi' in x")
- assert isinstance(exc.body, ast.Str)
- assert isinstance(exc.globals, ast.Name)
- assert exc.locals is None
- exc = self.get_first_stmt("exec 'hi' in x, 2")
- assert isinstance(exc.body, ast.Str)
- assert isinstance(exc.globals, ast.Name)
- assert isinstance(exc.locals, ast.Num)
+ def test_nonlocal(self):
+ nonloc = self.get_first_stmt("nonlocal x")
+ assert isinstance(nonloc, ast.Nonlocal)
+ assert nonloc.names == ["x"]
+ nonloc = self.get_first_stmt("nonlocal x, y")
+ assert nonloc.names == ["x", "y"]
def test_assert(self):
asrt = self.get_first_stmt("assert x")
@@ -343,13 +311,15 @@
assert isinstance(fr.orelse[0].value, ast.Num)
def test_try(self):
- tr = self.get_first_stmt("try: x\nfinally: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "finally: pass")
assert isinstance(tr, ast.TryFinally)
assert len(tr.body) == 1
assert isinstance(tr.body[0].value, ast.Name)
assert len(tr.finalbody) == 1
assert isinstance(tr.finalbody[0], ast.Pass)
- tr = self.get_first_stmt("try: x\nexcept: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except: pass")
assert isinstance(tr, ast.TryExcept)
assert len(tr.body) == 1
assert isinstance(tr.body[0].value, ast.Name)
@@ -361,7 +331,8 @@
assert len(handler.body) == 1
assert isinstance(handler.body[0], ast.Pass)
assert tr.orelse is None
- tr = self.get_first_stmt("try: x\nexcept Exception: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except Exception: pass")
assert len(tr.handlers) == 1
handler = tr.handlers[0]
assert isinstance(handler.type, ast.Name)
@@ -369,40 +340,48 @@
assert handler.name is None
assert len(handler.body) == 1
assert tr.orelse is None
- tr = self.get_first_stmt("try: x\nexcept Exception, e: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except Exception as e: pass")
assert len(tr.handlers) == 1
handler = tr.handlers[0]
assert isinstance(handler.type, ast.Name)
- assert isinstance(handler.name, ast.Name)
- assert handler.name.ctx == ast.Store
- assert handler.name.id == "e"
+ assert handler.type.id == "Exception"
+ assert handler.name == "e"
assert len(handler.body) == 1
- tr = self.get_first_stmt("try: x\nexcept: pass\nelse: 4")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except: pass" + "\n" +
+ "else: 4")
assert len(tr.body) == 1
assert isinstance(tr.body[0].value, ast.Name)
assert len(tr.handlers) == 1
assert isinstance(tr.handlers[0].body[0], ast.Pass)
assert len(tr.orelse) == 1
assert isinstance(tr.orelse[0].value, ast.Num)
- tr = self.get_first_stmt("try: x\nexcept Exc, a: 5\nexcept F: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except Exc as a: 5" + "\n" +
+ "except F: pass")
assert len(tr.handlers) == 2
h1, h2 = tr.handlers
assert isinstance(h1.type, ast.Name)
- assert isinstance(h1.name, ast.Name)
+ assert h1.name == "a"
assert isinstance(h1.body[0].value, ast.Num)
assert isinstance(h2.type, ast.Name)
assert h2.name is None
assert isinstance(h2.body[0], ast.Pass)
- tr = self.get_first_stmt("try: x\nexcept Exc as a: 5\nexcept F: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except Exc as a: 5" + "\n" +
+ "except F: pass")
assert len(tr.handlers) == 2
h1, h2 = tr.handlers
assert isinstance(h1.type, ast.Name)
- assert isinstance(h1.name, ast.Name)
+ assert h1.name == "a"
assert isinstance(h1.body[0].value, ast.Num)
assert isinstance(h2.type, ast.Name)
assert h2.name is None
assert isinstance(h2.body[0], ast.Pass)
- tr = self.get_first_stmt("try: x\nexcept: 4\nfinally: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except: 4" + "\n" +
+ "finally: pass")
assert isinstance(tr, ast.TryFinally)
assert len(tr.finalbody) == 1
assert isinstance(tr.finalbody[0], ast.Pass)
@@ -414,7 +393,10 @@
assert isinstance(exc.handlers[0].body[0].value, ast.Num)
assert len(exc.body) == 1
assert isinstance(exc.body[0].value, ast.Name)
- tr = self.get_first_stmt("try: x\nexcept: 4\nelse: 'hi'\nfinally: pass")
+ tr = self.get_first_stmt("try: x" + "\n" +
+ "except: 4" + "\n" +
+ "else: 'hi'" + "\n" +
+ "finally: pass")
assert isinstance(tr, ast.TryFinally)
assert len(tr.finalbody) == 1
assert isinstance(tr.finalbody[0], ast.Pass)
@@ -496,72 +478,40 @@
assert args.defaults is None
assert args.kwarg is None
assert args.vararg is None
+ assert func.returns is None
args = self.get_first_stmt("def f(a, b): pass").args
assert len(args.args) == 2
a1, a2 = args.args
- assert isinstance(a1, ast.Name)
- assert a1.id == "a"
- assert a1.ctx == ast.Param
- assert isinstance(a2, ast.Name)
- assert a2.id == "b"
- assert a2.ctx == ast.Param
+ assert isinstance(a1, ast.arg)
+ assert a1.arg == "a"
+ assert isinstance(a2, ast.arg)
+ assert a2.arg == "b"
assert args.vararg is None
assert args.kwarg is None
args = self.get_first_stmt("def f(a=b): pass").args
assert len(args.args) == 1
arg = args.args[0]
- assert isinstance(arg, ast.Name)
- assert arg.id == "a"
- assert arg.ctx == ast.Param
+ assert isinstance(arg, ast.arg)
+ assert arg.arg == "a"
assert len(args.defaults) == 1
default = args.defaults[0]
assert isinstance(default, ast.Name)
assert default.id == "b"
assert default.ctx == ast.Load
args = self.get_first_stmt("def f(*a): pass").args
- assert args.args is None
- assert args.defaults is None
+ assert not args.args
+ assert not args.defaults
assert args.kwarg is None
assert args.vararg == "a"
args = self.get_first_stmt("def f(**a): pass").args
- assert args.args is None
- assert args.defaults is None
+ assert not args.args
+ assert not args.defaults
assert args.vararg is None
assert args.kwarg == "a"
- args = self.get_first_stmt("def f((a, b)): pass").args
- assert args.defaults is None
- assert args.kwarg is None
- assert args.vararg is None
- assert len(args.args) == 1
- tup = args.args[0]
- assert isinstance(tup, ast.Tuple)
- assert tup.ctx == ast.Store
- assert len(tup.elts) == 2
- e1, e2 = tup.elts
- assert isinstance(e1, ast.Name)
- assert e1.ctx == ast.Store
- assert e1.id == "a"
- assert isinstance(e2, ast.Name)
- assert e2.ctx == ast.Store
- assert e2.id == "b"
- args = self.get_first_stmt("def f((a, (b, c))): pass").args
- assert len(args.args) == 1
- tup = args.args[0]
- assert isinstance(tup, ast.Tuple)
- assert len(tup.elts) == 2
- tup2 = tup.elts[1]
- assert isinstance(tup2, ast.Tuple)
- assert tup2.ctx == ast.Store
- for elt in tup2.elts:
- assert isinstance(elt, ast.Name)
- assert elt.ctx == ast.Store
- assert tup2.elts[0].id == "b"
- assert tup2.elts[1].id == "c"
args = self.get_first_stmt("def f(a, b, c=d, *e, **f): pass").args
assert len(args.args) == 3
for arg in args.args:
- assert isinstance(arg, ast.Name)
- assert arg.ctx == ast.Param
+ assert isinstance(arg, ast.arg)
assert len(args.defaults) == 1
assert isinstance(args.defaults[0], ast.Name)
assert args.defaults[0].ctx == ast.Load
@@ -570,9 +520,65 @@
input = "def f(a=b, c): pass"
exc = py.test.raises(SyntaxError, self.get_ast, input).value
assert exc.msg == "non-default argument follows default argument"
- input = "def f((x)=23): pass"
+
+ def test_kwonly_arguments(self):
+ fn = self.get_first_stmt("def f(a, b, c, *, kwarg): pass")
+ assert isinstance(fn, ast.FunctionDef)
+ assert len(fn.args.kwonlyargs) == 1
+ assert isinstance(fn.args.kwonlyargs[0], ast.arg)
+ assert fn.args.kwonlyargs[0].arg == "kwarg"
+ assert fn.args.kw_defaults == [None]
+ fn = self.get_first_stmt("def f(a, b, c, *args, kwarg): pass")
+ assert isinstance(fn, ast.FunctionDef)
+ assert len(fn.args.kwonlyargs) == 1
+ assert isinstance(fn.args.kwonlyargs[0], ast.arg)
+ assert fn.args.kwonlyargs[0].arg == "kwarg"
+ assert fn.args.kw_defaults == [None]
+ fn = self.get_first_stmt("def f(a, b, c, *, kwarg=2): pass")
+ assert isinstance(fn, ast.FunctionDef)
+ assert len(fn.args.kwonlyargs) == 1
+ assert isinstance(fn.args.kwonlyargs[0], ast.arg)
+ assert fn.args.kwonlyargs[0].arg == "kwarg"
+ assert len(fn.args.kw_defaults) == 1
+ assert isinstance(fn.args.kw_defaults[0], ast.Num)
+ input = "def f(p1, *, **k1): pass"
exc = py.test.raises(SyntaxError, self.get_ast, input).value
- assert exc.msg == "parenthesized arg with default"
+ assert exc.msg == "named arguments must follows bare *"
+
+ def test_function_annotation(self):
+ func = self.get_first_stmt("def f() -> X: pass")
+ assert isinstance(func.returns, ast.Name)
+ assert func.returns.id == "X"
+ assert func.returns.ctx == ast.Load
+ for stmt in "def f(x : 42): pass", "def f(x : 42=a): pass":
+ func = self.get_first_stmt(stmt)
+ assert isinstance(func.args.args[0].annotation, ast.Num)
+ assert isinstance(func.args.defaults[0], ast.Name)
+ func = self.get_first_stmt("def f(*x : 42): pass")
+ assert isinstance(func.args.varargannotation, ast.Num)
+ func = self.get_first_stmt("def f(**kw : 42): pass")
+ assert isinstance(func.args.kwargannotation, ast.Num)
+ func = self.get_first_stmt("def f(*, kw : 42=a): pass")
+ assert isinstance(func.args.kwonlyargs[0].annotation, ast.Num)
+
+ def test_lots_of_kwonly_arguments(self):
+ fundef = "def f("
+ for i in range(255):
+ fundef += "i%d, "%i
+ fundef += "*, key=100):\n pass\n"
+ py.test.raises(SyntaxError, self.get_first_stmt, fundef)
+
+ fundef2 = "def foo(i,*,"
+ for i in range(255):
+ fundef2 += "i%d, "%i
+ fundef2 += "lastarg):\n pass\n"
+ py.test.raises(SyntaxError, self.get_first_stmt, fundef)
+
+ fundef3 = "def f(i,*,"
+ for i in range(253):
+ fundef3 += "i%d, "%i
+ fundef3 += "lastarg):\n pass\n"
+ self.get_first_stmt(fundef3)
def test_decorators(self):
to_examine = (("def f(): pass", ast.FunctionDef),
@@ -664,6 +670,17 @@
assert isinstance(tup.elts[0], ast.Name)
assert tup.elts[0].ctx == ast.Store
+ def test_assign_starred(self):
+ assign = self.get_first_stmt("*a, b = x")
+ assert isinstance(assign, ast.Assign)
+ assert len(assign.targets) == 1
+ names = assign.targets[0]
+ assert len(names.elts) == 2
+ assert isinstance(names.elts[0], ast.Starred)
+ assert isinstance(names.elts[1], ast.Name)
+ assert isinstance(names.elts[0].value, ast.Name)
+ assert names.elts[0].value.id == "a"
+
def test_name(self):
name = self.get_first_expr("hi")
assert isinstance(name, ast.Name)
@@ -744,7 +761,6 @@
("{x for x in z}", "set comprehension"),
("{x : x for x in z}", "dict comprehension"),
("'str'", "literal"),
- ("u'str'", "literal"),
("b'bytes'", "literal"),
("()", "()"),
("23", "literal"),
@@ -752,7 +768,7 @@
("{1, 2, 3}", "literal"),
("(x > 4)", "comparison"),
("(x if y else a)", "conditional expression"),
- ("`x`", "repr")
+ ("...", "Ellipsis"),
)
test_contexts = (
("assign to", "%s = 23"),
@@ -782,15 +798,11 @@
"from x import y as %s",
"for %s in x: pass",
)
- for name in ("None", "__debug__"):
+ for name in "__debug__",:
for template in invalid:
input = template % (name,)
exc = py.test.raises(SyntaxError, self.get_ast, input).value
assert exc.msg == "cannot assign to %s" % (name,)
- # This is ok.
- self.get_ast("from None import x")
- self.get_ast("from x import None as y")
- self.get_ast("import None as x")
def test_lambda(self):
lam = self.get_first_expr("lambda x: expr")
@@ -799,13 +811,13 @@
assert isinstance(args, ast.arguments)
assert args.vararg is None
assert args.kwarg is None
- assert args.defaults is None
+ assert not args.defaults
assert len(args.args) == 1
- assert isinstance(args.args[0], ast.Name)
+ assert isinstance(args.args[0], ast.arg)
assert isinstance(lam.body, ast.Name)
lam = self.get_first_expr("lambda: True")
args = lam.args
- assert args.args is None
+ assert not args.args
lam = self.get_first_expr("lambda x=x: y")
assert len(lam.args.args) == 1
assert len(lam.args.defaults) == 1
@@ -1024,9 +1036,7 @@
slc = self.get_first_expr("x[::]").slice
assert slc.upper is None
assert slc.lower is None
- assert isinstance(slc.step, ast.Name)
- assert slc.step.id == "None"
- assert slc.step.ctx == ast.Load
+ assert slc.step is None
slc = self.get_first_expr("x[1:]").slice
assert isinstance(slc.lower, ast.Num)
assert slc.upper is None
@@ -1034,7 +1044,7 @@
slc = self.get_first_expr("x[1::]").slice
assert isinstance(slc.lower, ast.Num)
assert slc.upper is None
- assert isinstance(slc.step, ast.Name)
+ assert slc.step is None
slc = self.get_first_expr("x[:2]").slice
assert slc.lower is None
assert isinstance(slc.upper, ast.Num)
@@ -1042,7 +1052,7 @@
slc = self.get_first_expr("x[:2:]").slice
assert slc.lower is None
assert isinstance(slc.upper, ast.Num)
- assert isinstance(slc.step, ast.Name)
+ assert slc.step is None
slc = self.get_first_expr("x[2:2]").slice
assert isinstance(slc.lower, ast.Num)
assert isinstance(slc.upper, ast.Num)
@@ -1050,7 +1060,7 @@
slc = self.get_first_expr("x[2:2:]").slice
assert isinstance(slc.lower, ast.Num)
assert isinstance(slc.upper, ast.Num)
- assert isinstance(slc.step, ast.Name)
+ assert slc.step is None
slc = self.get_first_expr("x[::2]").slice
assert slc.lower is None
assert slc.upper is None
@@ -1066,8 +1076,6 @@
slc = self.get_first_expr("x[1:2:3]").slice
for field in (slc.lower, slc.upper, slc.step):
assert isinstance(field, ast.Num)
- sub = self.get_first_expr("x[...]")
- assert isinstance(sub.slice, ast.Ellipsis)
sub = self.get_first_expr("x[1,2,3]")
slc = sub.slice
assert isinstance(slc, ast.Index)
@@ -1083,10 +1091,11 @@
assert isinstance(complex_slc.upper, ast.Num)
assert complex_slc.step is None
- def test_repr(self):
- rep = self.get_first_expr("`x`")
- assert isinstance(rep, ast.Repr)
- assert isinstance(rep.value, ast.Name)
+ def test_ellipsis(self):
+ e = self.get_first_expr("...")
+ assert isinstance(e, ast.Ellipsis)
+ sub = self.get_first_expr("x[...]")
+ assert isinstance(sub.slice.value, ast.Ellipsis)
def test_string(self):
space = self.space
@@ -1096,8 +1105,12 @@
s = self.get_first_expr("'hi' ' implicitly' ' extra'")
assert isinstance(s, ast.Str)
assert space.eq_w(s.s, space.wrap("hi implicitly extra"))
+ s = self.get_first_expr("b'hi' b' implicitly' b' extra'")
+ assert isinstance(s, ast.Bytes)
+ assert space.eq_w(s.s, space.wrapbytes("hi implicitly extra"))
+ raises(SyntaxError, self.get_first_expr, "b'hello' 'world'")
sentence = u"Die Männer ärgen sich!"
- source = u"# coding: utf-7\nstuff = u'%s'" % (sentence,)
+ source = u"# coding: utf-7\nstuff = '%s'" % (sentence,)
info = pyparse.CompileInfo("<test>", "exec")
tree = self.parser.parse_source(source.encode("utf-7"), info)
assert info.encoding == "utf-7"
@@ -1105,6 +1118,17 @@
assert isinstance(s, ast.Str)
assert space.eq_w(s.s, space.wrap(sentence))
+ def test_string_pep3120(self):
+ space = self.space
+ japan = u'日本'
+ source = u"foo = '%s'" % japan
+ info = pyparse.CompileInfo("<test>", "exec")
+ tree = self.parser.parse_source(source.encode("utf-8"), info)
+ assert info.encoding == "utf-8"
+ s = ast_from_node(space, tree, info).body[0].value
+ assert isinstance(s, ast.Str)
+ assert space.eq_w(s.s, space.wrap(japan))
+
def test_number(self):
def get_num(s):
node = self.get_first_expr(s)
@@ -1115,14 +1139,11 @@
space = self.space
assert space.eq_w(get_num("32"), space.wrap(32))
assert space.eq_w(get_num("32.5"), space.wrap(32.5))
- assert space.eq_w(get_num("32L"), space.newlong(32))
- assert space.eq_w(get_num("32l"), space.newlong(32))
- assert space.eq_w(get_num("0L"), space.newlong(0))
assert space.eq_w(get_num("2"), space.wrap(2))
assert space.eq_w(get_num("13j"), space.wrap(13j))
assert space.eq_w(get_num("13J"), space.wrap(13J))
- assert space.eq_w(get_num("053"), space.wrap(053))
- assert space.eq_w(get_num("00053"), space.wrap(053))
+ assert space.eq_w(get_num("0o53"), space.wrap(053))
+ assert space.eq_w(get_num("0o0053"), space.wrap(053))
for num in ("0x53", "0X53", "0x0000053", "0X00053"):
assert space.eq_w(get_num(num), space.wrap(0x53))
assert space.eq_w(get_num("0Xb0d2"), space.wrap(0xb0d2))
@@ -1131,7 +1152,7 @@
assert space.eq_w(get_num("00000"), space.wrap(0))
assert space.eq_w(get_num("-3"), space.wrap(-3))
assert space.eq_w(get_num("-0"), space.wrap(0))
- assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL))
+ assert space.eq_w(get_num("-0xAAAAAA"), space.wrap(-0xAAAAAAL))
n = get_num(str(-sys.maxint - 1))
assert space.is_true(space.isinstance(n, space.w_int))
for num in ("0o53", "0O53", "0o0000053", "0O00053"):
@@ -1142,6 +1163,12 @@
py.test.raises(SyntaxError, self.get_ast, "0x")
py.test.raises(SyntaxError, self.get_ast, "0b")
py.test.raises(SyntaxError, self.get_ast, "0o")
+ py.test.raises(SyntaxError, self.get_ast, "32L")
+ py.test.raises(SyntaxError, self.get_ast, "32l")
+ py.test.raises(SyntaxError, self.get_ast, "0L")
+ py.test.raises(SyntaxError, self.get_ast, "-0xAAAAAAL")
+ py.test.raises(SyntaxError, self.get_ast, "053")
+ py.test.raises(SyntaxError, self.get_ast, "00053")
def check_comprehension(self, brackets, ast_type):
def brack(s):
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1,9 +1,11 @@
+from __future__ import division
import py
from pypy.interpreter.astcompiler import codegen, astbuilder, symtable, optimize
from pypy.interpreter.pyparser import pyparse
from pypy.interpreter.pyparser.test import expressions
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pyparser.error import SyntaxError, IndentationError
+from pypy.interpreter.error import OperationError
from pypy.tool import stdlib_opcode as ops
def compile_with_astcompiler(expr, mode, space):
@@ -40,15 +42,31 @@
source = str(py.code.Source(source))
space = self.space
code = compile_with_astcompiler(source, 'exec', space)
- # 2.7 bytecode is too different, the standard `dis` module crashes
+ # 3.2 bytecode is too different, the standard `dis` module crashes
# on older cpython versions
- if sys.version_info >= (2, 7):
+ if sys.version_info >= (3, 2):
+ # this will only (maybe) work in the far future, when we run pypy
+ # on top of Python 3. For now, it's just disabled
print
code.dump()
w_dict = space.newdict()
code.exec_code(space, w_dict, w_dict)
return w_dict
+ # on Python3 some reprs are different than Python2. Here is a collection
+ # of how the repr should be on on Python3 for some objects
+ PY3_REPR = {
+ int: "<class 'int'>",
+ float: "<class 'float'>",
+ }
+
+ def get_py3_repr(self, val):
+ try:
+ return self.PY3_REPR.get(val, repr(val))
+ except TypeError:
+ # e.g., for unhashable types
+ return repr(val)
+
def check(self, w_dict, evalexpr, expected):
# for now, we compile evalexpr with CPython's compiler but run
# it with our own interpreter to extract the data from w_dict
@@ -57,13 +75,16 @@
pyco_expr = PyCode._from_code(space, co_expr)
w_res = pyco_expr.exec_host_bytecode(w_dict, w_dict)
res = space.str_w(space.repr(w_res))
- if not isinstance(expected, float):
- noL = lambda expr: expr.replace('L', '')
- assert noL(res) == noL(repr(expected))
- else:
+ expected_repr = self.get_py3_repr(expected)
+ if isinstance(expected, float):
# Float representation can vary a bit between interpreter
# versions, compare the numbers instead.
assert eval(res) == expected
+ elif isinstance(expected, long):
+ assert expected_repr.endswith('L')
+ assert res == expected_repr[:-1] # in py3 we don't have the L suffix
+ else:
+ assert res == expected_repr
def simple_test(self, source, evalexpr, expected):
w_g = self.run(source)
@@ -89,12 +110,12 @@
yield self.st, func, "f(0)", 0
def test_argtuple(self):
- yield (self.simple_test, "def f( x, (y,z) ): return x,y,z",
- "f((1,2),(3,4))", ((1,2),3,4))
- yield (self.simple_test, "def f( x, (y,(z,t)) ): return x,y,z,t",
- "f(1,(2,(3,4)))", (1,2,3,4))
- yield (self.simple_test, "def f(((((x,),y),z),t),u): return x,y,z,t,u",
- "f(((((1,),2),3),4),5)", (1,2,3,4,5))
+ yield (self.error_test, "def f( x, (y,z) ): return x,y,z",
+ SyntaxError)
+ yield (self.error_test, "def f( x, (y,(z,t)) ): return x,y,z,t",
+ SyntaxError)
+ yield (self.error_test, "def f(((((x,),y),z),t),u): return x,y,z,t,u",
+ SyntaxError)
def test_constants(self):
for c in expressions.constants:
@@ -223,8 +244,7 @@
def test_funccalls(self):
decl = py.code.Source("""
def f(*args, **kwds):
- kwds = kwds.items()
- kwds.sort()
+ kwds = sorted(kwds.items())
return list(args) + kwds
""")
decl = str(decl) + '\n'
@@ -236,6 +256,16 @@
yield self.st, decl + "x=f(5, b=2, **{'a': 8})", "x", [5, ('a', 8),
('b', 2)]
+ def test_kwonly(self):
+ decl = py.code.Source("""
+ def f(a, *, b):
+ return a, b
+ """)
+ decl = str(decl) + '\n'
+ self.st(decl + "x=f(1, b=2)", "x", (1, 2))
+ operr = py.test.raises(OperationError, 'self.st(decl + "x=f(1, 2)", "x", (1, 2))')
+ assert operr.value.w_type is self.space.w_TypeError
+
def test_listmakers(self):
yield (self.st,
"l = [(j, i) for j in range(10) for i in range(j)"
@@ -315,7 +345,7 @@
from __foo__.bar import x
try:
A().m()
- except ImportError, e:
+ except ImportError as e:
msg = str(e)
''', "msg", "No module named __foo__")
@@ -377,13 +407,13 @@
return a
''', "foo docstring"),
('''def foo():
- """doc"""; print 1
+ """doc"""; assert 1
a=1
''', "doc"),
('''
class Foo(object): pass
foo = Foo()
- exec "'moduledoc'" in foo.__dict__
+ exec("'moduledoc'", foo.__dict__)
''', "moduledoc"),
]:
yield self.simple_test, source, "foo.__doc__", expected
@@ -448,16 +478,6 @@
yield self.st, decl, 'A,A1,A2,B2,C,C1,C2,D1,E,G,G1,G2,N1', \
(6,6 ,4 ,1 ,5,5 ,5 ,3 ,8,2,2 ,2 ,7 )
- decl = py.code.Source("""
- def f((a, b)):
- def g((c, d)):
- return (a, b, c, d)
- return g
- x = f((1, 2))((3, 4))
- """)
- decl = str(decl) + "\n"
- yield self.st, decl, 'x', (1, 2, 3, 4)
-
source = """if 1:
def f(a):
del a
@@ -508,7 +528,7 @@
else: # line 5
if 1: pass # line 6
import dis
- co = ireturn_example.func_code
+ co = ireturn_example.__code__
linestarts = list(dis.findlinestarts(co))
addrreturn = linestarts[-1][0]
x = [addrreturn == (len(co.co_code) - 4)]
@@ -516,8 +536,8 @@
""", 'x', [True, 3, 4, 6]
def test_type_of_constants(self):
- yield self.simple_test, "x=[0, 0L]", 'type(x[1])', long
- yield self.simple_test, "x=[(1,0), (1,0L)]", 'type(x[1][1])', long
+ yield self.simple_test, "x=[0, 0.]", 'type(x[1])', float
+ yield self.simple_test, "x=[(1,0), (1,0.)]", 'type(x[1][1])', float
yield self.simple_test, "x=['2?-', '2?-']", 'id(x[0])==id(x[1])', True
def test_pprint(self):
@@ -643,29 +663,27 @@
#Indexing
for key, value in self.reference.items():
self.assertEqual(d[key], value)
- knownkey = self.other.keys()[0]
+ knownkey = next(iter(self.other))
self.failUnlessRaises(KeyError, lambda:d[knownkey])
#len
self.assertEqual(len(p), 0)
self.assertEqual(len(d), len(self.reference))
#has_key
for k in self.reference:
- self.assert_(d.has_key(k))
self.assert_(k in d)
for k in self.other:
- self.failIf(d.has_key(k))
self.failIf(k in d)
#cmp
- self.assertEqual(cmp(p,p), 0)
- self.assertEqual(cmp(d,d), 0)
- self.assertEqual(cmp(p,d), -1)
- self.assertEqual(cmp(d,p), 1)
+ self.assert_(p == p)
+ self.assert_(d == d)
+ self.assert_(p < d)
+ self.assert_(d > p)
#__non__zero__
if p: self.fail("Empty mapping must compare to False")
if not d: self.fail("Full mapping must compare to True")
# keys(), items(), iterkeys() ...
def check_iterandlist(iter, lst, ref):
- self.assert_(hasattr(iter, 'next'))
+ self.assert_(hasattr(iter, '__next__'))
self.assert_(hasattr(iter, '__iter__'))
x = list(iter)
self.assert_(set(x)==set(lst)==set(ref))
@@ -674,8 +692,8 @@
check_iterandlist(d.itervalues(), d.values(), self.reference.values())
check_iterandlist(d.iteritems(), d.items(), self.reference.items())
#get
- key, value = d.iteritems().next()
- knownkey, knownvalue = self.other.iteritems().next()
+ key, value = next(d.iteritems())
+ knownkey, knownvalue = next(self.other.iteritems())
self.assertEqual(d.get(key, knownvalue), value)
self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
self.failIf(knownkey in d)
@@ -698,6 +716,15 @@
decl = str(decl) + '\n'
yield self.simple_test, decl, 'r', None
+ def test_assert(self):
+ decl = py.code.Source("""
+ try:
+ assert 0, 'hi'
+ except AssertionError as e:
+ msg = str(e)
+ """)
+ yield self.simple_test, decl, 'msg', 'hi'
+
def test_indentation_error(self):
source = py.code.Source("""
x
@@ -763,7 +790,7 @@
yield self.st, "y = lambda x: x", "y(4)", 4
def test_backquote_repr(self):
- yield self.st, "x = None; y = `x`", "y", "None"
+ py.test.raises(SyntaxError, self.simple_test, "y = `0`", None, None)
def test_deleting_attributes(self):
test = """if 1:
@@ -778,33 +805,72 @@
raise AssertionError("attribute not removed")"""
yield self.st, test, "X.__name__", "X"
+ def test_nonlocal(self):
+ test = """if 1:
+ def f():
+ y = 0
+ def g(x):
+ nonlocal y
+ y = x + 1
+ g(3)
+ return y"""
+ yield self.st, test, "f()", 4
+
+ def test_raise_from(self):
+ test = """if 1:
+ def f():
+ try:
+ raise TypeError() from ValueError()
+ except TypeError:
+ return 42
+ """
+ yield self.st, test, "f()", 42
+ # This line is needed for py.code to find the source.
+
+ def test_extended_unpacking(self):
+ func = """def f():
+ (a, *b, c) = 1, 2, 3, 4, 5
+ return a, b, c
+ """
+ yield self.st, func, "f()", (1, [2, 3, 4], 5)
+ func = """def f():
+ [a, *b, c] = 1, 2, 3, 4, 5
+ return a, b, c
+ """
+ yield self.st, func, "f()", (1, [2, 3, 4], 5)
+ func = """def f():
+ *a, = [1, 2, 3]
+ return a
+ """
+ yield self.st, func, "f()", [1, 2, 3]
+ func = """def f():
+ for a, *b, c in [(1, 2, 3, 4)]:
+ return a, b, c
+ """
+ yield self.st, func, "f()", (1, [2, 3], 4)
+ py.test.raises(SyntaxError, self.simple_test, "*a, *b = [1, 2]",
+ None, None)
+ py.test.raises(SyntaxError, self.simple_test, "a = [*b, c]",
+ None, None)
+ py.test.raises(SyntaxError, self.simple_test, "for *a in x: pass",
+ None, None)
+
class AppTestCompiler:
def test_docstring_not_loaded(self):
- import StringIO, dis, sys
+ import io, dis, sys
ns = {}
- exec "def f():\n 'hi'" in ns
+ exec("def f():\n 'hi'", ns)
f = ns["f"]
save = sys.stdout
- sys.stdout = output = StringIO.StringIO()
+ sys.stdout = output = io.StringIO()
try:
dis.dis(f)
finally:
sys.stdout = save
assert "0 ('hi')" not in output.getvalue()
- def test_print_to(self):
- exec """if 1:
- from StringIO import StringIO
- s = StringIO()
- print >> s, "hi", "lovely!"
- assert s.getvalue() == "hi lovely!\\n"
- s = StringIO()
- print >> s, "hi", "lovely!",
- assert s.getvalue() == "hi lovely!"
- """ in {}
-
class TestOptimizations:
def count_instructions(self, source):
code, blocks = generate_function_code(source, self.space)
@@ -841,14 +907,14 @@
def test_const_fold_unicode_subscr(self, monkeypatch):
source = """def f():
- return u"abc"[0]
+ return "abc"[0]
"""
counts = self.count_instructions(source)
assert counts == {ops.LOAD_CONST: 1, ops.RETURN_VALUE: 1}
# getitem outside of the BMP should not be optimized
source = """def f():
- return u"\U00012345"[0]
+ return "\U00012345"[0]
"""
counts = self.count_instructions(source)
assert counts == {ops.LOAD_CONST: 2, ops.BINARY_SUBSCR: 1,
@@ -856,7 +922,7 @@
monkeypatch.setattr(optimize, "MAXUNICODE", 0xFFFF)
source = """def f():
- return u"\uE01F"[0]
+ return "\uE01F"[0]
"""
counts = self.count_instructions(source)
assert counts == {ops.LOAD_CONST: 1, ops.RETURN_VALUE: 1}
@@ -865,11 +931,11 @@
# getslice is not yet optimized.
# Still, check a case which yields the empty string.
source = """def f():
- return u"abc"[:0]
+ return "abc"[:0]
"""
counts = self.count_instructions(source)
- assert counts == {ops.LOAD_CONST: 2, ops.SLICE+2: 1,
- ops.RETURN_VALUE: 1}
+ assert counts == {ops.LOAD_CONST: 3, ops.BUILD_SLICE: 1,
+ ops.BINARY_SUBSCR: 1, ops.RETURN_VALUE: 1}
def test_remove_dead_code(self):
source = """def f(x):
@@ -902,10 +968,10 @@
space = self.space
w_generator = space.appexec([], """():
d = {}
- exec '''def f(x):
+ exec('''def f(x):
return
yield 6
- ''' in d
+ ''', d)
return d['f'](5)
""")
assert 'generator' in space.str_w(space.repr(w_generator))
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -194,22 +194,22 @@
def immutable_unique_id(self, space):
return None
- def str_w(self, space):
- w_msg = typed_unwrap_error_msg(space, "string", self)
+ def bytes_w(self, space):
+ w_msg = typed_unwrap_error_msg(space, "bytes", self)
raise OperationError(space.w_TypeError, w_msg)
def unicode_w(self, space):
raise OperationError(space.w_TypeError,
- typed_unwrap_error_msg(space, "unicode", self))
+ typed_unwrap_error_msg(space, "string", self))
def int_w(self, space):
raise OperationError(space.w_TypeError,
typed_unwrap_error_msg(space, "integer", self))
-
+
def uint_w(self, space):
raise OperationError(space.w_TypeError,
typed_unwrap_error_msg(space, "integer", self))
-
+
def bigint_w(self, space):
raise OperationError(space.w_TypeError,
typed_unwrap_error_msg(space, "integer", self))
@@ -273,6 +273,7 @@
http://pypy.readthedocs.org/en/latest/objspace.html"""
full_exceptions = True # full support for exceptions (normalization & more)
+ py3k = True # are we interpreting py3k bytecode?
def __init__(self, config=None):
"NOT_RPYTHON: Basic initialization of objects."
@@ -296,7 +297,6 @@
self.check_signal_action = None # changed by the signal module
self.user_del_action = UserDelAction(self)
self.frame_trace_action = FrameTraceAction(self)
- self._code_of_sys_exc_info = None
from pypy.interpreter.pycode import cpython_magic, default_magic
self.our_magic = default_magic
@@ -337,9 +337,8 @@
def finish(self):
self.wait_for_thread_shutdown()
- w_exitfunc = self.sys.getdictvalue(self, 'exitfunc')
- if w_exitfunc is not None:
- self.call_function(w_exitfunc)
+ w_atexit = self.getbuiltinmodule('atexit')
+ self.call_method(w_atexit, '_run_exitfuncs')
from pypy.interpreter.module import Module
for w_mod in self.builtin_modules.values():
mod = self.interpclass_w(w_mod)
@@ -468,9 +467,9 @@
if name not in modules:
modules.append(name)
- # a bit of custom logic: rctime take precedence over time
+ # a bit of custom logic: time2 or rctime take precedence over time
# XXX this could probably be done as a "requires" in the config
- if 'rctime' in modules and 'time' in modules:
+ if ('time2' in modules or 'rctime' in modules) and 'time' in modules:
modules.remove('time')
if not self.config.objspace.nofaking:
@@ -507,24 +506,24 @@
self.exceptions_module = Module(self, w_name)
self.exceptions_module.install()
+ from pypy.module.imp import Module
+ w_name = self.wrap('imp')
+ mod = Module(self, w_name)
+ mod.install()
+
from pypy.module.sys import Module
w_name = self.wrap('sys')
self.sys = Module(self, w_name)
self.sys.install()
- from pypy.module.imp import Module
- w_name = self.wrap('imp')
- mod = Module(self, w_name)
- mod.install()
-
from pypy.module.__builtin__ import Module
- w_name = self.wrap('__builtin__')
+ w_name = self.wrap('builtins')
self.builtin = Module(self, w_name)
w_builtin = self.wrap(self.builtin)
w_builtin.install()
self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin)
- bootstrap_modules = set(('sys', 'imp', '__builtin__', 'exceptions'))
+ bootstrap_modules = set(('sys', 'imp', 'builtins', 'exceptions'))
installed_builtin_modules = list(bootstrap_modules)
exception_types_w = self.export_builtin_exceptions()
@@ -561,9 +560,15 @@
def export_builtin_exceptions(self):
"""NOT_RPYTHON"""
w_dic = self.exceptions_module.getdict(self)
- w_keys = self.call_method(w_dic, "keys")
exc_types_w = {}
- for w_name in self.unpackiterable(w_keys):
+ w_iter = self.iter(w_dic)
+ while True:
+ try:
+ w_name = self.next(w_iter)
+ except OperationError, e:
+ if not e.match(self, self.w_StopIteration):
+ raise
+ break
name = self.str_w(w_name)
if not name.startswith('__'):
excname = name
@@ -610,7 +615,7 @@
self.fromcache(State).build_api(self)
self.getbuiltinmodule('sys')
self.getbuiltinmodule('imp')
- self.getbuiltinmodule('__builtin__')
+ self.getbuiltinmodule('builtins')
for mod in self.builtin_modules.values():
mod.setup_after_space_initialization()
@@ -914,12 +919,6 @@
"""
return None
- def view_as_kwargs(self, w_dict):
- """ if w_dict is a kwargs-dict, return two lists, one of unwrapped
- strings and one of wrapped values. otherwise return (None, None)
- """
- return (None, None)
-
def newlist_str(self, list_s):
return self.newlist([self.wrap(s) for s in list_s])
@@ -927,19 +926,14 @@
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
if self.is_w(w_exc_type, w_check_class):
- return True # fast path (also here to handle string exceptions)
- try:
- if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
- for w_t in self.fixedview(w_check_class):
- if self.exception_match(w_exc_type, w_t):
- return True
- else:
- return False
- return self.exception_issubclass_w(w_exc_type, w_check_class)
- except OperationError, e:
- if e.match(self, self.w_TypeError): # string exceptions maybe
+ return True # fast path
+ if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
+ for w_t in self.fixedview(w_check_class):
+ if self.exception_match(w_exc_type, w_t):
+ return True
+ else:
return False
- raise
+ return self.exception_issubclass_w(w_exc_type, w_check_class)
def call_obj_args(self, w_callable, w_obj, args):
if not self.config.objspace.disable_call_speedhacks:
@@ -960,15 +954,10 @@
# start of hack for performance
from pypy.interpreter.function import Function, Method
if isinstance(w_func, Method):
- w_inst = w_func.w_instance
- if w_inst is not None:
- if nargs < 4:
- func = w_func.w_function
- if isinstance(func, Function):
- return func.funccall(w_inst, *args_w)
- elif args_w and (
- self.abstract_isinstance_w(args_w[0], w_func.w_class)):
- w_func = w_func.w_function
+ if nargs < 4:
+ func = w_func.w_function
+ if isinstance(func, Function):
+ return func.funccall(w_func.w_instance, *args_w)
if isinstance(w_func, Function):
return w_func.funccall(*args_w)
@@ -988,16 +977,10 @@
if not self.config.objspace.disable_call_speedhacks:
# start of hack for performance
if isinstance(w_func, Method):
- w_inst = w_func.w_instance
- if w_inst is not None:
- w_func = w_func.w_function
- # reuse callable stack place for w_inst
- frame.settopvalue(w_inst, nargs)
- nargs += 1
- elif nargs > 0 and (
- self.abstract_isinstance_w(frame.peekvalue(nargs-1), # :-(
- w_func.w_class)):
- w_func = w_func.w_function
+ # reuse callable stack place for w_inst
+ frame.settopvalue(w_func.w_instance, nargs)
+ nargs += 1
+ w_func = w_func.w_function
if isinstance(w_func, Function):
return w_func.funccall_valuestack(nargs, frame)
@@ -1030,26 +1013,8 @@
return w_value
return None
- def is_oldstyle_instance(self, w_obj):
- # xxx hack hack hack
- from pypy.module.__builtin__.interp_classobj import W_InstanceObject
- obj = self.interpclass_w(w_obj)
- return obj is not None and isinstance(obj, W_InstanceObject)
-
def callable(self, w_obj):
- if self.lookup(w_obj, "__call__") is not None:
- if self.is_oldstyle_instance(w_obj):
- # ugly old style class special treatment, but well ...
- try:
- self.getattr(w_obj, self.wrap("__call__"))
- return self.w_True
- except OperationError, e:
- if not e.match(self, self.w_AttributeError):
- raise
- return self.w_False
- else:
- return self.w_True
- return self.w_False
+ return self.wrap(self.lookup(w_obj, "__call__") is not None)
def issequence_w(self, w_obj):
return (self.findattr(w_obj, self.wrap("__getitem__")) is not None)
@@ -1059,7 +1024,7 @@
# The code below only works
# for the simple case (new-style instance).
- # These methods are patched with the full logic by the __builtin__
+ # These methods are patched with the full logic by the builtins
# module when it is loaded
def abstract_issubclass_w(self, w_cls1, w_cls2):
@@ -1078,8 +1043,7 @@
# Equivalent to 'obj.__class__'.
return self.type(w_obj)
- # CPython rules allows old style classes or subclasses
- # of BaseExceptions to be exceptions.
+ # CPython rules allows subclasses of BaseExceptions to be exceptions.
# This is slightly less general than the case above, so we prefix
# it with exception_
@@ -1305,7 +1269,7 @@
# unclear if there is any use at all for getting the bytes in
# the unicode buffer.)
try:
- return self.str_w(w_obj)
+ return self.bytes_w(w_obj)
except OperationError, e:
if not e.match(self, self.w_TypeError):
raise
@@ -1318,12 +1282,31 @@
return self.str_w(w_obj)
def str_w(self, w_obj):
- return w_obj.str_w(self)
+ if self.isinstance_w(w_obj, self.w_unicode):
+ try:
+ return self.unicode_w(w_obj).encode('ascii')
+ except UnicodeEncodeError:
+ w_bytes = self.call_method(w_obj, 'encode', self.wrap('utf-8'))
+ return self.bytes_w(w_bytes)
+ else:
+ return w_obj.bytes_w(self)
+
+ def bytes_w(self, w_obj):
+ return w_obj.bytes_w(self)
def str0_w(self, w_obj):
"Like str_w, but rejects strings with NUL bytes."
from pypy.rlib import rstring
- result = w_obj.str_w(self)
+ result = self.str_w(w_obj)
+ if '\x00' in result:
+ raise OperationError(self.w_TypeError, self.wrap(
+ 'argument must be a string without NUL characters'))
+ return rstring.assert_str0(result)
+
+ def bytes0_w(self, w_obj):
+ "Like bytes_w, but rejects strings with NUL bytes."
+ from pypy.rlib import rstring
+ result = self.bytes_w(w_obj)
if '\x00' in result:
raise OperationError(self.w_TypeError, self.wrap(
'argument must be a string without NUL characters'))
@@ -1454,8 +1437,7 @@
# not os.close(). It's likely designed for 'select'. It's irregular
# in the sense that it expects either a real int/long or an object
# with a fileno(), but not an object with an __int__().
- if (not self.isinstance_w(w_fd, self.w_int) and
- not self.isinstance_w(w_fd, self.w_long)):
+ if not self.isinstance_w(w_fd, self.w_int):
try:
w_fileno = self.getattr(w_fd, self.wrap("fileno"))
except OperationError, e:
@@ -1538,16 +1520,11 @@
('getitem', 'getitem', 2, ['__getitem__']),
('setitem', 'setitem', 3, ['__setitem__']),
('delitem', 'delitem', 2, ['__delitem__']),
- ('getslice', 'getslice', 3, ['__getslice__']),
- ('setslice', 'setslice', 4, ['__setslice__']),
- ('delslice', 'delslice', 3, ['__delslice__']),
('trunc', 'trunc', 1, ['__trunc__']),
('pos', 'pos', 1, ['__pos__']),
('neg', 'neg', 1, ['__neg__']),
- ('nonzero', 'truth', 1, ['__nonzero__']),
+ ('nonzero', 'truth', 1, ['__bool__']),
('abs' , 'abs', 1, ['__abs__']),
- ('hex', 'hex', 1, ['__hex__']),
- ('oct', 'oct', 1, ['__oct__']),
('ord', 'ord', 1, []),
('invert', '~', 1, ['__invert__']),
('add', '+', 2, ['__add__', '__radd__']),
@@ -1567,7 +1544,6 @@
('int', 'int', 1, ['__int__']),
('index', 'index', 1, ['__index__']),
('float', 'float', 1, ['__float__']),
- ('long', 'long', 1, ['__long__']),
('inplace_add', '+=', 2, ['__iadd__']),
('inplace_sub', '-=', 2, ['__isub__']),
('inplace_mul', '*=', 2, ['__imul__']),
@@ -1587,11 +1563,9 @@
('ne', '!=', 2, ['__ne__', '__ne__']),
('gt', '>', 2, ['__gt__', '__lt__']),
('ge', '>=', 2, ['__ge__', '__le__']),
- ('cmp', 'cmp', 2, ['__cmp__']), # rich cmps preferred
- ('coerce', 'coerce', 2, ['__coerce__', '__coerce__']),
('contains', 'contains', 2, ['__contains__']),
('iter', 'iter', 1, ['__iter__']),
- ('next', 'next', 1, ['next']),
+ ('next', 'next', 1, ['__next__']),
# ('call', 'call', 3, ['__call__']),
('get', 'get', 3, ['__get__']),
('set', 'set', 3, ['__set__']),
@@ -1601,7 +1575,7 @@
]
ObjSpace.BuiltinModuleTable = [
- '__builtin__',
+ 'builtins',
'sys',
]
@@ -1678,7 +1652,7 @@
ObjSpace.IrregularOpTable = [
'wrap',
- 'str_w',
+ 'bytes_w',
'int_w',
'float_w',
'uint_w',
More information about the pypy-commit
mailing list