Commits

Konstantin Lopuhin  committed 901682d Merge

merge default

  • Participants
  • Parent commits bf34393, 439617e
  • Branches bridge-logging

Comments (0)

Files changed (275)

File .tddium.requirements.txt

+pytest

File lib-python/2/pickle.py

 except ImportError:
     from StringIO import StringIO
 
-try:
-    from __pypy__.builders import StringBuilder
-except ImportError:
-    assert '__pypy__' not in sys.builtin_module_names
-    StringBuilderFile = StringIO
-else:
-    class StringBuilderFile(object):
-        ''' pickle uses only file.write - provide this method,
-        use StringBuilder for speed
-        '''
-        def __init__(self):
-            self.builder = StringBuilder()
-            self.write = self.builder.append
-            self.getvalue = self.builder.build
-
 def dump(obj, file, protocol=None):
     Pickler(file, protocol).dump(obj)
 
 def dumps(obj, protocol=None):
-    file = StringBuilderFile()
+    file = StringIO()
     Pickler(file, protocol).dump(obj)
     return file.getvalue()
 

File lib_pypy/cPickle.py

 
 from pickle import StringIO
 
-try:
-    from pickle import StringBuilderFile
-except ImportError:
-    assert '__pypy__' not in sys.builtin_module_names
-    StringBuilderFile = StringIO
-
 PythonPickler = Pickler
 class Pickler(PythonPickler):
     def __init__(self, *args, **kw):
         self.__f = None
         if len(args) == 1 and isinstance(args[0], int):
-            self.__f = StringBuilderFile()
+            self.__f = StringIO()
             PythonPickler.__init__(self, self.__f, args[0], **kw)
         else:
             PythonPickler.__init__(self, *args, **kw)
 
 @builtinify
 def dumps(obj, protocol=None):
-    file = StringBuilderFile()
+    file = StringIO()
     Pickler(file, protocol).dump(obj)
     return file.getvalue()
 

File lib_pypy/tputil.py

 """
 
-application level support module for transparent proxies. 
+application level support module for transparent proxies.
 
 """
-from __pypy__ import tproxy 
+from __pypy__ import tproxy
 from types import MethodType
 
 _dummy = object()
 origtype = type
 
-def make_proxy(controller, type=_dummy, obj=_dummy): 
-    """ return a tranparent proxy controlled by the given 
-        'controller' callable.  The proxy will appear 
-        as a completely regular instance of the given 
-        type but all operations on it are send to the 
-        specified controller - which receives on 
-        ProxyOperation instance on each such call.  
-        A non-specified type will default to type(obj) 
-        if obj is specified. 
+def make_proxy(controller, type=_dummy, obj=_dummy):
+    """ return a tranparent proxy controlled by the given
+        'controller' callable.  The proxy will appear
+        as a completely regular instance of the given
+        type but all operations on it are send to the
+        specified controller - which receives on
+        ProxyOperation instance on each such call.
+        A non-specified type will default to type(obj)
+        if obj is specified.
     """
-    if type is _dummy: 
-        if obj is _dummy: 
-            raise TypeError("you must specify a type or an instance obj of it") 
-        type = origtype(obj) 
+    if type is _dummy:
+        if obj is _dummy:
+            raise TypeError("you must specify a type or an instance obj of it")
+        type = origtype(obj)
     def perform(opname, *args, **kwargs):
         operation = ProxyOperation(tp, obj, opname, args, kwargs)
-        return controller(operation) 
-    tp = tproxy(type, perform) 
-    return tp 
+        return controller(operation)
+    tp = tproxy(type, perform)
+    return tp
 
 class ProxyOperation(object):
     def __init__(self, proxyobj, obj, opname, args, kwargs):
         self.proxyobj = proxyobj
-        self.opname = opname 
+        self.opname = opname
         self.args = args
         self.kwargs = kwargs
-        if obj is not _dummy: 
-            self.obj = obj 
+        if obj is not _dummy:
+            self.obj = obj
 
     def delegate(self):
-        """ return result from delegating this operation to the 
-            underyling self.obj - which must exist and is usually 
-            provided through the initial make_proxy(..., obj=...) 
-            creation. 
-        """ 
+        """ return result from delegating this operation to the
+            underyling self.obj - which must exist and is usually
+            provided through the initial make_proxy(..., obj=...)
+            creation.
+        """
         try:
             obj = getattr(self, 'obj')
-        except AttributeError: 
+        except AttributeError:
             raise TypeError("proxy does not have an underlying 'obj', "
                             "cannot delegate")
-        objattr = getattr(obj, self.opname) 
-        res = objattr(*self.args, **self.kwargs) 
-        if self.opname == "__getattribute__": 
+        objattr = getattr(obj, self.opname)
+        res = objattr(*self.args, **self.kwargs)
+        if self.opname == "__getattribute__":
             if (isinstance(res, MethodType) and
                 res.im_self is self.instance):
                 res = MethodType(res.im_func, self.proxyobj, res.im_class)
-        if res is self.obj: 
+        if res is self.obj:
             res = self.proxyobj
-        return res 
+        return res
 
     def __repr__(self):
         args = ", ".join([repr(x) for x in self.args])
-        args = "<0x%x>, " % id(self.proxyobj) + args 
+        args = "<0x%x>, " % id(self.proxyobj) + args
         if self.kwargs:
-            args += ", ".join(["%s=%r" % item 
+            args += ", ".join(["%s=%r" % item
                                   for item in self.kwargs.items()])
         return "<ProxyOperation %s.%s(%s)>" %(
                     type(self.proxyobj).__name__, self.opname, args)

File pypy/config/pypyoption.py

         BoolOption("withtproxy", "support transparent proxies",
                    default=True),
 
-        BoolOption("withsmallint", "use tagged integers",
-                   default=False,
-                   requires=[("objspace.std.withprebuiltint", False),
-                             ("translation.taggedpointers", True)]),
-
         BoolOption("withprebuiltint", "prebuild commonly used int objects",
                    default=False),
 
                   default=100, cmdline="--prebuiltintto"),
 
         BoolOption("withsmalllong", "use a version of 'long' in a C long long",
-                   default=False,
-                   requires=[("objspace.std.withsmallint", False)]),
-                             #  ^^^ because of missing delegate_xx2yy
+                   default=False),
 
         BoolOption("withstrbuf", "use strings optimized for addition (ver 2)",
                    default=False),

File pypy/config/test/test_pypyoption.py

 
     assert conf.objspace.usemodules.gc
 
-    conf.objspace.std.withsmallint = True
-    assert not conf.objspace.std.withprebuiltint
+    conf.objspace.std.withmapdict = True
+    assert conf.objspace.std.withmethodcache
     conf = get_pypy_config()
-    conf.objspace.std.withprebuiltint = True
-    py.test.raises(ConfigError, "conf.objspace.std.withsmallint = True")
+    conf.objspace.std.withmethodcache = False
+    py.test.raises(ConfigError, "conf.objspace.std.withmapdict = True")
 
 def test_conflicting_gcrootfinder():
     conf = get_pypy_config()

File pypy/doc/config/objspace.std.withsmallint.txt

-Use "tagged pointers" to represent small enough integer values: Integers that
-fit into 31 bits (respective 63 bits on 64 bit machines) are not represented by
-boxing them in an instance of ``W_IntObject``. Instead they are represented as a
-pointer having the lowest bit set and the rest of the bits used to store the
-value of the integer. This gives a small speedup for integer operations as well
-as better memory behaviour.

File pypy/doc/discussion/improve-rpython.rst

   implement a pypy module. A typical rpython file is likely to contain many
   `import` statements::
 
-    from pypy.interpreter.baseobjspace import Wrappable
+    from pypy.interpreter.baseobjspace import W_Root
     from pypy.interpreter.gateway import ObjSpace, W_Root
     from pypy.interpreter.argument import Arguments
     from pypy.interpreter.typedef import TypeDef, GetSetProperty
 
 - A more direct declarative way to write Typedef::
 
-    class W_Socket(Wrappable):
+    class W_Socket(W_Root):
         _typedef_name_ = 'socket'
         _typedef_base_ = W_EventualBaseClass
 

File pypy/doc/interpreter.rst

 ===================================
-Bytecode Interpreter 
+Bytecode Interpreter
 ===================================
 
 .. contents::
 Introduction and Overview
 ===============================
 
-This document describes the implementation of PyPy's 
-Bytecode Interpreter and related Virtual Machine functionalities. 
+This document describes the implementation of PyPy's
+Bytecode Interpreter and related Virtual Machine functionalities.
 
 PyPy's bytecode interpreter has a structure reminiscent of CPython's
 Virtual Machine: It processes code objects parsed and compiled from
 translated with the rest of PyPy.
 
 Code objects contain
-condensed information about their respective functions, class and 
+condensed information about their respective functions, class and
 module body source codes.  Interpreting such code objects means
 instantiating and initializing a `Frame class`_ and then
-calling its ``frame.eval()`` method.  This main entry point 
-initialize appropriate namespaces and then interprets each 
+calling its ``frame.eval()`` method.  This main entry point
+initialize appropriate namespaces and then interprets each
 bytecode instruction.  Python's standard library contains
-the `lib-python/2.7/dis.py`_ module which allows to inspection 
-of the virtual machine's bytecode instructions:: 
+the `lib-python/2.7/dis.py`_ module which allows to inspection
+of the virtual machine's bytecode instructions::
 
     >>> import dis
     >>> def f(x):
     >>> dis.dis(f)
     2         0 LOAD_FAST                0 (x)
               3 LOAD_CONST               1 (1)
-              6 BINARY_ADD          
-              7 RETURN_VALUE        
+              6 BINARY_ADD
+              7 RETURN_VALUE
 
 CPython and PyPy are stack-based virtual machines, i.e.
 they don't have registers but instead push object to and pull objects
 from a stack.  The bytecode interpreter is only responsible
 for implementing control flow and pushing and pulling black
-box objects to and from this value stack.  The bytecode interpreter 
+box objects to and from this value stack.  The bytecode interpreter
 does not know how to perform operations on those black box
 (`wrapped`_) objects for which it delegates to the `object
 space`_.  In order to implement a conditional branch in a program's
 execution, however, it needs to gain minimal knowledge about a
 wrapped object.  Thus, each object space has to offer a
 ``is_true(w_obj)`` operation which returns an
-interpreter-level boolean value.  
+interpreter-level boolean value.
 
 For the understanding of the interpreter's inner workings it
 is crucial to recognize the concepts of `interpreter-level and
 application-level`_ code.  In short, interpreter-level is executed
-directly on the machine and invoking application-level functions 
-leads to an bytecode interpretation indirection. However, 
+directly on the machine and invoking application-level functions
+leads to an bytecode interpretation indirection. However,
 special care must be taken regarding exceptions because
-application level exceptions are wrapped into ``OperationErrors`` 
-which are thus distinguished from plain interpreter-level exceptions. 
+application level exceptions are wrapped into ``OperationErrors``
+which are thus distinguished from plain interpreter-level exceptions.
 See `application level exceptions`_ for some more information
-on ``OperationErrors``. 
+on ``OperationErrors``.
 
 The interpreter implementation offers mechanisms to allow a
-caller to be unaware of whether a particular function invocation 
+caller to be unaware of whether a particular function invocation
 leads to bytecode interpretation or is executed directly at
 interpreter-level.  The two basic kinds of `Gateway classes`_
 expose either an interpreter-level function to
 application-level execution (``interp2app``) or allow
 transparent invocation of application-level helpers
-(``app2interp``) at interpreter-level. 
+(``app2interp``) at interpreter-level.
 
-Another task of the bytecode interpreter is to care for exposing its 
-basic code, frame, module and function objects to application-level 
-code.  Such runtime introspection and modification abilities are 
-implemented via `interpreter descriptors`_ (also see Raymond Hettingers 
-`how-to guide for descriptors`_ in Python, PyPy uses this model extensively). 
+Another task of the bytecode interpreter is to care for exposing its
+basic code, frame, module and function objects to application-level
+code.  Such runtime introspection and modification abilities are
+implemented via `interpreter descriptors`_ (also see Raymond Hettingers
+`how-to guide for descriptors`_ in Python, PyPy uses this model extensively).
 
-A significant complexity lies in `function argument parsing`_.  Python as a 
-language offers flexible ways of providing and receiving arguments 
-for a particular function invocation.  Not only does it take special care 
+A significant complexity lies in `function argument parsing`_.  Python as a
+language offers flexible ways of providing and receiving arguments
+for a particular function invocation.  Not only does it take special care
 to get this right, it also presents difficulties for the `annotation
 pass`_ which performs a whole-program analysis on the
 bytecode interpreter, argument parsing and gatewaying code
 in order to infer the types of all values flowing across function
-calls. 
+calls.
 
 It is for this reason that PyPy resorts to generate
 specialized frame classes and functions at `initialization
-time`_ in order to let the annotator only see rather static 
-program flows with homogeneous name-value assignments on 
-function invocations. 
+time`_ in order to let the annotator only see rather static
+program flows with homogeneous name-value assignments on
+function invocations.
 
 .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm
 .. _`annotation pass`: translation.html#the-annotation-pass
 .. _`initialization time`: translation.html#initialization-time
-.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level 
+.. _`interpreter-level and application-level`: coding-guide.html#interpreter-level
 .. _`wrapped`: coding-guide.html#wrapping-rules
 .. _`object space`: objspace.html
 .. _`application level exceptions`: coding-guide.html#applevel-exceptions
 .. _`here`: coding-guide.html#modules
 
 
-Bytecode Interpreter Implementation Classes  
+Bytecode Interpreter Implementation Classes
 ================================================
 
-.. _`Frame class`: 
-.. _`Frame`: 
+.. _`Frame class`:
+.. _`Frame`:
 
 Frame classes
 -----------------
 
-The concept of Frames is pervasive in executing programs and 
+The concept of Frames is pervasive in executing programs and
 on virtual machines in particular. They are sometimes called
 *execution frame* because they hold crucial information
 regarding the execution of a Code_ object, which in turn is
 often directly related to a Python `Function`_.  Frame
-instances hold the following state: 
+instances hold the following state:
 
-- the local scope holding name-value bindings, usually implemented 
+- the local scope holding name-value bindings, usually implemented
   via a "fast scope" which is an array of wrapped objects
 
 - a blockstack containing (nested) information regarding the
-  control flow of a function (such as ``while`` and ``try`` constructs) 
+  control flow of a function (such as ``while`` and ``try`` constructs)
 
 - a value stack where bytecode interpretation pulls object
   from and puts results on.
 
 - a reference to the *globals* dictionary, containing
-  module-level name-value bindings 
+  module-level name-value bindings
 
-- debugging information from which a current line-number and 
-  file location can be constructed for tracebacks 
+- debugging information from which a current line-number and
+  file location can be constructed for tracebacks
 
 Moreover the Frame class itself has a number of methods which implement
 the actual bytecodes found in a code object.  The methods of the ``PyFrame``
 - nested scope support is added to the ``PyFrame`` class in
   `pypy/interpreter/nestedscope.py`_.
 
-.. _Code: 
+.. _Code:
 
-Code Class 
------------- 
+Code Class
+------------
 
-PyPy's code objects contain the same information found in CPython's code objects. 
-They differ from Function_ objects in that they are only immutable representations 
+PyPy's code objects contain the same information found in CPython's code objects.
+They differ from Function_ objects in that they are only immutable representations
 of source code and don't contain execution state or references to the execution
-environment found in `Frames`.  Frames and Functions have references 
+environment found in `Frames`.  Frames and Functions have references
 to a code object. Here is a list of Code attributes:
 
-* ``co_flags`` flags if this code object has nested scopes/generators 
+* ``co_flags`` flags if this code object has nested scopes/generators
 * ``co_stacksize`` the maximum depth the stack can reach while executing the code
-* ``co_code`` the actual bytecode string 
- 
-* ``co_argcount`` number of arguments this code object expects 
+* ``co_code`` the actual bytecode string
+
+* ``co_argcount`` number of arguments this code object expects
 * ``co_varnames`` a tuple of all argument names pass to this code object
-* ``co_nlocals`` number of local variables 
+* ``co_nlocals`` number of local variables
 * ``co_names`` a tuple of all names used in the code object
-* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object 
-* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes 
-* ``co_freevars`` a tuple of Cell names from "above" scopes 
- 
-* ``co_filename`` source file this code object was compiled from 
-* ``co_firstlineno`` the first linenumber of the code object in its source file 
-* ``co_name`` name of the code object (often the function name) 
-* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes 
+* ``co_consts`` a tuple of prebuilt constant objects ("literals") used in the code object
+* ``co_cellvars`` a tuple of Cells containing values for access from nested scopes
+* ``co_freevars`` a tuple of Cell names from "above" scopes
+
+* ``co_filename`` source file this code object was compiled from
+* ``co_firstlineno`` the first linenumber of the code object in its source file
+* ``co_name`` name of the code object (often the function name)
+* ``co_lnotab`` a helper table to compute the line-numbers corresponding to bytecodes
 
 In PyPy, code objects also have the responsibility of creating their Frame_ objects
 via the `'create_frame()`` method.  With proper parser and compiler support this would
 allow to create custom Frame objects extending the execution of functions
 in various ways.  The several Frame_ classes already utilize this flexibility
-in order to implement Generators and Nested Scopes. 
+in order to implement Generators and Nested Scopes.
 
-.. _Function: 
+.. _Function:
 
 Function and Method classes
 ----------------------------
 
-The PyPy ``Function`` class (in `pypy/interpreter/function.py`_) 
-represents a Python function.  A ``Function`` carries the following 
-main attributes: 
+The PyPy ``Function`` class (in `pypy/interpreter/function.py`_)
+represents a Python function.  A ``Function`` carries the following
+main attributes:
 
-* ``func_doc`` the docstring (or None) 
-* ``func_name`` the name of the function 
-* ``func_code`` the Code_ object representing the function source code 
+* ``func_doc`` the docstring (or None)
+* ``func_name`` the name of the function
+* ``func_code`` the Code_ object representing the function source code
 * ``func_defaults`` default values for the function (built at function definition time)
-* ``func_dict`` dictionary for additional (user-defined) function attributes 
-* ``func_globals`` reference to the globals dictionary 
-* ``func_closure`` a tuple of Cell references  
+* ``func_dict`` dictionary for additional (user-defined) function attributes
+* ``func_globals`` reference to the globals dictionary
+* ``func_closure`` a tuple of Cell references
 
 ``Functions`` classes also provide a ``__get__`` descriptor which creates a Method
 object holding a binding to an instance or a class.  Finally, ``Functions``
-and ``Methods`` both offer a ``call_args()`` method which executes 
-the function given an `Arguments`_ class instance. 
+and ``Methods`` both offer a ``call_args()`` method which executes
+the function given an `Arguments`_ class instance.
 
-.. _Arguments: 
-.. _`function argument parsing`: 
+.. _Arguments:
+.. _`function argument parsing`:
 
-Arguments Class 
--------------------- 
+Arguments Class
+--------------------
 
 The Argument class (in `pypy/interpreter/argument.py`_) is
-responsible for parsing arguments passed to functions.  
+responsible for parsing arguments passed to functions.
 Python has rather complex argument-passing concepts:
 
-- positional arguments 
+- positional arguments
 
-- keyword arguments specified by name 
+- keyword arguments specified by name
 
 - default values for positional arguments, defined at function
-  definition time 
+  definition time
 
 - "star args" allowing a function to accept remaining
-  positional arguments 
+  positional arguments
 
-- "star keyword args" allow a function to accept additional 
-  arbitrary name-value bindings 
+- "star keyword args" allow a function to accept additional
+  arbitrary name-value bindings
 
-Moreover, a Function_ object can get bound to a class or instance 
+Moreover, a Function_ object can get bound to a class or instance
 in which case the first argument to the underlying function becomes
-the bound object.  The ``Arguments`` provides means to allow all 
-this argument parsing and also cares for error reporting. 
+the bound object.  The ``Arguments`` provides means to allow all
+this argument parsing and also cares for error reporting.
 
 
-.. _`Module`: 
+.. _`Module`:
 
-Module Class 
-------------------- 
+Module Class
+-------------------
 
-A ``Module`` instance represents execution state usually constructed 
+A ``Module`` instance represents execution state usually constructed
 from executing the module's source file.  In addition to such a module's
-global ``__dict__`` dictionary it has the following application level 
-attributes: 
+global ``__dict__`` dictionary it has the following application level
+attributes:
 
 * ``__doc__`` the docstring of the module
-* ``__file__`` the source filename from which this module was instantiated 
-* ``__path__`` state used for relative imports 
+* ``__file__`` the source filename from which this module was instantiated
+* ``__path__`` state used for relative imports
 
 Apart from the basic Module used for importing
 application-level files there is a more refined
 level and at interpreter level.  See the ``__builtin__``
 module's `pypy/module/__builtin__/__init__.py`_ file for an
 example and the higher level `chapter on Modules in the coding
-guide`_. 
+guide`_.
 
 .. _`__builtin__ module`: https://bitbucket.org/pypy/pypy/src/tip/pypy/module/__builtin__/
-.. _`chapter on Modules in the coding guide`: coding-guide.html#modules 
+.. _`chapter on Modules in the coding guide`: coding-guide.html#modules
 
-.. _`Gateway classes`: 
+.. _`Gateway classes`:
 
-Gateway classes 
----------------------- 
+Gateway classes
+----------------------
 
 A unique PyPy property is the ability to easily cross the barrier
 between interpreted and machine-level code (often referred to as
-the difference between `interpreter-level and application-level`_). 
-Be aware that the according code (in `pypy/interpreter/gateway.py`_) 
+the difference between `interpreter-level and application-level`_).
+Be aware that the according code (in `pypy/interpreter/gateway.py`_)
 for crossing the barrier in both directions is somewhat
 involved, mostly due to the fact that the type-inferring
 annotator needs to keep track of the types of objects flowing
-across those barriers. 
+across those barriers.
 
 .. _typedefs:
 
 Making interpreter-level functions available at application-level
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
-In order to make an interpreter-level function available at 
-application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``. 
-Such a function usually takes a ``space`` argument and any number 
+In order to make an interpreter-level function available at
+application level, one invokes ``pypy.interpreter.gateway.interp2app(func)``.
+Such a function usually takes a ``space`` argument and any number
 of positional arguments. Additionally, such functions can define
 an ``unwrap_spec`` telling the ``interp2app`` logic how
 application-level provided arguments should be unwrapped
-before the actual interpreter-level function is invoked. 
-For example, `interpreter descriptors`_ such as the ``Module.__new__`` 
-method for allocating and constructing a Module instance are 
-defined with such code:: 
+before the actual interpreter-level function is invoked.
+For example, `interpreter descriptors`_ such as the ``Module.__new__``
+method for allocating and constructing a Module instance are
+defined with such code::
 
     Module.typedef = TypeDef("module",
         __new__ = interp2app(Module.descr_module__new__.im_func,
                              unwrap_spec=[ObjSpace, W_Root, Arguments]),
         __init__ = interp2app(Module.descr_module__init__),
                         # module dictionaries are readonly attributes
-        __dict__ = GetSetProperty(descr_get_dict, cls=Module), 
-        __doc__ = 'module(name[, doc])\n\nCreate a module object...' 
+        __dict__ = GetSetProperty(descr_get_dict, cls=Module),
+        __doc__ = 'module(name[, doc])\n\nCreate a module object...'
         )
 
-The actual ``Module.descr_module__new__`` interpreter-level method 
-referenced from the ``__new__`` keyword argument above is defined 
-like this:: 
+The actual ``Module.descr_module__new__`` interpreter-level method
+referenced from the ``__new__`` keyword argument above is defined
+like this::
 
     def descr_module__new__(space, w_subtype, __args__):
         module = space.allocate_instance(Module, w_subtype)
         Module.__init__(module, space, None)
         return space.wrap(module)
 
-Summarizing, the ``interp2app`` mechanism takes care to route 
-an application level access or call to an internal interpreter-level 
+Summarizing, the ``interp2app`` mechanism takes care to route
+an application level access or call to an internal interpreter-level
 object appropriately to the descriptor, providing enough precision
-and hints to keep the type-inferring annotator happy. 
+and hints to keep the type-inferring annotator happy.
 
 
-Calling into application level code from interpreter-level 
+Calling into application level code from interpreter-level
 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
-Application level code is `often preferable`_. Therefore, 
-we often like to invoke application level code from interpreter-level. 
+Application level code is `often preferable`_. Therefore,
+we often like to invoke application level code from interpreter-level.
 This is done via the Gateway's ``app2interp`` mechanism
-which we usually invoke at definition time in a module. 
-It generates a hook which looks like an interpreter-level 
-function accepting a space and an arbitrary number of arguments. 
-When calling a function at interpreter-level the caller side 
+which we usually invoke at definition time in a module.
+It generates a hook which looks like an interpreter-level
+function accepting a space and an arbitrary number of arguments.
+When calling a function at interpreter-level the caller side
 does usually not need to be aware if its invoked function
 is run through the PyPy interpreter or if it will directly
-execute on the machine (after translation). 
+execute on the machine (after translation).
 
-Here is an example showing how we implement the Metaclass 
+Here is an example showing how we implement the Metaclass
 finding algorithm of the Python language in PyPy::
 
     app = gateway.applevel(r'''
 
     find_metaclass  = app.interphook('find_metaclass')
 
-The ``find_metaclass`` interpreter-level hook is invoked 
+The ``find_metaclass`` interpreter-level hook is invoked
 with five arguments from the ``BUILD_CLASS`` opcode implementation
-in `pypy/interpreter/pyopcode.py`_:: 
+in `pypy/interpreter/pyopcode.py`_::
 
     def BUILD_CLASS(f):
         w_methodsdict = f.valuestack.pop()
                                            w_bases, w_methodsdict)
         f.valuestack.push(w_newclass)
 
-Note that at a later point we can rewrite the ``find_metaclass`` 
-implementation at interpreter-level and we would not have 
-to modify the calling side at all. 
+Note that at a later point we can rewrite the ``find_metaclass``
+implementation at interpreter-level and we would not have
+to modify the calling side at all.
 
 .. _`often preferable`: coding-guide.html#app-preferable
-.. _`interpreter descriptors`: 
+.. _`interpreter descriptors`:
 
-Introspection and Descriptors 
+Introspection and Descriptors
 ------------------------------
 
-Python traditionally has a very far-reaching introspection model 
+Python traditionally has a very far-reaching introspection model
 for bytecode interpreter related objects. In PyPy and in CPython read
-and write accesses to such objects are routed to descriptors. 
+and write accesses to such objects are routed to descriptors.
 Of course, in CPython those are implemented in ``C`` while in
-PyPy they are implemented in interpreter-level Python code. 
+PyPy they are implemented in interpreter-level Python code.
 
 All instances of a Function_, Code_, Frame_ or Module_ classes
-are also ``Wrappable`` instances which means they can be represented 
+are also ``W_Root`` instances which means they can be represented
 at application level.  These days, a PyPy object space needs to
 work with a basic descriptor lookup when it encounters
 accesses to an interpreter-level object:  an object space asks
-a wrapped object for its type via a ``getclass`` method and then 
-calls the type's ``lookup(name)`` function in order to receive a descriptor 
+a wrapped object for its type via a ``getclass`` method and then
+calls the type's ``lookup(name)`` function in order to receive a descriptor
 function.  Most of PyPy's internal object descriptors are defined at the
-end of `pypy/interpreter/typedef.py`_.  You can use these definitions 
-as a reference for the exact attributes of interpreter classes visible 
-at application level. 
+end of `pypy/interpreter/typedef.py`_.  You can use these definitions
+as a reference for the exact attributes of interpreter classes visible
+at application level.
 
 .. include:: _ref.txt

File pypy/doc/objspace.rst

 ``wrap(x):``
   Returns a wrapped object that is a reference to the interpreter-level object
   x. This can be used either on simple immutable objects (integers,
-  strings...) to create a new wrapped object, or on instances of ``Wrappable``
+  strings...) to create a new wrapped object, or on instances of ``W_Root``
   to obtain an application-level-visible reference to them.  For example,
-  most classes of the bytecode interpreter subclass ``Wrappable`` and can
+  most classes of the bytecode interpreter subclass ``W_Root`` and can
   be directly exposed to app-level in this way - functions, frames, code
   objects, etc.
 

File pypy/doc/whatsnew-head.rst

 .. branch: rpython-bytearray
 Rudimentary support for bytearray in RPython
 
+.. branch: refactor-call_release_gil
+Fix a bug which casused cffi to return the wrong result when calling a C
+function which calls a Python callback which forces the frames
+
 .. branches we don't care about
 .. branch: autoreds
 .. branch: reflex-support
 Documentation fixes after going through the docs at PyCon 2013 sprint.
 
 .. branch: extregistry-refactor
+
+.. branch: remove-list-smm

File pypy/interpreter/astcompiler/ast.py

 # Generated by tools/asdl_py.py
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter import typedef
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.error import OperationError, operationerrfmt
     return w_obj
 
 
-class AST(Wrappable):
+class AST(W_Root):
 
     w_dict = None
 
     pass
 
 
-class _FieldsWrapper(Wrappable):
+class _FieldsWrapper(W_Root):
     "Hack around the fact we can't store tuples on a TypeDef."
 
     def __init__(self, fields):

File pypy/interpreter/astcompiler/test/test_astbuilder.py

         assert space.eq_w(get_num("-0"), space.wrap(0))
         assert space.eq_w(get_num("-0xAAAAAAL"), space.wrap(-0xAAAAAAL))
         n = get_num(str(-sys.maxint - 1))
-        assert space.is_true(space.isinstance(n, space.w_int))
+        assert space.isinstance_w(n, space.w_int)
         for num in ("0o53", "0O53", "0o0000053", "0O00053"):
             assert space.eq_w(get_num(num), space.wrap(053))
         for num in ("0b00101", "0B00101", "0b101", "0B101"):

File pypy/interpreter/astcompiler/tools/asdl_py.py

 
 
 HEAD = """# Generated by tools/asdl_py.py
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter import typedef
 from pypy.interpreter.gateway import interp2app
 from pypy.interpreter.error import OperationError, operationerrfmt
     return w_obj
 
 
-class AST(Wrappable):
+class AST(W_Root):
 
     w_dict = None
 
     pass
 
 
-class _FieldsWrapper(Wrappable):
+class _FieldsWrapper(W_Root):
     "Hack around the fact we can\'t store tuples on a TypeDef."
 
     def __init__(self, fields):

File pypy/interpreter/baseobjspace.py

 from pypy.interpreter.miscutils import ThreadLocals
 
 
-__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root']
+__all__ = ['ObjSpace', 'OperationError', 'W_Root']
 
 UINT_MAX_32_BITS = r_uint(4294967295)
 
         raise OperationError(space.w_TypeError,
                              typed_unwrap_error_msg(space, "integer", self))
 
+    def float_w(self, space):
+        raise OperationError(space.w_TypeError,
+                             typed_unwrap_error_msg(space, "float", self))
+
     def uint_w(self, space):
         raise OperationError(space.w_TypeError,
                              typed_unwrap_error_msg(space, "integer", self))
         raise OperationError(space.w_TypeError,
                              typed_unwrap_error_msg(space, "integer", self))
 
+    def int(self, space):
+        w_impl = space.lookup(self, '__int__')
+        if w_impl is None:
+            typename = space.type(self).getname(space)
+            raise operationerrfmt(space.w_TypeError,
+                  "unsupported operand type for int(): '%s'",
+                                  typename)
+        w_result = space.get_and_call_function(w_impl, self)
 
-class Wrappable(W_Root):
-    """A subclass of Wrappable is an internal, interpreter-level class
-    that can nevertheless be exposed at application-level by space.wrap()."""
-    __slots__ = ()
-    _settled_ = True
+        if (space.isinstance_w(w_result, space.w_int) or
+            space.isinstance_w(w_result, space.w_long)):
+            return w_result
+        typename = space.type(w_result).getname(space)
+        msg = "__int__ returned non-int (type '%s')"
+        raise operationerrfmt(space.w_TypeError, msg, typename)
 
     def __spacebind__(self, space):
         return self
 
+
 class W_InterpIterable(W_Root):
     def __init__(self, space, w_iterable):
         self.w_iter = space.iter(w_iterable)
     def __init__(self, space):
         Cache.__init__(self)
         self.space = space
+
     def _build(self, key):
-        val = self.space.enter_cache_building_mode()
-        try:
-            return self.build(key)
-        finally:
-            self.space.leave_cache_building_mode(val)
+        return self.build(key)
+
     def _ready(self, result):
-        val = self.space.enter_cache_building_mode()
-        try:
-            return self.ready(result)
-        finally:
-            self.space.leave_cache_building_mode(val)
+        return self.ready(result)
+
     def ready(self, result):
         pass
 
                 if e.match(self, self.w_KeyError):
                     continue
                 raise
-            mod = self.interpclass_w(w_mod)
-            if isinstance(mod, Module) and not mod.startup_called:
-                mod.init(self)
+            if isinstance(w_mod, Module) and not w_mod.startup_called:
+                w_mod.init(self)
 
     def finish(self):
         self.wait_for_thread_shutdown()
             self.call_function(w_exitfunc)
         from pypy.interpreter.module import Module
         for w_mod in self.builtin_modules.values():
-            mod = self.interpclass_w(w_mod)
-            if isinstance(mod, Module) and mod.startup_called:
-                mod.shutdown(self)
+            if isinstance(w_mod, Module) and w_mod.startup_called:
+                w_mod.shutdown(self)
 
     def wait_for_thread_shutdown(self):
         """Wait until threading._shutdown() completes, provided the threading
 
             # And initialize it
             from pypy.interpreter.module import Module
-            mod = self.interpclass_w(w_mod)
-            if isinstance(mod, Module):
-                mod.init(self)
+            if isinstance(w_mod, Module):
+                w_mod.init(self)
             return w_mod
 
     def get_builtinmodule_to_install(self):
         """NOT_RPYTHON: Abstract method that should put some minimal
         content into the w_builtins."""
 
-    def enter_cache_building_mode(self):
-        "hook for the flow object space"
-    def leave_cache_building_mode(self, val):
-        "hook for the flow object space"
-
     @jit.loop_invariant
     def getexecutioncontext(self):
         "Return what we consider to be the active execution context."
         w_s = self.interned_strings[s] = self.wrap(s)
         return w_s
 
-    def interpclass_w(self, w_obj):
-        """
-         If w_obj is a wrapped internal interpreter class instance unwrap to it,
-         otherwise return None.  (Can be overridden in specific spaces; you
-     should generally use the helper space.interp_w() instead.)
-        """
-        if isinstance(w_obj, Wrappable):
-            return w_obj
-        return None
-
     def descr_self_interp_w(self, RequiredClass, w_obj):
-        obj = self.interpclass_w(w_obj)
-        if not isinstance(obj, RequiredClass):
+        if not isinstance(w_obj, RequiredClass):
             raise DescrMismatch()
-        return obj
+        return w_obj
     descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)'
 
     def interp_w(self, RequiredClass, w_obj, can_be_None=False):
         """
         Unwrap w_obj, checking that it is an instance of the required internal
-        interpreter class (a subclass of Wrappable).
+        interpreter class.
         """
         assert RequiredClass is not None
         if can_be_None and self.is_none(w_obj):
             return None
-        obj = self.interpclass_w(w_obj)
-        if not isinstance(obj, RequiredClass):   # or obj is None
+        if not isinstance(w_obj, RequiredClass):   # or obj is None
             msg = "'%s' object expected, got '%s' instead"
             raise operationerrfmt(self.w_TypeError, msg,
                 wrappable_class_name(RequiredClass),
                 w_obj.getclass(self).getname(self))
-        return obj
+        return w_obj
     interp_w._annspecialcase_ = 'specialize:arg(1)'
 
     def unpackiterable(self, w_iterable, expected_length=-1):
         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)):
+            if self.isinstance_w(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
     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)
+        return isinstance(w_obj, W_InstanceObject)
 
     def callable(self, w_obj):
         if 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)
 
-    def isinstance_w(self, w_obj, w_type):
-        return self.is_true(self.isinstance(w_obj, w_type))
-
     # The code below only works
     # for the simple case (new-style instance).
     # These methods are patched with the full logic by the __builtin__
 
     def abstract_isinstance_w(self, w_obj, w_cls):
         # Equivalent to 'isinstance(obj, cls)'.
-        return self.is_true(self.isinstance(w_obj, w_cls))
+        return self.isinstance_w(w_obj, w_cls)
 
     def abstract_isclass_w(self, w_obj):
         # Equivalent to 'isinstance(obj, type)'.
-        return self.is_true(self.isinstance(w_obj, self.w_type))
+        return self.isinstance_w(w_obj, self.w_type)
 
     def abstract_getclass(self, w_obj):
         # Equivalent to 'obj.__class__'.
             expression = compiler.compile(expression, '?', 'eval', 0,
                                          hidden_applevel=hidden_applevel)
         else:
-            raise TypeError, 'space.eval(): expected a string, code or PyCode object'
+            raise TypeError('space.eval(): expected a string, code or PyCode object')
         return expression.exec_code(self, w_globals, w_locals)
 
     def exec_(self, statement, w_globals, w_locals, hidden_applevel=False,
             statement = compiler.compile(statement, filename, 'exec', 0,
                                          hidden_applevel=hidden_applevel)
         if not isinstance(statement, PyCode):
-            raise TypeError, 'space.exec_(): expected a string, code or PyCode object'
+            raise TypeError('space.exec_(): expected a string, code or PyCode object')
         w_key = self.wrap('__builtins__')
         if not self.is_true(self.contains(w_globals, w_key)):
             self.setitem(w_globals, w_key, self.wrap(self.builtin))
              -> (index, 0, 0) or
                 (start, stop, step)
         """
-        if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)):
+        if self.isinstance_w(w_index_or_slice, self.w_slice):
             from pypy.objspace.std.sliceobject import W_SliceObject
             assert isinstance(w_index_or_slice, W_SliceObject)
             start, stop, step = w_index_or_slice.indices3(self, seqlength)
              -> (index, 0, 0, 1) or
                 (start, stop, step, slice_length)
         """
-        if self.is_true(self.isinstance(w_index_or_slice, self.w_slice)):
+        if self.isinstance_w(w_index_or_slice, self.w_slice):
             from pypy.objspace.std.sliceobject import W_SliceObject
             assert isinstance(w_index_or_slice, W_SliceObject)
             start, stop, step, length = w_index_or_slice.indices4(self,
     def int_w(self, w_obj):
         return w_obj.int_w(self)
 
+    def int(self, w_obj):
+        return w_obj.int(self)
+
     def uint_w(self, w_obj):
         return w_obj.uint_w(self)
 
     def bigint_w(self, w_obj):
         return w_obj.bigint_w(self)
 
+    def float_w(self, w_obj):
+        return w_obj.float_w(self)
+
     def realstr_w(self, w_obj):
         # Like str_w, but only works if w_obj is really of type 'str'.
-        if not self.is_true(self.isinstance(w_obj, self.w_str)):
+        if not self.isinstance_w(w_obj, self.w_str):
             raise OperationError(self.w_TypeError,
                                  self.wrap('argument must be a string'))
         return self.str_w(w_obj)
     def realunicode_w(self, w_obj):
         # Like unicode_w, but only works if w_obj is really of type
         # 'unicode'.
-        if not self.is_true(self.isinstance(w_obj, self.w_unicode)):
+        if not self.isinstance_w(w_obj, self.w_unicode):
             raise OperationError(self.w_TypeError,
                                  self.wrap('argument must be a unicode'))
         return self.unicode_w(w_obj)
 
     # This is all interface for gateway.py.
     def gateway_int_w(self, w_obj):
-        if self.is_true(self.isinstance(w_obj, self.w_float)):
+        if self.isinstance_w(w_obj, self.w_float):
             raise OperationError(self.w_TypeError,
                             self.wrap("integer argument expected, got float"))
         return self.int_w(self.int(w_obj))
         return self.float_w(self.float(w_obj))
 
     def gateway_r_longlong_w(self, w_obj):
-        if self.is_true(self.isinstance(w_obj, self.w_float)):
+        if self.isinstance_w(w_obj, self.w_float):
             raise OperationError(self.w_TypeError,
                             self.wrap("integer argument expected, got float"))
         return self.r_longlong_w(self.int(w_obj))
 
     def gateway_r_uint_w(self, w_obj):
-        if self.is_true(self.isinstance(w_obj, self.w_float)):
+        if self.isinstance_w(w_obj, self.w_float):
             raise OperationError(self.w_TypeError,
                             self.wrap("integer argument expected, got float"))
         return self.uint_w(self.int(w_obj))
 
     def gateway_r_ulonglong_w(self, w_obj):
-        if self.is_true(self.isinstance(w_obj, self.w_float)):
+        if self.isinstance_w(w_obj, self.w_float):
             raise OperationError(self.w_TypeError,
                             self.wrap("integer argument expected, got float"))
         return self.r_ulonglong_w(self.int(w_obj))
         space.exec_(str(source), w_glob, w_glob)
         return space.getitem(w_glob, space.wrap('anonymous'))
 
+
 class DummyLock(object):
     def acquire(self, flag):
         return True
+
     def release(self):
         pass
+
     def _freeze_(self):
         return True
+
     def __enter__(self):
         pass
+
     def __exit__(self, *args):
         pass
 
 dummy_lock = DummyLock()
 
-## Table describing the regular part of the interface of object spaces,
-## namely all methods which only take w_ arguments and return a w_ result
-## (if any).  Note: keep in sync with rpython.flowspace.operation.Table.
+# Table describing the regular part of the interface of object spaces,
+# namely all methods which only take w_ arguments and return a w_ result
+# (if any).
 
 ObjSpace.MethodTable = [
 # method name # symbol # number of arguments # special method name(s)
     ('pos',             'pos',       1, ['__pos__']),
     ('neg',             'neg',       1, ['__neg__']),
     ('nonzero',         'truth',     1, ['__nonzero__']),
-    ('abs' ,            'abs',       1, ['__abs__']),
+    ('abs',             'abs',       1, ['__abs__']),
     ('hex',             'hex',       1, ['__hex__']),
     ('oct',             'oct',       1, ['__oct__']),
     ('ord',             'ord',       1, []),
     ('delete',          'delete',    2, ['__delete__']),
     ('userdel',         'del',       1, ['__del__']),
     ('buffer',          'buffer',    1, ['__buffer__']),   # see buffer.py
-    ]
+]
 
 ObjSpace.BuiltinModuleTable = [
     '__builtin__',
     'sys',
-    ]
+]
 
 ObjSpace.ConstantTable = [
     'None',
     'True',
     'Ellipsis',
     'NotImplemented',
-    ]
+]
 
 ObjSpace.ExceptionTable = [
     'ArithmeticError',
     'ZeroDivisionError',
     'RuntimeWarning',
     'PendingDeprecationWarning',
-    ]
+]
 
 if sys.platform.startswith("win"):
     ObjSpace.ExceptionTable += ['WindowsError']
 #                       float_w(w_floatval) -> floatval
 #             uint_w(w_ival or w_long_ival) -> r_uint_val (unsigned int value)
 #             bigint_w(w_ival or w_long_ival) -> rbigint
-#interpclass_w(w_interpclass_inst or w_obj) -> interpclass_inst|w_obj
 #                               unwrap(w_x) -> x
 #                              is_true(w_x) -> True or False
 #                  newtuple([w_1, w_2,...]) -> w_tuple
     'uint_w',
     'bigint_w',
     'unicode_w',
-    'interpclass_w',
     'unwrap',
     'is_true',
     'is_w',
     'newslice',
     'call_args',
     'marshal_w',
-    ]
+]

File pypy/interpreter/buffer.py

 # free the typecheck that __buffer__() really returned a wrapped Buffer.
 
 import operator
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
 from rpython.rlib.rstring import StringBuilder
 
 
-class Buffer(Wrappable):
+class Buffer(W_Root):
     """Abstract base class for memory views."""
 
     __slots__ = ()     # no extra slot here
 
     def _make_descr__cmp(name):
         def descr__cmp(self, space, w_other):
-            other = space.interpclass_w(w_other)
-            if not isinstance(other, Buffer):
+            if not isinstance(w_other, Buffer):
                 return space.w_NotImplemented
             # xxx not the most efficient implementation
             str1 = self.as_str()
-            str2 = other.as_str()
+            str2 = w_other.as_str()
             return space.wrap(getattr(operator, name)(str1, str2))
         descr__cmp.func_name = name
         return descr__cmp
         for i in range(len(string)):
             self.setitem(start + i, string[i])
 
+
 @unwrap_spec(offset=int, size=int)
 def descr_buffer__new__(space, w_subtype, w_object, offset=0, size=-1):
     # w_subtype can only be exactly 'buffer' for now
     __mul__ = interp2app(Buffer.descr_mul),
     __rmul__ = interp2app(Buffer.descr_mul),
     __repr__ = interp2app(Buffer.descr_repr),
-    )
+)
 Buffer.typedef.acceptable_as_base_class = False
 
 # ____________________________________________________________

File pypy/interpreter/error.py

         #
         w_type = self.w_type
         w_value = self.get_w_value(space)
-        while space.is_true(space.isinstance(w_type, space.w_tuple)):
+        while space.isinstance_w(w_type, space.w_tuple):
             w_type = space.getitem(w_type, space.wrap(0))
 
         if space.exception_is_valid_obj_as_class_w(w_type):
                     # raise Type, Instance: let etype be the exact type of value
                     w_type = w_valuetype
                 else:
-                    if space.is_true(space.isinstance(w_value, space.w_tuple)):
+                    if space.isinstance_w(w_value, space.w_tuple):
                         # raise Type, tuple: assume the tuple contains the
                         #                    constructor args
                         w_value = space.call(w_type, w_value)

File pypy/interpreter/eval.py

 Code and Frame.
 """
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root
 
 
-class Code(Wrappable):
+class Code(W_Root):
     """A code is a compiled version of some source code.
     Abstract base class."""
     _immutable_ = True
     def funcrun_obj(self, func, w_obj, args):
         return self.funcrun(func, args.prepend(w_obj))
 
