Author: wenzhuman <[email protected]>
Branch: gc_no_cleanup_nursery
Changeset: r72706:3027c2c5d444
Date: 2014-08-05 23:28 -0700
http://bitbucket.org/pypy/pypy/changeset/3027c2c5d444/
Log: merge default
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -309,11 +309,9 @@
#endif
int _m_ispad(WINDOW *win) {
-#if defined WINDOW_HAS_FLAGS
+ // <curses.h> may not have _flags (and possibly _ISPAD),
+ // but for now let's assume that <ncurses.h> always has it
return (win->_flags & _ISPAD);
-#else
- return 0;
-#endif
}
void _m_getsyx(int *yx) {
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -740,7 +740,7 @@
Adding an entry under pypy/module (e.g. mymodule) entails automatic
creation of a new config option (such as --withmod-mymodule and
---withoutmod-mymodule (the later being the default)) for py.py and
+--withoutmod-mymodule (the latter being the default)) for py.py and
translate.py.
Testing modules in ``lib_pypy/``
@@ -931,7 +931,7 @@
assert self.result == 2 ** 6
which executes the code string function with the given arguments at app level.
-Note the use of ``w_result`` in ``setup_class`` but self.result in the test
+Note the use of ``w_result`` in ``setup_class`` but self.result in the test.
Here is how to define an app level class in ``setup_class`` that can be used
in subsequent tests::
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -74,9 +74,6 @@
zipimport
zlib
- When translated to Java or .NET, the list is smaller; see
- `pypy/config/pypyoption.py`_ for details.
-
When translated on Windows, a few Unix-only modules are skipped,
and the following module is built instead:
@@ -328,7 +325,7 @@
* directly calling the internal magic methods of a few built-in types
with invalid arguments may have a slightly different result. For
example, ``[].__add__(None)`` and ``(2).__add__(None)`` both return
- ``NotImplemented`` on PyPy; on CPython, only the later does, and the
+ ``NotImplemented`` on PyPy; on CPython, only the latter does, and the
former raises ``TypeError``. (Of course, ``[]+None`` and ``2+None``
both raise ``TypeError`` everywhere.) This difference is an
implementation detail that shows up because of internal C-level slots
diff --git a/pypy/doc/getting-started-python.rst
b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -50,6 +50,8 @@
libz-dev libbz2-dev libncurses-dev libexpat1-dev \
libssl-dev libgc-dev python-sphinx python-greenlet
+ For the optional lzma module on PyPy3 you will also need ``liblzma-dev``.
+
On a Fedora-16 box these are::
[user@fedora-or-rh-box ~]$ sudo yum install \
@@ -57,6 +59,8 @@
zlib-devel bzip2-devel ncurses-devel expat-devel \
openssl-devel gc-devel python-sphinx python-greenlet
+ For the optional lzma module on PyPy3 you will also need ``xz-devel``.
+
On SLES11:
$ sudo zypper install gcc make python-devel pkg-config \
@@ -74,6 +78,7 @@
* ``pkg-config`` (to help us locate libffi files)
* ``libz-dev`` (for the optional ``zlib`` module)
* ``libbz2-dev`` (for the optional ``bz2`` module)
+ * ``liblzma`` (for the optional ``lzma`` module, PyPy3 only)
* ``libsqlite3-dev`` (for the optional ``sqlite3`` module via cffi)
* ``libncurses-dev`` (for the optional ``_minimal_curses`` module)
* ``libexpat1-dev`` (for the optional ``pyexpat`` module)
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -102,7 +102,7 @@
.. _Python: http://docs.python.org/index.html
.. _`more...`: architecture.html#mission-statement
.. _`PyPy blog`: http://morepypy.blogspot.com/
-.. _`development bug/feature tracker`: https://bugs.pypy.org
+.. _`development bug/feature tracker`: https://bitbucket.org/pypy/pypy/issues
.. _here: http://www.tismer.com/pypy/irc-logs/pypy/
.. _`Mercurial commit mailing list`:
http://mail.python.org/mailman/listinfo/pypy-commit
.. _`development mailing list`:
http://mail.python.org/mailman/listinfo/pypy-dev
diff --git a/pypy/doc/you-want-to-help.rst b/pypy/doc/you-want-to-help.rst
--- a/pypy/doc/you-want-to-help.rst
+++ b/pypy/doc/you-want-to-help.rst
@@ -15,14 +15,14 @@
* Because of the above, we are very serious about Test Driven Development.
It's not only what we believe in, but also that PyPy's architecture is
working very well with TDD in mind and not so well without it. Often
- the development means progressing in an unrelated corner, one unittest
+ development means progressing in an unrelated corner, one unittest
at a time; and then flipping a giant switch, bringing it all together.
(It generally works out of the box. If it doesn't, then we didn't
- write enough unit tests.) It's worth repeating - PyPy
- approach is great if you do TDD, not so great otherwise.
+ write enough unit tests.) It's worth repeating - PyPy's
+ approach is great if you do TDD, and not so great otherwise.
* PyPy uses an entirely different set of tools - most of them included
- in the PyPy repository. There is no Makefile, nor autoconf. More below
+ in the PyPy repository. There is no Makefile, nor autoconf. More below.
Architecture
============
@@ -32,7 +32,7 @@
* `RPython`_ is the language in which we write interpreters. Not the entire
PyPy project is written in RPython, only the parts that are compiled in
the translation process. The interesting point is that RPython has no parser,
- it's compiled from the live python objects, which make it possible to do
+ it's compiled from the live python objects, which makes it possible to do
all kinds of metaprogramming during import time. In short, Python is a meta
programming language for RPython.
@@ -40,7 +40,7 @@
.. _`RPython`: coding-guide.html#RPython
-* The translation toolchain - this is the part that takes care about
translating
+* The translation toolchain - this is the part that takes care of translating
RPython to flow graphs and then to C. There is more in the `architecture`_
document written about it.
@@ -73,7 +73,7 @@
.. _`we have a tracing JIT`: jit/index.html
-* Garbage Collectors (GC): as you can notice if you are used to CPython's
+* Garbage Collectors (GC): as you may notice if you are used to CPython's
C code, there are no ``Py_INCREF/Py_DECREF`` equivalents in RPython code.
`Garbage collection in PyPy`_ is inserted
during translation. Moreover, this is not reference counting; it is a real
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -616,7 +616,8 @@
def descr_classmethod_get(self, space, w_obj, w_klass=None):
if space.is_none(w_klass):
w_klass = space.type(w_obj)
- return space.wrap(Method(space, self.w_function, w_klass,
space.w_None))
+ return space.wrap(Method(space, self.w_function, w_klass,
+ space.type(w_klass)))
def descr_classmethod__new__(space, w_subtype, w_function):
instance = space.allocate_instance(ClassMethod, w_subtype)
diff --git a/pypy/interpreter/pycompiler.py b/pypy/interpreter/pycompiler.py
--- a/pypy/interpreter/pycompiler.py
+++ b/pypy/interpreter/pycompiler.py
@@ -96,7 +96,7 @@
XXX: This class should override the baseclass implementation of
compile_command() in order to optimize it, especially in case
- of incomplete inputs (e.g. we shouldn't re-compile from sracth
+ of incomplete inputs (e.g. we shouldn't re-compile from scratch
the whole source after having only added a new '\n')
"""
def __init__(self, space, override_version=None):
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -200,7 +200,7 @@
elif opcode == opcodedesc.BREAK_LOOP.index:
next_instr = self.BREAK_LOOP(oparg, next_instr)
elif opcode == opcodedesc.CONTINUE_LOOP.index:
- next_instr = self.CONTINUE_LOOP(oparg, next_instr)
+ return self.CONTINUE_LOOP(oparg, next_instr)
elif opcode == opcodedesc.FOR_ITER.index:
next_instr = self.FOR_ITER(oparg, next_instr)
elif opcode == opcodedesc.JUMP_FORWARD.index:
diff --git a/pypy/interpreter/test/test_typedef.py
b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -388,6 +388,13 @@
# differs from .im_class in case the method is
# defined in some parent class of l's actual class
+ def test_classmethod_im_class(self):
+ class Foo(object):
+ @classmethod
+ def bar(cls):
+ pass
+ assert Foo.bar.im_class is type
+
def test_func_closure(self):
x = 2
def f():
diff --git a/pypy/module/__builtin__/app_inspect.py
b/pypy/module/__builtin__/app_inspect.py
--- a/pypy/module/__builtin__/app_inspect.py
+++ b/pypy/module/__builtin__/app_inspect.py
@@ -7,8 +7,8 @@
from __pypy__ import lookup_special
-def _caller_locals():
- return sys._getframe(0).f_locals
+def _caller_locals():
+ return sys._getframe(0).f_locals
def vars(*obj):
"""Return a dictionary of all the attributes currently bound in obj. If
@@ -17,12 +17,11 @@
if len(obj) == 0:
return _caller_locals()
elif len(obj) != 1:
- raise TypeError, "vars() takes at most 1 argument."
- else:
- try:
- return obj[0].__dict__
- except AttributeError:
- raise TypeError, "vars() argument must have __dict__ attribute"
+ raise TypeError("vars() takes at most 1 argument.")
+ try:
+ return obj[0].__dict__
+ except AttributeError:
+ raise TypeError("vars() argument must have __dict__ attribute")
def dir(*args):
"""dir([object]) -> list of strings
@@ -38,8 +37,7 @@
attributes of its class's base classes.
"""
if len(args) > 1:
- raise TypeError("dir expected at most 1 arguments, got %d"
- % len(args))
+ raise TypeError("dir expected at most 1 arguments, got %d" % len(args))
if len(args) == 0:
local_names = _caller_locals().keys() # 2 stackframes away
if not isinstance(local_names, list):
@@ -48,92 +46,61 @@
return local_names
import types
-
obj = args[0]
-
- dir_meth = None
if isinstance(obj, types.InstanceType):
- try:
- dir_meth = getattr(obj, "__dir__")
- except AttributeError:
- pass
+ dir_meth = getattr(obj, '__dir__', None)
else:
- dir_meth = lookup_special(obj, "__dir__")
+ dir_meth = lookup_special(obj, '__dir__')
if dir_meth is not None:
- result = dir_meth()
- if not isinstance(result, list):
+ names = dir_meth()
+ if not isinstance(names, list):
raise TypeError("__dir__() must return a list, not %r" % (
- type(result),))
- result.sort()
- return result
+ type(names),))
+ names.sort()
+ return names
elif isinstance(obj, types.ModuleType):
try:
- result = list(obj.__dict__)
- result.sort()
- return result
+ return sorted(obj.__dict__)
except AttributeError:
return []
-
elif isinstance(obj, (types.TypeType, types.ClassType)):
- #Don't look at __class__, as metaclass methods would be confusing.
- result = _classdir(obj).keys()
- result.sort()
- return result
-
- else: #(regular item)
- Dict = {}
- try:
- if isinstance(obj.__dict__, dict):
- Dict.update(obj.__dict__)
- except AttributeError:
- pass
- try:
- Dict.update(_classdir(obj.__class__))
- except AttributeError:
- pass
+ # Don't look at __class__, as metaclass methods would be confusing.
+ return sorted(_classdir(obj))
+ else:
+ names = set()
+ ns = getattr(obj, '__dict__', None)
+ if isinstance(ns, dict):
+ names.update(ns)
+ klass = getattr(obj, '__class__', None)
+ if klass is not None:
+ names.update(_classdir(klass))
## Comment from object.c:
## /* Merge in __members__ and __methods__ (if any).
## XXX Would like this to go away someday; for now, it's
## XXX needed to get at im_self etc of method objects. */
- for attr in ['__members__','__methods__']:
- try:
- l = getattr(obj, attr)
- if not isinstance(l, list):
- continue
- for item in l:
- if isinstance(item, types.StringTypes):
- Dict[item] = None
- except (AttributeError, TypeError):
- pass
+ for attr in '__members__', '__methods__':
+ l = getattr(obj, attr, None)
+ if not isinstance(l, list):
+ continue
+ names.extend(item for item in l if isinstance(item, str))
- result = Dict.keys()
- result.sort()
- return result
+ return sorted(names)
def _classdir(klass):
- """Return a dict of the accessible attributes of class/type klass.
+ """Return a set of the accessible attributes of class/type klass.
- This includes all attributes of klass and all of the
- base classes recursively.
-
- The values of this dict have no meaning - only the keys have
- meaning.
+ This includes all attributes of klass and all of the base classes
+ recursively.
"""
- Dict = {}
- try:
- Dict.update(klass.__dict__)
- except AttributeError: pass
- try:
- # XXX - Use of .__mro__ would be suggested, if the existance
- # of that attribute could be guarranted.
- bases = klass.__bases__
- except AttributeError: pass
- else:
- try:
- #Note that since we are only interested in the keys,
- # the order we merge classes is unimportant
- for base in bases:
- Dict.update(_classdir(base))
- except TypeError: pass
- return Dict
+ names = set()
+ ns = getattr(klass, '__dict__', None)
+ if ns is not None:
+ names.update(ns)
+ bases = getattr(klass, '__bases__', None)
+ if bases is not None:
+ # Note that since we are only interested in the keys, the order
+ # we merge classes is unimportant
+ for base in bases:
+ names.update(_classdir(base))
+ return names
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -30,10 +30,6 @@
raise NotImplementedError
def descr_reduce(self, space):
- """
- XXX to do: remove this __reduce__ method and do
- a registration with copy_reg, instead.
- """
from pypy.interpreter.mixedmodule import MixedModule
w_mod = space.getbuiltinmodule('_pickle_support')
mod = space.interp_w(MixedModule, w_mod)
@@ -125,10 +121,6 @@
self.index = space.int_w(self.w_len) + index
def descr_reduce(self, space):
- """
- XXX to do: remove this __reduce__ method and do
- a registration with copy_reg, instead.
- """
from pypy.interpreter.mixedmodule import MixedModule
w_mod = space.getbuiltinmodule('_pickle_support')
mod = space.interp_w(MixedModule, w_mod)
diff --git a/rpython/flowspace/test/test_model.py
b/rpython/flowspace/test/test_model.py
--- a/rpython/flowspace/test/test_model.py
+++ b/rpython/flowspace/test/test_model.py
@@ -13,7 +13,7 @@
class pieces:
""" The manually-built graph corresponding to the sample_function().
"""
- i = Variable("i")
+ i0 = Variable("i0")
i1 = Variable("i1")
i2 = Variable("i2")
i3 = Variable("i3")
@@ -25,12 +25,12 @@
conditionop = SpaceOperation("gt", [i1, Constant(0)], conditionres)
addop = SpaceOperation("add", [sum2, i2], sum3)
decop = SpaceOperation("sub", [i2, Constant(1)], i3)
- startblock = Block([i])
+ startblock = Block([i0])
headerblock = Block([i1, sum1])
whileblock = Block([i2, sum2])
graph = FunctionGraph("f", startblock)
- startblock.closeblock(Link([i, Constant(0)], headerblock))
+ startblock.closeblock(Link([i0, Constant(0)], headerblock))
headerblock.operations.append(conditionop)
headerblock.exitswitch = conditionres
headerblock.closeblock(Link([sum1], graph.returnblock, False),
@@ -55,7 +55,7 @@
def test_graphattributes():
assert graph.startblock is pieces.startblock
assert graph.returnblock is pieces.headerblock.exits[0].target
- assert graph.getargs() == [pieces.i]
+ assert graph.getargs() == [pieces.i0]
assert [graph.getreturnvar()] == graph.returnblock.inputargs
assert graph.source == inspect.getsource(sample_function)
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py
b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -21,7 +21,7 @@
# this is a basic test that tries to hit a number of features and their
# translation:
# - jitting of loops and bridges
- # - virtualizables
+ # - two virtualizable types
# - set_param interface
# - profiler
# - full optimizer
@@ -79,22 +79,28 @@
if rposix.get_errno() != total: raise ValueError
return chr(total % 253)
#
+ class Virt2(object):
+ _virtualizable_ = ['i']
+ def __init__(self, i):
+ self.i = i
from rpython.rlib.libffi import types, CDLL, ArgChain
from rpython.rlib.test.test_clibffi import get_libm_name
libm_name = get_libm_name(sys.platform)
- jitdriver2 = JitDriver(greens=[], reds = ['i', 'func', 'res', 'x'])
+ jitdriver2 = JitDriver(greens=[], reds = ['v2', 'func', 'res', 'x'],
+ virtualizables = ['v2'])
def libffi_stuff(i, j):
lib = CDLL(libm_name)
func = lib.getpointer('fabs', [types.double], types.double)
res = 0.0
x = float(j)
- while i > 0:
- jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x)
+ v2 = Virt2(i)
+ while v2.i > 0:
+ jitdriver2.jit_merge_point(v2=v2, res=res, func=func, x=x)
promote(func)
argchain = ArgChain()
argchain.arg(x)
res = func.call(argchain, rffi.DOUBLE)
- i -= 1
+ v2.i -= 1
return res
#
def main(i, j):
diff --git a/rpython/jit/metainterp/test/test_virtualizable.py
b/rpython/jit/metainterp/test/test_virtualizable.py
--- a/rpython/jit/metainterp/test/test_virtualizable.py
+++ b/rpython/jit/metainterp/test/test_virtualizable.py
@@ -1611,6 +1611,40 @@
op.getopnum() == rop.GUARD_NOT_FORCED_2]
assert len(l) == 0
+ def test_two_virtualizable_types(self):
+ class A:
+ _virtualizable_ = ['x']
+ def __init__(self, x):
+ self.x = x
+
+ class B:
+ _virtualizable_ = ['lst[*]']
+ def __init__(self, lst):
+ self.lst = lst
+
+ driver_a = JitDriver(greens=[], reds=['a'], virtualizables=['a'])
+ driver_b = JitDriver(greens=[], reds=['b'], virtualizables=['b'])
+
+ def foo_a(a):
+ while a.x > 0:
+ driver_a.jit_merge_point(a=a)
+ a.x -= 2
+ return a.x
+
+ def foo_b(b):
+ while b.lst[0] > 0:
+ driver_b.jit_merge_point(b=b)
+ b.lst[0] -= 2
+ return b.lst[0]
+
+ def f():
+ return foo_a(A(13)) * 100 + foo_b(B([13]))
+
+ assert f() == -101
+ res = self.meta_interp(f, [], listops=True)
+ assert res == -101
+
+
class TestLLtype(ExplicitVirtualizableTests,
ImplicitVirtualizableTests,
LLJitMixin):
diff --git a/rpython/jit/metainterp/test/test_virtualref.py
b/rpython/jit/metainterp/test/test_virtualref.py
--- a/rpython/jit/metainterp/test/test_virtualref.py
+++ b/rpython/jit/metainterp/test/test_virtualref.py
@@ -34,7 +34,7 @@
#
def check_call(op, fname):
assert op.opname == 'direct_call'
- assert op.args[0].value._obj._name == fname
+ assert op.args[0].value._obj._name.startswith(fname)
#
ops = [op for block, op in graph.iterblockops()]
check_call(ops[-3], 'virtual_ref')
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -340,6 +340,7 @@
# ____________________________________________________________
# VRefs
[email protected](0)
def virtual_ref(x):
"""Creates a 'vref' object that contains a reference to 'x'. Calls
to virtual_ref/virtual_ref_finish must be properly nested. The idea
@@ -351,6 +352,7 @@
return DirectJitVRef(x)
virtual_ref.oopspec = 'virtual_ref(x)'
[email protected](1)
def virtual_ref_finish(vref, x):
"""See docstring in virtual_ref(x)"""
keepalive_until_here(x) # otherwise the whole function call is removed
diff --git a/rpython/rtyper/lltypesystem/lltype.py
b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -1155,7 +1155,12 @@
type(other).__name__,))
if self._TYPE != other._TYPE:
raise TypeError("comparing %r and %r" % (self._TYPE, other._TYPE))
- return self._obj == other._obj
+ try:
+ return self._obj == other._obj
+ except DelayedPointer:
+ # if one of the two pointers is delayed, they cannot
+ # possibly be equal unless they are the same _ptr instance
+ return self is other
def __ne__(self, other):
return not (self == other)
diff --git a/rpython/rtyper/normalizecalls.py b/rpython/rtyper/normalizecalls.py
--- a/rpython/rtyper/normalizecalls.py
+++ b/rpython/rtyper/normalizecalls.py
@@ -93,7 +93,12 @@
return False # nothing to do, all signatures already match
shape_cnt, shape_keys, shape_star = shape
- assert not shape_star, "XXX not implemented"
+ if shape_star:
+ raise TyperError(
+ "not implemented: a call is done with a '*' argument, and the"
+ " multiple functions or methods that it can go to don't have"
+ " all the same signature (different argument names or defaults)."
+ " The call can go to:\n%s" % '\n'.join(map(repr, graphs)))
# for the first 'shape_cnt' arguments we need to generalize to
# a common type
diff --git a/rpython/rtyper/test/test_annlowlevel.py
b/rpython/rtyper/test/test_annlowlevel.py
--- a/rpython/rtyper/test/test_annlowlevel.py
+++ b/rpython/rtyper/test/test_annlowlevel.py
@@ -64,3 +64,13 @@
assert lltype.typeOf(ptr) == OBJECTPTR
y = annlowlevel.cast_base_ptr_to_instance(X, ptr)
assert y is x
+
+ def test_delayedptr(self):
+ FUNCTYPE = lltype.FuncType([], lltype.Signed)
+ name = "delayed!myfunc"
+ delayedptr1 = lltype._ptr(lltype.Ptr(FUNCTYPE), name, solid=True)
+ delayedptr2 = lltype._ptr(lltype.Ptr(FUNCTYPE), name, solid=True)
+ assert delayedptr1 == delayedptr1
+ assert delayedptr1 != delayedptr2
+ assert bool(delayedptr1)
+ assert delayedptr1 != lltype.nullptr(FUNCTYPE)
diff --git a/rpython/rtyper/test/test_normalizecalls.py
b/rpython/rtyper/test/test_normalizecalls.py
--- a/rpython/rtyper/test/test_normalizecalls.py
+++ b/rpython/rtyper/test/test_normalizecalls.py
@@ -192,6 +192,25 @@
import re
assert re.match(msg, excinfo.value.args[0])
+ def test_methods_with_named_arg_call(self):
+ class Base:
+ def fn(self, y):
+ raise NotImplementedError
+ class Sub1(Base):
+ def fn(self, y):
+ return 1 + y
+ class Sub2(Base):
+ def fn(self, x): # different name!
+ return x - 2
+ def dummyfn(n):
+ if n == 1:
+ s = Sub1()
+ else:
+ s = Sub2()
+ return s.fn(*(n,))
+
+ py.test.raises(TyperError, self.rtype, dummyfn, [int], int)
+
class PBase:
def fn(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit