Antonio Cuni avatar Antonio Cuni committed b645748 Merge

hg merge default

Comments (0)

Files changed (66)

lib_pypy/_pypy_testcapi.py

     # set link options
     output_filename = modulename + _get_c_extension_suffix()
     if sys.platform == 'win32':
-        # XXX libpypy-c.lib is currently not installed automatically
-        library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
+        # XXX pyconfig.h uses a pragma to link to the import library,
+        #     which is currently python27.lib
+        library = os.path.join(thisdir, '..', 'include', 'python27')
         if not os.path.exists(library + '.lib'):
-            #For a nightly build
-            library = os.path.join(thisdir, '..', 'include', 'python27')
-        if not os.path.exists(library + '.lib'):
-            # For a local translation
-            library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
+            # For a local translation or nightly build
+            library = os.path.join(thisdir, '..', 'pypy', 'goal', 'python27')
+        assert os.path.exists(library + '.lib'),'Could not find import library "%s"' % library
         libraries = [library, 'oleaut32']
         extra_ldargs = ['/MANIFEST',  # needed for VC10
                         '/EXPORT:init' + modulename]

lib_pypy/cffi/__init__.py

 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "0.8"
-__version_info__ = (0, 8)
+__version__ = "0.8.1"
+__version_info__ = (0, 8, 1)
 # The short X.Y version.
 version = '2.2'
 # The full version, including alpha/beta/rc tags.
-release = '2.2.0'
+release = '2.2.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

pypy/doc/extending.rst

 This document tries to explain how to interface the PyPy python interpreter
 with any external library.
 
-Note: We try to describe state-of-the art, but it
-might fade out of date as this is the front on which things are changing
-in pypy rapidly.
+Right now, there are the following possibilities of providing
+third-party modules for the PyPy python interpreter (in order of
+usefulness):
 
-Possibilities
-=============
+* Write them in pure Python and use CFFI_.
 
-Right now, there are three possibilities of providing third-party modules
-for the PyPy python interpreter (in order of usefulness):
+* Write them in pure Python and use ctypes_.
 
-* Write them in pure python and use ctypes, see ctypes_
-  section
+* Write them in C++ and bind them through Reflex_.
 
-* Write them in pure python and use direct libffi low-level bindings, See
-  \_ffi_ module description.
+* Write them in as `RPython mixed modules`_.
 
-* Write them in RPython as mixedmodule_, using *rffi* as bindings.
 
-* Write them in C++ and bind them through Reflex_
+CFFI
+====
 
-.. _ctypes: #CTypes
-.. _\_ffi: #LibFFI
-.. _mixedmodule: #Mixed Modules
+CFFI__ is the recommended way.  It is a way to write pure Python code
+that accesses C libraries.  The idea is to support either ABI- or
+API-level access to C --- so that you can sanely access C libraries
+without depending on details like the exact field order in the C
+structures or the numerical value of all the constants.  It works on
+both CPython (as a separate ``pip install cffi``) and on PyPy, where it
+is included by default.
+
+PyPy's JIT does a quite reasonable job on the Python code that call C
+functions or manipulate C pointers with CFFI.  (As of PyPy 2.2.1, it
+could still be improved, but is already good.)
+
+See the documentation here__.
+
+.. __: http://cffi.readthedocs.org/
+.. __: http://cffi.readthedocs.org/
+
 
 CTypes
 ======
 
-The ctypes module in PyPy is ready to use.
-It's goal is to be as-compatible-as-possible with the
-`CPython ctypes`_ version. Right now it's able to support large examples,
-such as pyglet. PyPy is planning to have a 100% compatible ctypes
-implementation, without the CPython C-level API bindings (so it is very
-unlikely that direct object-manipulation trickery through this API will work).
+The goal of the ctypes module of PyPy is to be as compatible as possible
+with the `CPython ctypes`_ version.  It works for large examples, such
+as pyglet.  PyPy's implementation is not strictly 100% compatible with
+CPython, but close enough for most cases.
 
-We also provide a `ctypes-configure`_ for overcoming the platform dependencies,
-not relying on the ctypes codegen. This tool works by querying gcc about
-platform-dependent details (compiling small snippets of C code and running
-them), so it'll benefit not pypy-related ctypes-based modules as well.
+We also used to provide ``ctypes-configure`` for some API-level access.
+This is now viewed as a precursor of CFFI, which you should use instead.
+More (but older) information is available here__.
+Also, ctypes' performance is not as good as CFFI's.
 
-ctypes call are optimized by the JIT and the resulting machine code contains a
-direct call to the target C function.  However, due to the very dynamic nature
-of ctypes, some overhead over a bare C call is still present, in particular to
-check/convert the types of the parameters.  Moreover, even if most calls are
-optimized, some cannot and thus need to follow the slow path, not optimized by
-the JIT.
+.. _`CPython ctypes`: http://docs.python.org/library/ctypes.html
+.. __: ctypes-implementation.html
 
-.. _`ctypes-configure`: ctypes-implementation.html#ctypes-configure
-.. _`CPython ctypes`: http://docs.python.org/library/ctypes.html
+PyPy implements ctypes as pure Python code around two built-in modules
+called ``_ffi`` and ``_rawffi``, which give a very low-level binding to
+the C library libffi_.  Nowadays it is not recommended to use directly
+these two modules.
 
-Pros
-----
+.. _libffi: http://sourceware.org/libffi/
 
-Stable, CPython-compatible API.  Most calls are fast, optimized by JIT.
-
-Cons
-----
-
-Problems with platform-dependency (although we partially solve
-those). Although the JIT optimizes ctypes calls, some overhead is still
-present.  The slow-path is very slow.
-
-
-LibFFI
-======
-
-Mostly in order to be able to write a ctypes module, we developed a very
-low-level libffi bindings called ``_ffi``. (libffi is a C-level library for dynamic calling,
-which is used by CPython ctypes). This library provides stable and usable API,
-although it's API is a very low-level one. It does not contain any
-magic.  It is also optimized by the JIT, but has much less overhead than ctypes.
-
-Pros
-----
-
-It Works. Probably more suitable for a delicate code where ctypes magic goes
-in a way.  All calls are optimized by the JIT, there is no slow path as in
-ctypes.
-
-Cons
-----
-
-It combines disadvantages of using ctypes with disadvantages of using mixed
-modules. CPython-incompatible API, very rough and low-level.
-
-Mixed Modules
-=============
-
-This is the most advanced and powerful way of writing extension modules.
-It has some serious disadvantages:
-
-* a mixed module needs to be written in RPython, which is far more
-  complicated than Python (XXX link)
-
-* due to lack of separate compilation (as of July 2011), each
-  compilation-check requires to recompile whole PyPy python interpreter,
-  which takes 0.5-1h. We plan to solve this at some point in near future.
-
-* although rpython is a garbage-collected language, the border between
-  C and RPython needs to be managed by hand (each object that goes into the
-  C level must be explicitly freed).
-
-Some documentation is available `here`_
-
-.. _`here`: rffi.html
-
-XXX we should provide detailed docs about lltype and rffi, especially if we
-    want people to follow that way.
 
 Reflex
 ======
 
-This method is still experimental and is being exercised on a branch,
-`reflex-support`_, which adds the `cppyy`_ module.
+This method is still experimental.  It adds the `cppyy`_ module.
 The method works by using the `Reflex package`_ to provide reflection
 information of the C++ code, which is then used to automatically generate
 bindings at runtime.
 to work around it in python or with a C++ helper function.
 Although Reflex works on various platforms, the bindings with PyPy have only
 been tested on Linux.
+
+
+RPython Mixed Modules
+=====================
+
+This is the internal way to write built-in extension modules in PyPy.
+It cannot be used by any 3rd-party module: the extension modules are
+*built-in*, not independently loadable DLLs.
+
+This is reserved for special cases: it gives direct access to e.g. the
+details of the JIT, allowing us to tweak its interaction with user code.
+This is how the numpy module is being developed.
 So the position of the core PyPy developers is that if anyone wants to
 make an N+1'th attempt with LLVM, they are welcome, and will be happy to
 provide help in the IRC channel, but they are left with the burden of proof
-that it works.
+that (a) it works and (b) it gives important benefits.
 
 ----------------------
 How do I compile PyPy?

pypy/doc/index.rst

 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 2.2.0`_: the latest official release
+* `Release 2.2.1`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 2.2.0`: http://pypy.org/download.html
+.. _`Release 2.2.1`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html

pypy/doc/release-2.2.1.rst

+=======================================
+PyPy 2.2.1 - Incrementalism.1
+=======================================
+
+We're pleased to announce PyPy 2.2.1, which targets version 2.7.3 of the Python
+language. This is a bugfix release over 2.2.
+
+You can download the PyPy 2.2.1 release here:
+
+    http://pypy.org/download.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.2 and cpython 2.7.2`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows
+32, or ARM (ARMv6 or ARMv7, with VFPv3).
+
+Work on the native Windows 64 is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.2 and cpython 2.7.2`: http://speed.pypy.org
+
+Highlights
+==========
+
+This is a bugfix release.  The most important bugs fixed are:
+
+* an issue in sockets' reference counting emulation, showing up
+  notably when using the ssl module and calling ``makefile()``.
+
+* Tkinter support on Windows.
+
+* If sys.maxunicode==65535 (on Windows and maybe OS/X), the json
+  decoder incorrectly decoded surrogate pairs.
+
+* some FreeBSD fixes.
+
+Note that CFFI 0.8.1 was released.  Both versions 0.8 and 0.8.1 are
+compatible with both PyPy 2.2 and 2.2.1.
+
+
+Cheers,
+Armin Rigo & everybody

pypy/doc/whatsnew-head.rst

 
 .. branch: voidtype_strformat
 Better support for record numpy arrays
+
+.. branch: osx-eci-frameworks-makefile
+OSX: Ensure frameworks end up in Makefile when specified in External compilation info
+
+.. branch: less-stringly-ops
+Use subclasses of SpaceOperation instead of SpaceOperator objects.
+Random cleanups in flowspace and annotator.

pypy/module/_cffi_backend/cdataobj.py

     def get_array_length(self):
         return self.length
 
+    def _sizeof(self):
+        from pypy.module._cffi_backend.ctypeptr import W_CTypePtrOrArray
+        ctype = self.ctype
+        assert isinstance(ctype, W_CTypePtrOrArray)
+        return self.length * ctype.ctitem.size
+
 
 class W_CDataHandle(W_CData):
     _attrs_ = ['w_keepalive']

pypy/module/_cffi_backend/test/_backend_test_c.py

     py.test.raises(TypeError, "p + cast(new_primitive_type('int'), 42)")
     py.test.raises(TypeError, "p - cast(new_primitive_type('int'), 42)")
 
+def test_sizeof_sliced_array():
+    BInt = new_primitive_type("int")
+    BArray = new_array_type(new_pointer_type(BInt), 10)
+    p = newp(BArray, None)
+    assert sizeof(p[2:9]) == 7 * sizeof(BInt)
+
 
 def test_version():
     # this test is here mostly for PyPy

pypy/module/micronumpy/app_numpy.py

     if dtype is None:
         test = _numpypy.multiarray.array([start, stop, step, 0])
         dtype = test.dtype
-    arr = _numpypy.multiarray.zeros(int(math.ceil((stop - start) / step)), dtype=dtype)
+    length = math.ceil((float(stop) - start) / step)
+    length = int(length)
+    arr = _numpypy.multiarray.zeros(length, dtype=dtype)
     i = start
     for j in range(arr.size):
         arr[j] = i

pypy/module/micronumpy/test/test_numarray.py

         assert a.dtype is dtype(int)
         a = arange(3, 7, 2)
         assert (a == [3, 5]).all()
+        a = arange(3, 8, 2)
+        assert (a == [3, 5, 7]).all()
         a = arange(3, dtype=float)
         assert (a == [0., 1., 2.]).all()
         assert a.dtype is dtype(float)

pypy/module/posix/app_startfile.py

         ffi.cdef("""
         HINSTANCE ShellExecuteA(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT);
         HINSTANCE ShellExecuteW(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT);
-        DWORD GetLastError(void);
         """)
         self.NULL = ffi.NULL
         self.cast = ffi.cast

pypy/module/pypyjit/interp_jit.py

 """This is not the JIT :-)
 
-This is transformed to become a JIT by code elsewhere: pypy/jit/*
+This is transformed to become a JIT by code elsewhere: rpython/jit/*
 """
 
-from rpython.tool.pairtype import extendabletype
 from rpython.rlib.rarithmetic import r_uint, intmask
 from rpython.rlib.jit import JitDriver, hint, we_are_jitted, dont_look_inside
 from rpython.rlib import jit
 from rpython.rlib.jit import current_trace_length, unroll_parameters
 import pypy.interpreter.pyopcode   # for side-effects
 from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.interpreter.pycode import PyCode, CO_GENERATOR
+from pypy.interpreter.pycode import CO_GENERATOR
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.pyopcode import ExitFrame, Yield
 from opcode import opmap
 
+
 PyFrame._virtualizable_ = ['last_instr', 'pycode',
                            'valuestackdepth', 'locals_stack_w[*]',
                            'cells[*]',

pypy/module/test_lib_pypy/cffi_tests/test_version.py

     '0.4.2': '0.4',     # did not change
     '0.7.1': '0.7',     # did not change
     '0.7.2': '0.7',     # did not change
+    '0.8.1': '0.8',     # did not change
     }
 
 def test_version():

pypy/tool/release/package.py

 def package(basedir, name='pypy-nightly', rename_pypy_c='pypy',
             copy_to_dir=None, override_pypy_c=None, nostrip=False,
             withouttk=False):
+    assert '/' not in rename_pypy_c
     basedir = py.path.local(basedir)
     if override_pypy_c is None:
         basename = 'pypy-c'

rpython/annotator/annrpython.py

     def consider_op(self, block, opindex):
         op = block.operations[opindex]
         argcells = [self.binding(a) for a in op.args]
-        consider_meth = getattr(self,'consider_op_'+op.opname,
-                                None)
-        if not consider_meth:
-            raise Exception,"unknown op: %r" % op
 
         # let's be careful about avoiding propagated SomeImpossibleValues
         # to enter an op; the latter can result in violations of the
             if isinstance(arg, annmodel.SomeImpossibleValue):
                 raise BlockedInference(self, op, opindex)
         try:
-            resultcell = consider_meth(*argcells)
+            resultcell = op.consider(self, *argcells)
         except annmodel.AnnotatorError as e: # note that UnionError is a subclass
             graph = self.bookkeeper.position_key[0]
             e.source = gather_error(self, graph, block, opindex)

rpython/annotator/argument.py

 """
 Arguments objects.
 """
-from rpython.annotator.model import SomeTuple, SomeObject
+from rpython.annotator.model import SomeTuple
+from rpython.flowspace.argument import CallSpec
 
-# for parsing call arguments
-class RPythonCallsSpace(object):
-    """Pseudo Object Space providing almost no real operation.
-    For the Arguments class: if it really needs other operations, it means
-    that the call pattern is too complex for R-Python.
-    """
-    def newtuple(self, items_s):
-        if len(items_s) == 1 and items_s[0] is Ellipsis:
-            res = SomeObject()   # hack to get a SomeObject as the *arg
-            res.from_ellipsis = True
-            return res
-        else:
-            return SomeTuple(items_s)
-
-    def unpackiterable(self, s_obj, expected_length=None):
-        if isinstance(s_obj, SomeTuple):
-            return list(s_obj.items)
-        if (s_obj.__class__ is SomeObject and
-            getattr(s_obj, 'from_ellipsis', False)):    # see newtuple()
-            return [Ellipsis]
-        raise CallPatternTooComplex("'*' argument must be SomeTuple")
-
-    def bool(self, s_tup):
-        assert isinstance(s_tup, SomeTuple)
-        return bool(s_tup.items)
-
-
-class CallPatternTooComplex(Exception):
-    pass
-
-
-class ArgumentsForTranslation(object):
-    w_starstararg = None
-    def __init__(self, space, args_w, keywords=None, keywords_w=None,
-                 w_stararg=None, w_starstararg=None):
-        self.w_stararg = w_stararg
-        assert w_starstararg is None
-        self.space = space
-        assert isinstance(args_w, list)
-        self.arguments_w = args_w
-        self.keywords = keywords
-        self.keywords_w = keywords_w
-        self.keyword_names_w = None
-
-    def __repr__(self):
-        """ NOT_RPYTHON """
-        name = self.__class__.__name__
-        if not self.keywords:
-            return '%s(%s)' % (name, self.arguments_w,)
-        else:
-            return '%s(%s, %s, %s)' % (name, self.arguments_w,
-                                       self.keywords, self.keywords_w)
-
+class ArgumentsForTranslation(CallSpec):
     @property
     def positional_args(self):
         if self.w_stararg is not None:
-            args_w = self.space.unpackiterable(self.w_stararg)
+            args_w = self.unpackiterable(self.w_stararg)
             return self.arguments_w + args_w
         else:
             return self.arguments_w
 
+    def newtuple(self, items_s):
+        return SomeTuple(items_s)
+
+    def unpackiterable(self, s_obj):
+        assert isinstance(s_obj, SomeTuple)
+        return list(s_obj.items)
+
     def fixedunpack(self, argcount):
         """The simplest argument parsing: get the 'argcount' arguments,
         or raise a real ValueError if the length is wrong."""
 
     def prepend(self, w_firstarg): # used often
         "Return a new Arguments with a new argument inserted first."
-        return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w,
-                                       self.keywords, self.keywords_w, self.w_stararg,
-                                       self.w_starstararg)
+        return ArgumentsForTranslation([w_firstarg] + self.arguments_w,
+                                       self.keywords, self.w_stararg)
 
     def copy(self):
-        return ArgumentsForTranslation(self.space, self.arguments_w,
-                                       self.keywords, self.keywords_w, self.w_stararg,
-                                       self.w_starstararg)
+        return ArgumentsForTranslation(self.arguments_w, self.keywords,
+                self.w_stararg)
 
     def _match_signature(self, scope_w, signature, defaults_w=None):
         """Parse args and kwargs according to the signature of a code object,
 
         args_w = self.positional_args
         num_args = len(args_w)
-        keywords = self.keywords or []
+        keywords = self.keywords
         num_kwds = len(keywords)
 
         # put as many positional input arguments into place as available
                 starargs_w = args_w[co_argcount:]
             else:
                 starargs_w = []
-            scope_w[co_argcount] = self.space.newtuple(starargs_w)
+            scope_w[co_argcount] = self.newtuple(starargs_w)
         elif num_args > co_argcount:
             raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0)
 
 
         # handle keyword arguments
         num_remainingkwds = 0
-        keywords_w = self.keywords_w
         kwds_mapping = None
         if num_kwds:
             # kwds_mapping maps target indexes in the scope (minus input_argcount)
-            # to positions in the keywords_w list
-            kwds_mapping = [-1] * (co_argcount - input_argcount)
+            # to keyword names
+            kwds_mapping = []
             # match the keywords given at the call site to the argument names
             # the called function takes
             # this function must not take a scope_w, to make the scope not
             # escape
             num_remainingkwds = len(keywords)
-            for i, name in enumerate(keywords):
-                # If name was not encoded as a string, it could be None. In that
-                # case, it's definitely not going to be in the signature.
-                if name is None:
-                    continue
+            for name in keywords:
                 j = signature.find_argname(name)
                 # if j == -1 nothing happens
                 if j < input_argcount:
                     if j >= 0:
                         raise ArgErrMultipleValues(name)
                 else:
-                    kwds_mapping[j - input_argcount] = i # map to the right index
+                    kwds_mapping.append(name)
                     num_remainingkwds -= 1
 
             if num_remainingkwds:
                 if co_argcount == 0:
                     raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0)
-                raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords,
-                                        kwds_mapping, self.keyword_names_w)
+                raise ArgErrUnknownKwds(num_remainingkwds, keywords,
+                                        kwds_mapping)
 
         # check for missing arguments and fill them from the kwds,
         # or with defaults, if available
         if input_argcount < co_argcount:
             def_first = co_argcount - (0 if defaults_w is None else len(defaults_w))
             j = 0
-            kwds_index = -1
             for i in range(input_argcount, co_argcount):
-                if kwds_mapping is not None:
-                    kwds_index = kwds_mapping[j]
-                    j += 1
-                    if kwds_index >= 0:
-                        scope_w[i] = keywords_w[kwds_index]
-                        continue
+                name = signature.argnames[i]
+                if name in keywords:
+                    scope_w[i] = keywords[name]
+                    continue
                 defnum = i - def_first
                 if defnum >= 0:
                     scope_w[i] = defaults_w[defnum]
 
     def unpack(self):
         "Return a ([w1,w2...], {'kw':w3...}) pair."
-        kwds_w = dict(zip(self.keywords, self.keywords_w)) if self.keywords else {}
-        return self.positional_args, kwds_w
+        return self.positional_args, self.keywords
 
     def match_signature(self, signature, defaults_w):
         """Parse args and kwargs according to the signature of a code object,
 
     def unmatch_signature(self, signature, data_w):
         """kind of inverse of match_signature"""
-        need_cnt = len(self.positional_args)
-        need_kwds = self.keywords or []
-        space = self.space
         argnames, varargname, kwargname = signature
         assert kwargname is None
         cnt = len(argnames)
-        data_args_w = data_w[:cnt]
+        need_cnt = len(self.positional_args)
         if varargname:
-            data_w_stararg = data_w[cnt]
-            cnt += 1
-        else:
-            data_w_stararg = space.newtuple([])
+            assert len(data_w) == cnt + 1
+            stararg_w = self.unpackiterable(data_w[cnt])
+            if stararg_w:
+                args_w = data_w[:cnt] + stararg_w
+                assert len(args_w) == need_cnt
+                assert not self.keywords
+                return ArgumentsForTranslation(args_w, {})
+            else:
+                data_w = data_w[:-1]
         assert len(data_w) == cnt
+        assert len(data_w) >= need_cnt
+        args_w = data_w[:need_cnt]
+        _kwds_w = dict(zip(argnames[need_cnt:], data_w[need_cnt:]))
+        keywords_w = [_kwds_w[key] for key in self.keywords]
+        return ArgumentsForTranslation(args_w, dict(zip(self.keywords, keywords_w)))
 
-        unfiltered_kwds_w = {}
-        if len(data_args_w) >= need_cnt:
-            args_w = data_args_w[:need_cnt]
-            for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]):
-                unfiltered_kwds_w[argname] = w_arg
-            assert not space.bool(data_w_stararg)
-        else:
-            stararg_w = space.unpackiterable(data_w_stararg)
-            args_w = data_args_w + stararg_w
-            assert len(args_w) == need_cnt
-
-        keywords = []
-        keywords_w = []
-        for key in need_kwds:
-            keywords.append(key)
-            keywords_w.append(unfiltered_kwds_w[key])
-
-        return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w)
-
-    @staticmethod
-    def fromshape(space, (shape_cnt, shape_keys, shape_star, shape_stst), data_w):
+    @classmethod
+    def fromshape(cls, (shape_cnt, shape_keys, shape_star), data_w):
         args_w = data_w[:shape_cnt]
         p = end_keys = shape_cnt + len(shape_keys)
         if shape_star:
             p += 1
         else:
             w_star = None
-        if shape_stst:
-            w_starstar = data_w[p]
-            p += 1
-        else:
-            w_starstar = None
-        return ArgumentsForTranslation(space, args_w, list(shape_keys),
-                                       data_w[shape_cnt:end_keys], w_star,
-                                       w_starstar)
+        return cls(args_w, dict(zip(shape_keys, data_w[shape_cnt:end_keys])),
+                w_star)
 
-    def flatten(self):
-        """ Argument <-> list of w_objects together with "shape" information """
-        shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape()
-        data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)]
-                                         for key in shape_keys]
-        if shape_star:
-            data_w.append(self.w_stararg)
-        if shape_stst:
-            data_w.append(self.w_starstararg)
-        return (shape_cnt, shape_keys, shape_star, shape_stst), data_w
 
-    def _rawshape(self, nextra=0):
-        shape_cnt = len(self.arguments_w) + nextra       # Number of positional args
-        if self.keywords:
-            shape_keys = self.keywords[:]                # List of keywords (strings)
-            shape_keys.sort()
-        else:
-            shape_keys = []
-        shape_star = self.w_stararg is not None   # Flag: presence of *arg
-        shape_stst = self.w_starstararg is not None # Flag: presence of **kwds
-        return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted
-
-
-def rawshape(args, nextra=0):
-    return args._rawshape(nextra)
+def rawshape(args):
+    return args._rawshape()
 
 
 #
 
 
 class ArgErrUnknownKwds(ArgErr):
-    def __init__(self, space, num_remainingkwds, keywords, kwds_mapping,
-                 keyword_names_w):
+    def __init__(self, num_remainingkwds, keywords, kwds_mapping):
         name = ''
         self.num_kwds = num_remainingkwds
         if num_remainingkwds == 1:
-            for i in range(len(keywords)):
-                if i not in kwds_mapping:
-                    name = keywords[i]
-                    if name is None:
-                        # We'll assume it's unicode. Encode it.
-                        # Careful, I *think* it should not be possible to
-                        # get an IndexError here but you never know.
-                        try:
-                            if keyword_names_w is None:
-                                raise IndexError
-                            # note: negative-based indexing from the end
-                            w_name = keyword_names_w[i - len(keywords)]
-                        except IndexError:
-                            name = '?'
-                        else:
-                            w_enc = space.wrap(space.sys.defaultencoding)
-                            w_err = space.wrap("replace")
-                            w_name = space.call_method(w_name, "encode", w_enc,
-                                                       w_err)
-                            name = space.str_w(w_name)
+            for name in keywords:
+                if name not in kwds_mapping:
                     break
         self.kwd_name = name
 

rpython/annotator/binaryop.py

 import py
 import operator
 from rpython.tool.pairtype import pair, pairtype
-from rpython.annotator.model import SomeObject, SomeInteger, SomeBool, s_Bool
-from rpython.annotator.model import SomeString, SomeChar, SomeList, SomeDict,\
-     SomeOrderedDict
-from rpython.annotator.model import SomeUnicodeCodePoint, SomeUnicodeString
-from rpython.annotator.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue
-from rpython.annotator.model import SomeInstance, SomeBuiltin, SomeIterator
-from rpython.annotator.model import SomePBC, SomeFloat, s_None, SomeByteArray
-from rpython.annotator.model import SomeWeakRef
-from rpython.annotator.model import SomeAddress, SomeTypedAddressAccess
-from rpython.annotator.model import SomeSingleFloat, SomeLongFloat, SomeType
-from rpython.annotator.model import unionof, UnionError, missing_operation
-from rpython.annotator.model import read_can_only_throw
-from rpython.annotator.model import add_knowntypedata, merge_knowntypedata
+from rpython.annotator.model import (
+    SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList,
+    SomeDict, SomeOrderedDict, SomeUnicodeCodePoint, SomeUnicodeString,
+    SomeTuple, SomeImpossibleValue, s_ImpossibleValue, SomeInstance,
+    SomeBuiltin, SomeIterator, SomePBC, SomeFloat, s_None, SomeByteArray,
+    SomeWeakRef, SomeAddress, SomeTypedAddressAccess, SomeSingleFloat,
+    SomeLongFloat, SomeType, SomeConstantType, unionof, UnionError,
+    missing_operation, read_can_only_throw, add_knowntypedata,
+    merge_knowntypedata,)
 from rpython.annotator.bookkeeper import getbookkeeper
 from rpython.flowspace.model import Variable, Constant
 from rpython.rlib import rarithmetic
     getitem_key = getitem_idx_key
 
 
-class __extend__(pairtype(SomeType, SomeType)):
+class __extend__(pairtype(SomeType, SomeType),
+                 pairtype(SomeType, SomeConstantType),
+                 pairtype(SomeConstantType, SomeType),):
 
     def union((obj1, obj2)):
         result = SomeType()

rpython/annotator/bookkeeper.py

     SomeBuiltin, SomePBC, SomeInteger, TLS, SomeAddress, SomeUnicodeCodePoint,
     s_None, s_ImpossibleValue, SomeLLADTMeth, SomeBool, SomeTuple,
     SomeImpossibleValue, SomeUnicodeString, SomeList, HarmlesslyBlocked,
-    SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray)
+    SomeWeakRef, lltype_to_annotation, SomeType, SomeByteArray, SomeConstantType)
 from rpython.annotator.classdef import InstanceSource, ClassDef
 from rpython.annotator.listdef import ListDef, ListItem
 from rpython.annotator.dictdef import DictDef
 from rpython.annotator import description
 from rpython.annotator.signature import annotationoftype
-from rpython.annotator.argument import ArgumentsForTranslation, RPythonCallsSpace
+from rpython.annotator.argument import ArgumentsForTranslation
 from rpython.rlib.objectmodel import r_dict, Symbolic
 from rpython.tool.algo.unionfind import UnionFind
 from rpython.rtyper.lltypesystem import lltype, llmemory
         elif isinstance(x, llmemory.fakeaddress):
             result = SomeAddress()
         elif tp is type:
-            if (x is type(None) or      # add cases here if needed
-                x.__module__ == 'rpython.rtyper.lltypesystem.lltype'):
-                result = SomeType()
-            else:
-                result = SomePBC([self.getdesc(x)])
+            result = SomeConstantType(x, self)
         elif callable(x):
             if hasattr(x, 'im_self') and hasattr(x, 'im_func'):
                 # on top of PyPy, for cases like 'l.append' where 'l' is a
         return op
 
     def build_args(self, op, args_s):
-        space = RPythonCallsSpace()
         if op == "simple_call":
-            return ArgumentsForTranslation(space, list(args_s))
+            return ArgumentsForTranslation(list(args_s))
         elif op == "call_args":
             return ArgumentsForTranslation.fromshape(
-                    space, args_s[0].const, # shape
+                    args_s[0].const, # shape
                     list(args_s[1:]))
 
     def ondegenerated(self, what, s_value, where=None, called_from_graph=None):

rpython/annotator/builtin.py

     r_func, nimplicitarg = s_repr.const.get_r_implfunc()
 
     nbargs = len(args_s) + nimplicitarg
-    s_sigs = r_func.get_s_signatures((nbargs, (), False, False))
+    s_sigs = r_func.get_s_signatures((nbargs, (), False))
     if len(s_sigs) != 1:
         raise TyperError("cannot hlinvoke callable %r with not uniform"
                          "annotations: %r" % (s_repr.const,

rpython/annotator/description.py

                                              self.name,
                                              flags)
 
+    @staticmethod
     def consider_call_site(bookkeeper, family, descs, args, s_result, op):
-        shape = rawshape(args, nextra=1)     # account for the extra 'self'
+        cnt, keys, star = rawshape(args)
+        shape = cnt + 1, keys, star  # account for the extra 'self'
         row = FunctionDesc.row_to_consider(descs, args, op)
         family.calltable_add_row(shape, row)
-    consider_call_site = staticmethod(consider_call_site)
 
     def rowkey(self):
         # we are computing call families and call tables that always contain
         args = args.prepend(s_self)
         return self.funcdesc.pycall(schedule, args, s_previous_result, op)
 
+    @staticmethod
     def consider_call_site(bookkeeper, family, descs, args, s_result, op):
-        shape = rawshape(args, nextra=1)    # account for the extra 'self'
+        cnt, keys, star = rawshape(args)
+        shape = cnt + 1, keys, star  # account for the extra 'self'
         row = FunctionDesc.row_to_consider(descs, args, op)
         family.calltable_add_row(shape, row)
-    consider_call_site = staticmethod(consider_call_site)
 
     def rowkey(self):
         return self.funcdesc

rpython/annotator/model.py

         else:
             return kt.__name__
 
+class SomeConstantType(SomePBC):
+    can_be_None = False
+    subset_of = None
+    def __init__(self, x, bk):
+        self.descriptions = set([bk.getdesc(x)])
+        self.knowntype = type(x)
+        self.const = x
+
 
 class SomeBuiltin(SomeObject):
     "Stands for a built-in function or method with special-cased analysis."

rpython/annotator/policy.py

 # base annotation policy for specialization
 from rpython.annotator.specialize import default_specialize as default
-from rpython.annotator.specialize import specialize_argvalue, specialize_argtype, specialize_arglistitemtype, specialize_arg_or_var
-from rpython.annotator.specialize import memo, specialize_call_location
+from rpython.annotator.specialize import (
+    specialize_argvalue, specialize_argtype, specialize_arglistitemtype,
+    specialize_arg_or_var, memo, specialize_call_location)
 
 
-class BasicAnnotatorPolicy(object):
+class AnnotatorPolicy(object):
+    """
+    Possibly subclass and pass an instance to the annotator to control
+    special-casing during annotation
+    """
 
     def event(pol, bookkeeper, what, *args):
         pass
 
-    def get_specializer(pol, tag):
-        return pol.no_specialization
-
-    def no_specialization(pol, funcdesc, args_s):
-        return funcdesc.cachedgraph(None)
-
-    def no_more_blocks_to_annotate(pol, annotator):
-        # hint to all pending specializers that we are done
-        for callback in annotator.bookkeeper.pending_specializations:
-            callback()
-        del annotator.bookkeeper.pending_specializations[:]
-
-class AnnotatorPolicy(BasicAnnotatorPolicy):
-    """
-    Possibly subclass and pass an instance to the annotator to control special casing during annotation
-    """
-
     def get_specializer(pol, directive):
         if directive is None:
             return pol.default_specialize
     def specialize__ll_and_arg(pol, *args):
         from rpython.rtyper.annlowlevel import LowLevelAnnotatorPolicy
         return LowLevelAnnotatorPolicy.specialize__ll_and_arg(*args)
+
+    def no_more_blocks_to_annotate(pol, annotator):
+        # hint to all pending specializers that we are done
+        for callback in annotator.bookkeeper.pending_specializations:
+            callback()
+        del annotator.bookkeeper.pending_specializations[:]

rpython/annotator/specialize.py

 from rpython.tool.algo.unionfind import UnionFind
 from rpython.flowspace.model import Block, Link, Variable, SpaceOperation
 from rpython.flowspace.model import checkgraph
+from rpython.flowspace.operation import op
 from rpython.annotator import model as annmodel
 from rpython.flowspace.argument import Signature
 
             argscopy = [Variable(v) for v in graph.getargs()]
             starargs = [Variable('stararg%d'%i) for i in range(nb_extra_args)]
             newstartblock = Block(argscopy[:-1] + starargs)
-            newtup = SpaceOperation('newtuple', starargs, argscopy[-1])
+            newtup = op.newtuple(*starargs)
+            newtup.result = argscopy[-1]
             newstartblock.operations.append(newtup)
             newstartblock.closeblock(Link(argscopy, graph.startblock))
             graph.startblock = newstartblock

rpython/annotator/test/test_annrpython.py

 from rpython.rlib.rarithmetic import r_singlefloat
 from rpython.rlib import objectmodel
 from rpython.flowspace.objspace import build_flow, FlowingError
+from rpython.flowspace.operation import op
 
 from rpython.translator.test import snippet
 
             return x+1
         """
         x = Variable("x")
-        result = Variable("result")
-        op = SpaceOperation("add", [x, Constant(1)], result)
+        oper = op.add(x, Constant(1))
         block = Block([x])
         fun = FunctionGraph("f", block)
-        block.operations.append(op)
-        block.closeblock(Link([result], fun.returnblock))
+        block.operations.append(oper)
+        block.closeblock(Link([oper.result], fun.returnblock))
         a = self.RPythonAnnotator()
         a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
         a.complete()
         """
         i1 = Variable("i1")
         i2 = Variable("i2")
-        i3 = Variable("i3")
-        conditionres = Variable("conditionres")
-        conditionop = SpaceOperation("gt", [i1, Constant(0)], conditionres)
-        decop = SpaceOperation("add", [i2, Constant(-1)], i3)
+        conditionop = op.gt(i1, Constant(0))
+        decop = op.add(i2, Constant(-1))
         headerblock = Block([i1])
         whileblock = Block([i2])
 
         fun = FunctionGraph("f", headerblock)
         headerblock.operations.append(conditionop)
-        headerblock.exitswitch = conditionres
+        headerblock.exitswitch = conditionop.result
         headerblock.closeblock(Link([i1], fun.returnblock, False),
                                Link([i1], whileblock, True))
         whileblock.operations.append(decop)
-        whileblock.closeblock(Link([i3], headerblock))
+        whileblock.closeblock(Link([decop.result], headerblock))
 
         a = self.RPythonAnnotator()
         a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
         i1 = Variable("i1")
         i2 = Variable("i2")
         i3 = Variable("i3")
-        i4 = Variable("i4")
         sum2 = Variable("sum2")
         sum3 = Variable("sum3")
-        sum4 = Variable("sum4")
-
-        conditionres = Variable("conditionres")
-        conditionop = SpaceOperation("gt", [i2, Constant(0)], conditionres)
-        decop = SpaceOperation("add", [i3, Constant(-1)], i4)
-        addop = SpaceOperation("add", [i3, sum3], sum4)
+
+        conditionop = op.gt(i2, Constant(0))
+        decop = op.add(i3, Constant(-1))
+        addop = op.add(i3, sum3)
         startblock = Block([i1])
         headerblock = Block([i2, sum2])
         whileblock = Block([i3, sum3])
         fun = FunctionGraph("f", startblock)
         startblock.closeblock(Link([i1, Constant(0)], headerblock))
         headerblock.operations.append(conditionop)
-        headerblock.exitswitch = conditionres
+        headerblock.exitswitch = conditionop.result
         headerblock.closeblock(Link([sum2], fun.returnblock, False),
                                Link([i2, sum2], whileblock, True))
         whileblock.operations.append(addop)
         whileblock.operations.append(decop)
-        whileblock.closeblock(Link([i4, sum4], headerblock))
+        whileblock.closeblock(Link([decop.result, addop.result], headerblock))
 
         a = self.RPythonAnnotator()
         a.addpendingblock(fun, fun.startblock, [annmodel.SomeInteger()])
         gf2 = graphof(a, f2)
         gf3 = graphof(a, f3)
 
-        assert fam1.calltables == {(2, (), False, False): [{fdesc1: gf1}], (1, (), False, False): [{fdesc1: gf1}]}
-        assert fam2.calltables == {(1, (), False, False): [{fdesc2: gf2, fdesc3: gf3}]}
+        assert fam1.calltables == {(2, (), False): [{fdesc1: gf1}],
+                                   (1, (), False): [{fdesc1: gf1}]}
+        assert fam2.calltables == {(1, (), False): [{fdesc2: gf2, fdesc3: gf3}]}
 
     def test_pbc_call_ins(self):
         class A(object):
         gfA_m = graphof(a, A.m.im_func)
         gfC_m = graphof(a, C.m.im_func)
 
-        assert famB_n.calltables == {(1, (), False, False): [{mdescB_n.funcdesc: gfB_n}] }
-        assert famA_m.calltables == {(1, (), False, False): [{mdescA_m.funcdesc: gfA_m, mdescC_m.funcdesc: gfC_m }] }
+        assert famB_n.calltables == {(1, (), False): [{mdescB_n.funcdesc: gfB_n}] }
+        assert famA_m.calltables == {(1, (), False): [{mdescA_m.funcdesc: gfA_m, mdescC_m.funcdesc: gfC_m }] }
 
         mdescCinit = getmdesc(C().__init__)
         famCinit = mdescCinit.getcallfamily()
         gfCinit = graphof(a, C.__init__.im_func)
 
-        assert famCinit.calltables == {(1, (), False, False): [{mdescCinit.funcdesc: gfCinit}] }
+        assert famCinit.calltables == {(1, (), False): [{mdescCinit.funcdesc: gfCinit}] }
 
     def test_isinstance_usigned(self):
         def f(x):
 
         someint = annmodel.SomeInteger()
 
-        assert (fdesc.get_s_signatures((2,(),False,False))
+        assert (fdesc.get_s_signatures((2, (), False))
                 == [([someint,someint],someint)])
 
     def test_emulated_pbc_call_callback(self):

rpython/annotator/test/test_argument.py

 # -*- coding: utf-8 -*-
 import py
 from rpython.annotator.argument import ArgumentsForTranslation, rawshape
-from rpython.flowspace.argument import Signature
+from rpython.flowspace.argument import Signature, CallSpec
 
-class DummySpace(object):
+class MockArgs(ArgumentsForTranslation):
     def newtuple(self, items):
         return tuple(items)
 
-    def bool(self, obj):
-        return bool(obj)
-
     def unpackiterable(self, it):
         return list(it)
 
 
-def make_arguments_for_translation(space, args_w, keywords_w={},
-                                   w_stararg=None, w_starstararg=None):
-    return ArgumentsForTranslation(space, args_w, keywords_w.keys(),
-                                   keywords_w.values(), w_stararg,
-                                   w_starstararg)
-
 class TestArgumentsForTranslation(object):
 
     def test_prepend(self):
-        space = DummySpace()
-        args = ArgumentsForTranslation(space, ["0"])
+        args = MockArgs(["0"])
         args1 = args.prepend("thingy")
         assert args1 is not args
         assert args1.arguments_w == ["thingy", "0"]
-        assert args1.keywords is args.keywords
-        assert args1.keywords_w is args.keywords_w
+        assert args1.keywords == args.keywords
 
     def test_fixedunpacked(self):
-        space = DummySpace()
-
-        args = ArgumentsForTranslation(space, [], ["k"], [1])
+        args = MockArgs([], {"k": 1})
         py.test.raises(ValueError, args.fixedunpack, 1)
 
-        args = ArgumentsForTranslation(space, ["a", "b"])
+        args = MockArgs(["a", "b"])
         py.test.raises(ValueError, args.fixedunpack, 0)
         py.test.raises(ValueError, args.fixedunpack, 1)
         py.test.raises(ValueError, args.fixedunpack, 3)
         assert args.fixedunpack(2) == ['a', 'b']
 
     def test_unmatch_signature(self):
-        space = DummySpace()
-        args = make_arguments_for_translation(space, [1,2,3])
+        args = MockArgs([1, 2, 3])
         sig = Signature(['a', 'b', 'c'], None, None)
         data = args.match_signature(sig, [])
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
-        args = make_arguments_for_translation(space, [1])
+        args = MockArgs([1])
         sig = Signature(['a', 'b', 'c'], None, None)
         data = args.match_signature(sig, [2, 3])
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
-        args = make_arguments_for_translation(space, [1,2,3,4,5])
+        args = MockArgs([1, 2, 3, 4, 5])
         sig = Signature(['a', 'b', 'c'], 'r', None)
         data = args.match_signature(sig, [])
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
-        args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
+        args = MockArgs([1], {'c': 3, 'b': 2})
         sig = Signature(['a', 'b', 'c'], None, None)
         data = args.match_signature(sig, [])
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
-        args = make_arguments_for_translation(space, [1], {'c': 5})
+        args = MockArgs([1], {'c': 5})
         sig = Signature(['a', 'b', 'c'], None, None)
         data = args.match_signature(sig, [2, 3])
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
     def test_rawshape(self):
-        space = DummySpace()
-        args = make_arguments_for_translation(space, [1,2,3])
-        assert rawshape(args) == (3, (), False, False)
+        args = MockArgs([1, 2, 3])
+        assert rawshape(args) == (3, (), False)
 
-        args = make_arguments_for_translation(space, [1])
-        assert rawshape(args, 2) == (3, (), False, False)
+        args = MockArgs([1, 2, 3, 4, 5])
+        assert rawshape(args) == (5, (), False)
 
-        args = make_arguments_for_translation(space, [1,2,3,4,5])
-        assert rawshape(args) == (5, (), False, False)
+        args = MockArgs([1], {'c': 3, 'b': 2})
+        assert rawshape(args) == (1, ('b', 'c'), False)
 
-        args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
-        assert rawshape(args) == (1, ('b', 'c'), False, False)
+        args = MockArgs([1], {'c': 5})
+        assert rawshape(args) == (1, ('c', ), False)
 
-        args = make_arguments_for_translation(space, [1], {'c': 5})
-        assert rawshape(args) == (1, ('c', ), False, False)
+        args = MockArgs([1], {'c': 5, 'd': 7})
+        assert rawshape(args) == (1, ('c', 'd'), False)
 
-        args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
-        assert rawshape(args) == (1, ('c', 'd'), False, False)
-
-        args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
-        assert rawshape(args) == (5, ('d', 'e'), False, False)
-
-
-    def test_flatten(self):
-        space = DummySpace()
-        args = make_arguments_for_translation(space, [1,2,3])
-        assert args.flatten() == ((3, (), False, False), [1, 2, 3])
-
-        args = make_arguments_for_translation(space, [1])
-        assert args.flatten() == ((1, (), False, False), [1])
-
-        args = make_arguments_for_translation(space, [1,2,3,4,5])
-        assert args.flatten() == ((5, (), False, False), [1,2,3,4,5])
-
-        args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
-        assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3])
-
-        args = make_arguments_for_translation(space, [1], {'c': 5})
-        assert args.flatten() == ((1, ('c', ), False, False), [1, 5])
-
-        args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
-        assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7])
-
-        args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
-        assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5])
+        args = MockArgs([1, 2, 3, 4, 5], {'e': 5, 'd': 7})
+        assert rawshape(args) == (5, ('d', 'e'), False)
 
     def test_stararg_flowspace_variable(self):
-        space = DummySpace()
         var = object()
-        shape = ((2, ('g', ), True, False), [1, 2, 9, var])
-        args = make_arguments_for_translation(space, [1,2], {'g': 9},
-                                       w_stararg=var)
+        shape = ((2, ('g', ), True), [1, 2, 9, var])
+        args = MockArgs([1, 2], {'g': 9}, w_stararg=var)
         assert args.flatten() == shape
 
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-
     def test_fromshape(self):
-        space = DummySpace()
-        shape = ((3, (), False, False), [1, 2, 3])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((3, (), False), [1, 2, 3])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((1, (), False, False), [1])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((1, (), False), [1])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((5, (), False, False), [1,2,3,4,5])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((5, (), False), [1, 2, 3, 4, 5])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((1, ('b', 'c'), False, False), [1, 2, 3])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((1, ('b', 'c'), False), [1, 2, 3])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((1, ('c', ), False, False), [1, 5])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((1, ('c', ), False), [1, 5])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((1, ('c', 'd'), False, False), [1, 5, 7])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((1, ('c', 'd'), False), [1, 5, 7])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape
 
-        shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5])
-        args = ArgumentsForTranslation.fromshape(space, *shape)
+        shape = ((5, ('d', 'e'), False), [1, 2, 3, 4, 5, 7, 5])
+        args = MockArgs.fromshape(*shape)
         assert args.flatten() == shape

rpython/annotator/unaryop.py

 
 class __extend__(SomeObject):
 
-    def type(obj, *moreargs):
+    def type(self, *moreargs):
         if moreargs:
             raise Exception('type() called with more than one argument')
         r = SomeType()
         bk = getbookkeeper()
-        op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=obj)
+        op = bk._find_current_op(opname="type", arity=1, pos=0, s_type=self)
         r.is_type_of = [op.args[0]]
         return r
 
-    def issubtype(obj, s_cls):
-        if hasattr(obj, 'is_type_of'):
-            vars = obj.is_type_of
+    def issubtype(self, s_cls):
+        if hasattr(self, 'is_type_of'):
+            vars = self.is_type_of
             annotator = getbookkeeper().annotator
             return builtin.builtin_isinstance(annotator.binding(vars[0]),
                                               s_cls, vars)
-        if obj.is_constant() and s_cls.is_constant():
-            return immutablevalue(issubclass(obj.const, s_cls.const))
+        if self.is_constant() and s_cls.is_constant():
+            return immutablevalue(issubclass(self.const, s_cls.const))
         return s_Bool
 
-    def len(obj):
+    def len(self):
         return SomeInteger(nonneg=True)
 
-    def bool_behavior(obj, s):
-        if obj.is_immutable_constant():
-            s.const = bool(obj.const)
+    def bool_behavior(self, s):
+        if self.is_immutable_constant():
+            s.const = bool(self.const)
         else:
-            s_len = obj.len()
+            s_len = self.len()
             if s_len.is_immutable_constant():
                 s.const = s_len.const > 0
 
         r.set_knowntypedata(knowntypedata)
         return r
 
-    def hash(obj):
+    def hash(self):
         raise AnnotatorError("cannot use hash() in RPython")
 
-    def str(obj):
-        getbookkeeper().count('str', obj)
+    def str(self):
+        getbookkeeper().count('str', self)
         return SomeString()
 
-    def unicode(obj):
-        getbookkeeper().count('unicode', obj)
+    def unicode(self):
+        getbookkeeper().count('unicode', self)
         return SomeUnicodeString()
 
-    def repr(obj):
-        getbookkeeper().count('repr', obj)
+    def repr(self):
+        getbookkeeper().count('repr', self)
         return SomeString()
 
-    def hex(obj):
-        getbookkeeper().count('hex', obj)
+    def hex(self):
+        getbookkeeper().count('hex', self)
         return SomeString()
 
-    def oct(obj):
-        getbookkeeper().count('oct', obj)
+    def oct(self):
+        getbookkeeper().count('oct', self)
         return SomeString()
 
-    def id(obj):
+    def id(self):
         raise Exception("cannot use id() in RPython; "
                         "see objectmodel.compute_xxx()")
 
-    def int(obj):
+    def int(self):
         return SomeInteger()
 
-    def float(obj):
+    def float(self):
         return SomeFloat()
 
-    def delattr(obj, s_attr):
-        if obj.__class__ != SomeObject or obj.knowntype != object:
+    def delattr(self, s_attr):
+        if self.__class__ != SomeObject or self.knowntype != object:
             getbookkeeper().warning(
                 ("delattr on potentally non-SomeObjects is not RPythonic: delattr(%r,%r)" %
-                 (obj, s_attr)))
+                 (self, s_attr)))
 
-    def find_method(obj, name):
+    def find_method(self, name):
         "Look for a special-case implementation for the named method."
         try:
-            analyser = getattr(obj.__class__, 'method_' + name)
+            analyser = getattr(self.__class__, 'method_' + name)
         except AttributeError:
             return None
         else:
-            return SomeBuiltin(analyser, obj, name)
+            return SomeBuiltin(analyser, self, name)
 
-    def getattr(obj, s_attr):
+    def getattr(self, s_attr):
         # get a SomeBuiltin if the SomeObject has
         # a corresponding method to handle it
         if not s_attr.is_constant() or not isinstance(s_attr.const, str):
             raise AnnotatorError("getattr(%r, %r) has non-constant argument"
-                                 % (obj, s_attr))
+                                 % (self, s_attr))
         attr = s_attr.const
-        s_method = obj.find_method(attr)
+        s_method = self.find_method(attr)
         if s_method is not None:
             return s_method
         # if the SomeObject is itself a constant, allow reading its attrs
-        if obj.is_immutable_constant() and hasattr(obj.const, attr):
-            return immutablevalue(getattr(obj.const, attr))
-        raise AnnotatorError("Cannot find attribute %r on %r" % (attr, obj))
+        if self.is_immutable_constant() and hasattr(self.const, attr):
+            return immutablevalue(getattr(self.const, attr))
+        raise AnnotatorError("Cannot find attribute %r on %r" % (attr, self))
     getattr.can_only_throw = []
 
-    def bind_callables_under(obj, classdef, name):
-        return obj   # default unbound __get__ implementation
+    def bind_callables_under(self, classdef, name):
+        return self   # default unbound __get__ implementation
 
-    def simple_call(obj, *args_s):
-        return obj.call(getbookkeeper().build_args("simple_call", args_s))
+    def simple_call(self, *args_s):
+        return self.call(getbookkeeper().build_args("simple_call", args_s))
 
-    def call_args(obj, *args_s):
-        return obj.call(getbookkeeper().build_args("call_args", args_s))
+    def call_args(self, *args_s):
+        return self.call(getbookkeeper().build_args("call_args", args_s))
 
-    def call(obj, args, implicit_init=False):
+    def call(self, args, implicit_init=False):
         raise AnnotatorError("Cannot prove that the object is callable")
 
-    def op_contains(obj, s_element):
+    def op_contains(self, s_element):
         return s_Bool
     op_contains.can_only_throw = []
 
 
 class __extend__(SomeFloat):
 
-    def pos(flt):
-        return flt
+    def pos(self):
+        return self
 
-    def neg(flt):
+    def neg(self):
         return SomeFloat()
 
     abs = neg
 
 class __extend__(SomeTuple):
 
-    def len(tup):
-        return immutablevalue(len(tup.items))
+    def len(self):
+        return immutablevalue(len(self.items))
 
-    def iter(tup):
-        getbookkeeper().count("tuple_iter", tup)
-        return SomeIterator(tup)
+    def iter(self):
+        getbookkeeper().count("tuple_iter", self)
+        return SomeIterator(self)
     iter.can_only_throw = []
 
-    def getanyitem(tup):
-        return unionof(*tup.items)
+    def getanyitem(self):
+        return unionof(*self.items)
 
-    def getslice(tup, s_start, s_stop):
+    def getslice(self, s_start, s_stop):
         assert s_start.is_immutable_constant(),"tuple slicing: needs constants"
         assert s_stop.is_immutable_constant(), "tuple slicing: needs constants"
-        items = tup.items[s_start.const:s_stop.const]
+        items = self.items[s_start.const:s_stop.const]
         return SomeTuple(items)
 
 
 class __extend__(SomeList):
 
-    def method_append(lst, s_value):
-        lst.listdef.resize()
-        lst.listdef.generalize(s_value)
+    def method_append(self, s_value):
+        self.listdef.resize()
+        self.listdef.generalize(s_value)
 
-    def method_extend(lst, s_iterable):
-        lst.listdef.resize()
+    def method_extend(self, s_iterable):
+        self.listdef.resize()
         if isinstance(s_iterable, SomeList):   # unify the two lists
-            lst.listdef.agree(s_iterable.listdef)
+            self.listdef.agree(s_iterable.listdef)
         else:
             s_iter = s_iterable.iter()
-            lst.method_append(s_iter.next())
+            self.method_append(s_iter.next())
 
-    def method_reverse(lst):
-        lst.listdef.mutate()
+    def method_reverse(self):
+        self.listdef.mutate()
 
-    def method_insert(lst, s_index, s_value):
-        lst.method_append(s_value)
+    def method_insert(self, s_index, s_value):
+        self.method_append(s_value)
 
-    def method_remove(lst, s_value):
-        lst.listdef.resize()
-        lst.listdef.generalize(s_value)
+    def method_remove(self, s_value):
+        self.listdef.resize()
+        self.listdef.generalize(s_value)
 
-    def method_pop(lst, s_index=None):
-        lst.listdef.resize()
-        return lst.listdef.read_item()
+    def method_pop(self, s_index=None):
+        self.listdef.resize()
+        return self.listdef.read_item()
     method_pop.can_only_throw = [IndexError]
 
-    def method_index(lst, s_value):
+    def method_index(self, s_value):
         getbookkeeper().count("list_index")
-        lst.listdef.generalize(s_value)
+        self.listdef.generalize(s_value)
         return SomeInteger(nonneg=True)
 
-    def len(lst):
-        s_item = lst.listdef.read_item()
+    def len(self):
+        s_item = self.listdef.read_item()
         if isinstance(s_item, SomeImpossibleValue):
             return immutablevalue(0)
-        return SomeObject.len(lst)
+        return SomeObject.len(self)
 
-    def iter(lst):
-        return SomeIterator(lst)
+    def iter(self):
+        return SomeIterator(self)
     iter.can_only_throw = []
 
-    def getanyitem(lst):
-        return lst.listdef.read_item()
+    def getanyitem(self):
+        return self.listdef.read_item()
 
-    def op_contains(lst, s_element):
-        lst.listdef.generalize(s_element)
+    def op_contains(self, s_element):
+        self.listdef.generalize(s_element)
         return s_Bool
     op_contains.can_only_throw = []
 
-    def hint(lst, *args_s):
+    def hint(self, *args_s):
         hints = args_s[-1].const
         if 'maxlength' in hints:
             # only for iteration over lists or dicts at the moment,
             # not over an iterator object (because it has no known length)
             s_iterable = args_s[0]
             if isinstance(s_iterable, (SomeList, SomeDict)):
-                lst = SomeList(lst.listdef) # create a fresh copy
-                lst.listdef.resize()
-                lst.listdef.listitem.hint_maxlength = True
+                self = SomeList(self.listdef) # create a fresh copy
+                self.listdef.resize()
+                self.listdef.listitem.hint_maxlength = True
         elif 'fence' in hints:
-            lst = lst.listdef.offspring()
-        return lst
+            self = self.listdef.offspring()
+        return self
 
-    def getslice(lst, s_start, s_stop):
+    def getslice(self, s_start, s_stop):
         check_negative_slice(s_start, s_stop)
-        return lst.listdef.offspring()
+        return self.listdef.offspring()
 
-    def setslice(lst, s_start, s_stop, s_iterable):
+    def setslice(self, s_start, s_stop, s_iterable):
         check_negative_slice(s_start, s_stop)
         if not isinstance(s_iterable, SomeList):
             raise Exception("list[start:stop] = x: x must be a list")
-        lst.listdef.mutate()
-        lst.listdef.agree(s_iterable.listdef)
+        self.listdef.mutate()
+        self.listdef.agree(s_iterable.listdef)
         # note that setslice is not allowed to resize a list in RPython
 
-    def delslice(lst, s_start, s_stop):
+    def delslice(self, s_start, s_stop):
         check_negative_slice(s_start, s_stop)
-        lst.listdef.resize()
+        self.listdef.resize()
 
 def check_negative_slice(s_start, s_stop, error="slicing"):
     if isinstance(s_start, SomeInteger) and not s_start.nonneg:
 
 class __extend__(SomeDict):
 
-    def _is_empty(dct):
-        s_key = dct.dictdef.read_key()
-        s_value = dct.dictdef.read_value()
+    def _is_empty(self):
+        s_key = self.dictdef.read_key()
+        s_value = self.dictdef.read_value()
         return (isinstance(s_key, SomeImpossibleValue) or
                 isinstance(s_value, SomeImpossibleValue))
 
-    def len(dct):
-        if dct._is_empty():
+    def len(self):
+        if self._is_empty():
             return immutablevalue(0)
-        return SomeObject.len(dct)
+        return SomeObject.len(self)
 
-    def iter(dct):
-        return SomeIterator(dct)
+    def iter(self):
+        return SomeIterator(self)
     iter.can_only_throw = []
 
-    def getanyitem(dct, variant='keys'):
+    def getanyitem(self, variant='keys'):
         if variant == 'keys':
-            return dct.dictdef.read_key()
+            return self.dictdef.read_key()
         elif variant == 'values':
-            return dct.dictdef.read_value()
+            return self.dictdef.read_value()
         elif variant == 'items':
-            s_key   = dct.dictdef.read_key()
-            s_value = dct.dictdef.read_value()
+            s_key   = self.dictdef.read_key()
+            s_value = self.dictdef.read_value()
             if (isinstance(s_key, SomeImpossibleValue) or
                 isinstance(s_value, SomeImpossibleValue)):
                 return s_ImpossibleValue
         else:
             raise ValueError
 
-    def method_get(dct, key, dfl):
-        dct.dictdef.generalize_key(key)
-        dct.dictdef.generalize_value(dfl)
-        return dct.dictdef.read_value()
+    def method_get(self, key, dfl):
+        self.dictdef.generalize_key(key)
+        self.dictdef.generalize_value(dfl)
+        return self.dictdef.read_value()
 
     method_setdefault = method_get
 
-    def method_copy(dct):
-        return SomeDict(dct.dictdef)
+    def method_copy(self):
+        return SomeDict(self.dictdef)
 
     def method_update(dct1, dct2):
         if s_None.contains(dct2):
             return SomeImpossibleValue()
         dct1.dictdef.union(dct2.dictdef)
 
-    def method_keys(dct):
-        return getbookkeeper().newlist(dct.dictdef.read_key())
+    def method_keys(self):
+        return getbookkeeper().newlist(self.dictdef.read_key())
 
-    def method_values(dct):
-        return getbookkeeper().newlist(dct.dictdef.read_value())
+    def method_values(self):
+        return getbookkeeper().newlist(self.dictdef.read_value())
 
-    def method_items(dct):
-        return getbookkeeper().newlist(dct.getanyitem('items'))
+    def method_items(self):
+        return getbookkeeper().newlist(self.getanyitem('items'))
 
-    def method_iterkeys(dct):
-        return SomeIterator(dct, 'keys')
+    def method_iterkeys(self):
+        return SomeIterator(self, 'keys')
 
-    def method_itervalues(dct):
-        return SomeIterator(dct, 'values')
+    def method_itervalues(self):
+        return SomeIterator(self, 'values')
 
-    def method_iteritems(dct):
-        return SomeIterator(dct, 'items')
+    def method_iteritems(self):
+        return SomeIterator(self, 'items')
 
-    def method_clear(dct):
+    def method_clear(self):
         pass
 
-    def method_popitem(dct):
-        return dct.getanyitem('items')
+    def method_popitem(self):
+        return self.getanyitem('items')
 
-    def method_pop(dct, s_key, s_dfl=None):
-        dct.dictdef.generalize_key(s_key)
+    def method_pop(self, s_key, s_dfl=None):
+        self.dictdef.generalize_key(s_key)
         if s_dfl is not None:
-            dct.dictdef.generalize_value(s_dfl)
-        return dct.dictdef.read_value()
+            self.dictdef.generalize_value(s_dfl)
+        return self.dictdef.read_value()
 
-    def _can_only_throw(dic, *ignore):
-        if dic.dictdef.dictkey.custom_eq_hash:
+    def _can_only_throw(self, *ignore):
+        if self.dictdef.dictkey.custom_eq_hash:
             return None    # r_dict: can throw anything
         return []          # else: no possible exception
 
-    def op_contains(dct, s_element):
-        dct.dictdef.generalize_key(s_element)
-        if dct._is_empty():
+    def op_contains(self, s_element):
+        self.dictdef.generalize_key(s_element)
+        if self._is_empty():
             s_bool = SomeBool()
             s_bool.const = False
             return s_bool
 class __extend__(SomeString,
                  SomeUnicodeString):
 
-    def method_startswith(str, frag):
-        if str.is_constant() and frag.is_constant():
-            return immutablevalue(str.const.startswith(frag.const))
+    def method_startswith(self, frag):
+        if self.is_constant() and frag.is_constant():
+            return immutablevalue(self.const.startswith(frag.const))
         return s_Bool
 
-    def method_endswith(str, frag):
-        if str.is_constant() and frag.is_constant():
-            return immutablevalue(str.const.endswith(frag.const))
+    def method_endswith(self, frag):
+        if self.is_constant() and frag.is_constant():
+            return immutablevalue(self.const.endswith(frag.const))
         return s_Bool
 
-    def method_find(str, frag, start=None, end=None):
+    def method_find(self, frag, start=None, end=None):
         check_negative_slice(start, end, "find")
         return SomeInteger()
 
-    def method_rfind(str, frag, start=None, end=None):
+    def method_rfind(self, frag, start=None, end=None):
         check_negative_slice(start, end, "rfind")
         return SomeInteger()
 
-    def method_count(str, frag, start=None, end=None):
+    def method_count(self, frag, start=None, end=None):
         check_negative_slice(start, end, "count")
         return SomeInteger(nonneg=True)
 
-    def method_strip(str, chr=None):
-        return str.basestringclass(no_nul=str.no_nul)
+    def method_strip(self, chr=None):
+        return self.basestringclass(no_nul=self.no_nul)
 
-    def method_lstrip(str, chr=None):
-        return str.basestringclass(no_nul=str.no_nul)
+    def method_lstrip(self, chr=None):
+        return self.basestringclass(no_nul=self.no_nul)
 
-    def method_rstrip(str, chr=None):
-        return str.basestringclass(no_nul=str.no_nul)
+    def method_rstrip(self, chr=None):
+        return self.basestringclass(no_nul=self.no_nul)
 
-    def method_join(str, s_list):
+    def method_join(self, s_list):
         if s_None.contains(s_list):
             return SomeImpossibleValue()
-        getbookkeeper().count("str_join", str)
+        getbookkeeper().count("str_join", self)
         s_item = s_list.listdef.read_item()
         if s_None.contains(s_item):
-            if isinstance(str, SomeUnicodeString):
+            if isinstance(self, SomeUnicodeString):
                 return immutablevalue(u"")
             return immutablevalue("")
-        no_nul = str.no_nul and s_item.no_nul
-        return str.basestringclass(no_nul=no_nul)
+        no_nul = self.no_nul and s_item.no_nul
+        return self.basestringclass(no_nul=no_nul)
 
-    def iter(str):
-        return SomeIterator(str)
+    def iter(self):
+        return SomeIterator(self)
     iter.can_only_throw = []
 
-    def getanyitem(str):
-        return str.basecharclass()
+    def getanyitem(self):
+        return self.basecharclass()
 
-    def method_split(str, patt, max=-1):
-        getbookkeeper().count("str_split", str, patt)
+    def method_split(self, patt, max=-1):
+        getbookkeeper().count("str_split", self, patt)
         if max == -1 and patt.is_constant() and patt.const == "\0":
             no_nul = True
         else:
-            no_nul = str.no_nul
-        s_item = str.basestringclass(no_nul=no_nul)
+            no_nul = self.no_nul
+        s_item = self.basestringclass(no_nul=no_nul)
         return getbookkeeper().newlist(s_item)
 
-    def method_rsplit(str, patt, max=-1):
-        getbookkeeper().count("str_rsplit", str, patt)
-        s_item = str.basestringclass(no_nul=str.no_nul)
+    def method_rsplit(self, patt, max=-1):
+        getbookkeeper().count("str_rsplit", self, patt)
+        s_item = self.basestringclass(no_nul=self.no_nul)
         return getbookkeeper().newlist(s_item)
 
-    def method_replace(str, s1, s2):
-        return str.basestringclass(no_nul=str.no_nul and s2.no_nul)
+    def method_replace(self, s1, s2):
+        return self.basestringclass(no_nul=self.no_nul and s2.no_nul)
 
-    def getslice(str, s_start, s_stop):
+    def getslice(self, s_start, s_stop):
         check_negative_slice(s_start, s_stop)
-        result = str.basestringclass(no_nul=str.no_nul)
+        result = self.basestringclass(no_nul=self.no_nul)
         return result
 
-    def op_contains(str, s_element):
+    def op_contains(self, s_element):
         if s_element.is_constant() and s_element.const == "\0":
             r = SomeBool()
             bk = getbookkeeper()
-            op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=str)
+            op = bk._find_current_op(opname="contains", arity=2, pos=0, s_type=self)
             knowntypedata = {}
-            add_knowntypedata(knowntypedata, False, [op.args[0]], str.nonnulify())
+            add_knowntypedata(knowntypedata, False, [op.args[0]], self.nonnulify())
             r.set_knowntypedata(knowntypedata)
             return r
         else:
-            return SomeObject.op_contains(str, s_element)
+            return SomeObject.op_contains(self, s_element)
     op_contains.can_only_throw = []
 
     def method_format(self, *args):
         return SomeByteArray()
 
 class __extend__(SomeUnicodeString):
-    def method_encode(uni, s_enc):
+    def method_encode(self, s_enc):
         if not s_enc.is_constant():
             raise AnnotatorError("Non-constant encoding not supported")
         enc = s_enc.const
 
 
 class __extend__(SomeString):
-    def method_isdigit(str):
+    def method_isdigit(self):
         return s_Bool
 
-    def method_isalpha(str):
+    def method_isalpha(self):
         return s_Bool
 
-    def method_isalnum(str):
+    def method_isalnum(self):
         return s_Bool
 
-    def method_upper(str):
+    def method_upper(self):
         return SomeString()
 
-    def method_lower(str):
+    def method_lower(self):
         return SomeString()
 
-    def method_splitlines(str, s_keep_newlines=None):
-        s_list = getbookkeeper().newlist(str.basestringclass())
+    def method_splitlines(self, s_keep_newlines=None):
+        s_list = getbookkeeper().newlist(self.basestringclass())
         # Force the list to be resizable because ll_splitlines doesn't
         # preallocate the list.
         s_list.listdef.listitem.resize()
         return s_list
 
-    def method_decode(str, s_enc):
+    def method_decode(self, s_enc):
         if not s_enc.is_constant():
             raise AnnotatorError("Non-constant encoding not supported")
         enc = s_enc.const
 
 class __extend__(SomeChar, SomeUnicodeCodePoint):
 
-    def len(chr):
+    def len(self):
         return immutablevalue(1)
 
-    def ord(str):
+    def ord(self):
         return SomeInteger(nonneg=True)
 
 class __extend__(SomeChar):
 
-    def method_isspace(chr):
+    def method_isspace(self):
         return s_Bool
 
-    def method_isalnum(chr):
+    def method_isalnum(self):
         return s_Bool
 
-    def method_islower(chr):
+    def method_islower(self):
         return s_Bool
 
-    def method_isupper(chr):
+    def method_isupper(self):