-class Frame(Wrappable):
+
+class Frame(W_Root):
     """A frame is an environment supporting the execution of a code object.
     Abstract base class."""
 
     def __init__(self, space, w_globals=None):
-        self.space      = space
-        self.w_globals  = w_globals  # wrapped dict of globals
-        self.w_locals   = None       # wrapped dict of locals
+        self.space = space
+        self.w_globals = w_globals  # wrapped dict of globals
+        self.w_locals = None       # wrapped dict of locals
 
     def run(self):
         "Abstract method to override. Runs the frame"
-        raise TypeError, "abstract"
-    
+        raise TypeError("abstract")
+
     def getdictscope(self):
         "Get the locals as a dictionary."
         self.fast2locals()
 
     def getfastscope(self):
         "Abstract. Get the fast locals as a list."
-        raise TypeError, "abstract"
+        raise TypeError("abstract")
 
     def setfastscope(self, scope_w):
         """Abstract. Initialize the fast locals from a list of values,
         where the order is according to self.getcode().signature()."""
-        raise TypeError, "abstract"
+        raise TypeError("abstract")
 
     def getfastscopelength(self):
         "Abstract. Get the expected number of locals."
-        raise TypeError, "abstract"
+        raise TypeError("abstract")
 
     def fast2locals(self):
         # Copy values from the fastlocals to self.w_locals

File pypy/interpreter/function.py

 
 from rpython.rlib.unroll import unrolling_iterable
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.eval import Code
 from pypy.interpreter.argument import Arguments
 from rpython.rlib import jit
 
+
 funccallunrolling = unrolling_iterable(range(4))
 
+
 @jit.elidable_promote()
 def _get_immutable_code(func):
     assert not func.can_change_code
     return func.code
 
-
-class Function(Wrappable):
+class Function(W_Root):
     """A function is a code object captured with some environment:
     an object space, a dictionary of globals, default arguments,
     and an arbitrary 'closure' passed to the code object."""
         self.w_doc = None   # lazily read from code.getdocstring()
         self.code = code       # Code instance
         self.w_func_globals = w_globals  # the globals dictionary
-        self.closure   = closure    # normally, list of Cell instances or None
+        self.closure = closure    # normally, list of Cell instances or None
         self.defs_w = defs_w
         self.w_func_dict = None # filled out below if needed
         self.w_module = None
 
     def call_args(self, args):
         # delegate activation to code
-        return self.getcode().funcrun(self, args)
+        w_res = self.getcode().funcrun(self, args)
+        assert isinstance(w_res, W_Root)
+        return w_res
 
     def call_obj_args(self, w_obj, args):
         # delegate activation to code
-        return self.getcode().funcrun_obj(self, w_obj, args)
+        w_res = self.getcode().funcrun_obj(self, w_obj, args)
+        assert isinstance(w_res, W_Root)
+        return w_res
 
     def getcode(self):
         if jit.we_are_jitted():
     def descr_function__new__(space, w_subtype, w_code, w_globals,
                               w_name=None, w_argdefs=None, w_closure=None):
         code = space.interp_w(Code, w_code)
-        if not space.is_true(space.isinstance(w_globals, space.w_dict)):
+        if not space.isinstance_w(w_globals, space.w_dict):
             raise OperationError(space.w_TypeError, space.wrap("expected dict"))
         if not space.is_none(w_name):
             name = space.str_w(w_name)
     def descr_function_repr(self):
         return self.getrepr(self.space, 'function %s' % (self.name,))
 
-
     # delicate
     _all = {'': None}
 
     def descr_function__reduce__(self, space):
         from pypy.interpreter.gateway import BuiltinCode
         from pypy.interpreter.mixedmodule import MixedModule
-        w_mod    = space.getbuiltinmodule('_pickle_support')
-        mod      = space.interp_w(MixedModule, w_mod)
+        w_mod = space.getbuiltinmodule('_pickle_support')
+        mod = space.interp_w(MixedModule, w_mod)
         code = self.code
         if isinstance(code, BuiltinCode):
             new_inst = mod.get('builtin_function')
                                    space.newtuple([space.wrap(code.identifier)])])
 
         new_inst = mod.get('func_new')
-        w        = space.wrap
+        w = space.wrap
         if self.closure is None:
             w_closure = space.w_None
         else:
         if space.is_w(w_defaults, space.w_None):
             self.defs_w = []
             return
-        if not space.is_true(space.isinstance(w_defaults, space.w_tuple)):
-            raise OperationError( space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None") )
+        if not space.isinstance_w(w_defaults, space.w_tuple):
+            raise OperationError(space.w_TypeError, space.wrap("func_defaults must be set to a tuple object or None"))
         self.defs_w = space.fixedview(w_defaults)
 
     def fdel_func_defaults(self, space):
                                                 "to a string object"))
             raise
 
-
     def fdel_func_doc(self, space):
         self.w_doc = space.w_None
 
 
     def fget_func_closure(self, space):
         if self.closure is not None:
-            w_res = space.newtuple( [ space.wrap(i) for i in self.closure ] )
+            w_res = space.newtuple([space.wrap(i) for i in self.closure])
         else:
             w_res = space.w_None
         return w_res
         return space.wrap(Method(space, w_function, None, w_cls))
 
 
-class Method(Wrappable):
+class Method(W_Root):
     """A method is a function bound to a specific instance or class."""
     _immutable_fields_ = ['w_function', 'w_instance', 'w_class']
 
 
     def descr_method_eq(self, w_other):
         space = self.space
-        other = space.interpclass_w(w_other)
-        if not isinstance(other, Method):
+        if not isinstance(w_other, Method):
             return space.w_NotImplemented
         if self.w_instance is None:
-            if other.w_instance is not None:
+            if w_other.w_instance is not None:
                 return space.w_False
         else:
-            if other.w_instance is None:
+            if w_other.w_instance is None:
                 return space.w_False
-            if not space.eq_w(self.w_instance, other.w_instance):
+            if not space.eq_w(self.w_instance, w_other.w_instance):
                 return space.w_False
-        return space.eq(self.w_function, other.w_function)
+        return space.eq(self.w_function, w_other.w_function)
 
     def descr_method_hash(self):
         space = self.space
         mod      = space.interp_w(MixedModule, w_mod)
         new_inst = mod.get('method_new')
         w_instance = self.w_instance or space.w_None
-        function = space.interpclass_w(self.w_function)
-        if isinstance(function, Function) and isinstance(function.code, BuiltinCode):
+        w_function = self.w_function
+        if (isinstance(w_function, Function) and
+                isinstance(w_function.code, BuiltinCode)):
             new_inst = mod.get('builtin_method_new')
             if space.is_w(w_instance, space.w_None):
-                tup = [self.w_class, space.wrap(function.name)]
+                tup = [self.w_class, space.wrap(w_function.name)]
             else:
-                tup = [w_instance, space.wrap(function.name)]
-        elif space.is_w( self.w_class, space.w_None ):
+                tup = [w_instance, space.wrap(w_function.name)]
+        elif space.is_w(self.w_class, space.w_None):
             tup = [self.w_function, w_instance]
         else:
             tup = [self.w_function, w_instance, self.w_class]
         return space.newtuple([new_inst, space.newtuple(tup)])
 
-class StaticMethod(Wrappable):
+
+class StaticMethod(W_Root):
     """The staticmethod objects."""
     _immutable_fields_ = ['w_function']
 
         instance.__init__(w_function)
         return space.wrap(instance)
 
-class ClassMethod(Wrappable):
+
+class ClassMethod(W_Root):
     """The classmethod objects."""
     _immutable_fields_ = ['w_function']
 

File pypy/interpreter/gateway.py

 * BuiltinCode (call interp-level code from app-level)
 * app2interp  (embed an app-level function into an interp-level callable)
 * interp2app  (publish an interp-level object to be visible from app-level)
+* interpindirect2app (publish an interp-level object to be visible from
+                      app-level as an indirect call to implementation)
 
 """
 
 import sys
 import os
 import types
+import inspect
 
 import py
 
 from pypy.interpreter.eval import Code
 from pypy.interpreter.argument import Arguments
 from pypy.interpreter.signature import Signature
-from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, Wrappable,
-    SpaceCache, DescrMismatch)
+from pypy.interpreter.baseobjspace import (W_Root, ObjSpace, SpaceCache,
+    DescrMismatch)
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.function import ClassMethod, FunctionWithFixedCode
 from rpython.rlib import rstackovf
 class UnwrapSpecRecipe(object):
     "NOT_RPYTHON"
 
-    bases_order = [Wrappable, W_Root, ObjSpace, Arguments, object]
+    bases_order = [W_Root, ObjSpace, Arguments, object]
 
     def dispatch(self, el, *args):
         if isinstance(el, str):
         self.orig_arg = iter(original_sig.argnames).next
 
     def visit_self(self, cls, app_sig):
-        self.visit__Wrappable(cls, app_sig)
+        self.visit__W_Root(cls, app_sig)
 
     def checked_space_method(self, typname, app_sig):
         argname = self.orig_arg()
         assert not argname.startswith('w_'), (
-            "unwrapped %s argument %s of built-in function %r should "
-            "not start with 'w_'" % (typname, argname, self.func))
+            "unwrapped %s argument %s of built-in function %r in %r should "
+            "not start with 'w_'" % (typname, argname, self.func.func_name, self.func.func_globals['__name__']))
         app_sig.append(argname)
 
     def visit_index(self, index, app_sig):
     def visit_truncatedint_w(self, el, app_sig):
         self.checked_space_method(el, app_sig)
 
-    def visit__Wrappable(self, el, app_sig):
-        name = el.__name__
-        argname = self.orig_arg()
-        assert not argname.startswith('w_'), (
-            "unwrapped %s argument %s of built-in function %r should "
-            "not start with 'w_'" % (name, argname, self.func))
-        app_sig.append(argname)
-
     def visit__ObjSpace(self, el, app_sig):
         self.orig_arg()
 
     def visit__W_Root(self, el, app_sig):
-        assert el is W_Root, "%s is not W_Root (forgotten to put .im_func in interp2app argument?)" % (el,)
         argname = self.orig_arg()
+        if argname == 'self':
+            assert el is not W_Root
+            app_sig.append(argname)
+            return
         assert argname.startswith('w_'), (
-            "argument %s of built-in function %r should "
-            "start with 'w_'" % (argname, self.func))