1. Pypy
  2. Untitled project
  3. pypy

Commits

Manuel Jacob  committed ef1b477 Merge

hg merge py3k

  • Participants
  • Parent commits 2ab9e63, a3fe46f
  • Branches py3k-memoryview

Comments (0)

Files changed (274)

File dotviewer/drawgraph.py

View file
  • Ignore whitespace
     'yellow': (255,255,0),
     }
 re_nonword=re.compile(r'([^0-9a-zA-Z_.]+)')
+re_linewidth=re.compile(r'setlinewidth\((\d+(\.\d*)?|\.\d+)\)')
 
 def combine(color1, color2, alpha):
     r1, g1, b1 = color1
             self.yl = float(yl)
             rest = rest[3:]
         self.style, self.color = rest
+        linematch = re_linewidth.match(self.style)
+        if linematch:
+            num = linematch.group(1)
+            self.linewidth = int(round(float(num)))
+            self.style = self.style[linematch.end(0):]
+        else:
+            self.linewidth = 1
         self.highlight = False
         self.cachedbezierpoints = None
         self.cachedarrowhead = None
                 fgcolor = highlight_color(fgcolor)
             points = [self.map(*xy) for xy in edge.bezierpoints()]
 
-            def drawedgebody(points=points, fgcolor=fgcolor):
-                pygame.draw.lines(self.screen, fgcolor, False, points)
+            def drawedgebody(points=points, fgcolor=fgcolor, width=edge.linewidth):
+                pygame.draw.lines(self.screen, fgcolor, False, points, width)
             edgebodycmd.append(drawedgebody)
 
             points = [self.map(*xy) for xy in edge.arrowhead()]

File dotviewer/graphparse.py

View file
  • Ignore whitespace
         try:
             plaincontent = dot2plain_graphviz(content, contenttype)
         except PlainParseError, e:
-            print e
-            # failed, retry via codespeak
-            plaincontent = dot2plain_codespeak(content, contenttype)
+            raise
+            ##print e
+            ### failed, retry via codespeak
+            ##plaincontent = dot2plain_codespeak(content, contenttype)
     return list(parse_plain(graph_id, plaincontent, links, fixedfont))

File dotviewer/test/test_interactive.py

View file
  • Ignore whitespace
 }
 '''
 
+SOURCE2=r'''digraph f {
+  a; d; e; f; g; h; i; j; k; l;
+  a -> d [penwidth=1, style="setlinewidth(1)"];
+  d -> e [penwidth=2, style="setlinewidth(2)"];
+  e -> f [penwidth=4, style="setlinewidth(4)"];
+  f -> g [penwidth=8, style="setlinewidth(8)"];
+  g -> h [penwidth=16, style="setlinewidth(16)"];
+  h -> i [penwidth=32, style="setlinewidth(32)"];
+  i -> j [penwidth=64, style="setlinewidth(64)"];
+  j -> k [penwidth=128, style="setlinewidth(128)"];
+  k -> l [penwidth=256, style="setlinewidth(256)"];
+}'''
+
+
+
+
+
 def setup_module(mod):
     if not option.pygame:
         py.test.skip("--pygame not enabled")
     page = MyPage(str(dotfile))
     page.fixedfont = True
     graphclient.display_page(page)
+
+def test_linewidth():
+    udir.join("graph2.dot").write(SOURCE2)
+    from dotviewer import graphpage, graphclient
+    dotfile = udir.join('graph2.dot')
+    page = graphpage.DotFileGraphPage(str(dotfile))
+    graphclient.display_page(page)

File lib-python/2.7/socket.py

View file
  • Ignore whitespace
     # All _delegate_methods must also be initialized here.
     send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy
     __getattr__ = _dummy
+    def _drop(self):
+        pass
 
 # Wrapper around platform socket objects. This implements
 # a platform-independent dup() functionality. The
     def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
         if _sock is None:
             _sock = _realsocket(family, type, proto)
-        elif _type(_sock) is _realsocket:
+        else:
+            # PyPy note about refcounting: implemented with _reuse()/_drop()
+            # on the class '_socket.socket'.  Python 3 did it differently
+            # with a reference counter on this class 'socket._socketobject'
+            # instead, but it is a less compatible change.
+            
+            # Note that a few libraries (like eventlet) poke at the
+            # private implementation of socket.py, passing custom
+            # objects to _socketobject().  These libraries need the
+            # following fix for use on PyPy: the custom objects need
+            # methods _reuse() and _drop() that maintains an explicit
+            # reference counter, starting at 0.  When it drops back to
+            # zero, close() must be called.
             _sock._reuse()
-        # PyPy note about refcounting: implemented with _reuse()/_drop()
-        # on the class '_socket.socket'.  Python 3 did it differently
-        # with a reference counter on this class 'socket._socketobject'
-        # instead, but it is a less compatible change (breaks eventlet).
+
         self._sock = _sock
 
     def send(self, data, flags=0):
 
     def close(self):
         s = self._sock
-        if type(s) is _realsocket:
-            s._drop()
         self._sock = _closedsocket()
+        s._drop()
     close.__doc__ = _realsocket.close.__doc__
 
     def accept(self):
                  "_close"]
 
     def __init__(self, sock, mode='rb', bufsize=-1, close=False):
-        if type(sock) is _realsocket:
-            sock._reuse()
+        # Note that a few libraries (like eventlet) poke at the
+        # private implementation of socket.py, passing custom
+        # objects to _fileobject().  These libraries need the
+        # following fix for use on PyPy: the custom objects need
+        # methods _reuse() and _drop() that maintains an explicit
+        # reference counter, starting at 0.  When it drops back to
+        # zero, close() must be called.
+        sock._reuse()
         self._sock = sock
         self.mode = mode # Not actually used in this version
         if bufsize < 0:
                 self.flush()
         finally:
             s = self._sock
-            if type(s) is _realsocket:
+            self._sock = None
+            if s is not None:
                 s._drop()
-            if self._close:
-                self._sock.close()
-            self._sock = None
+                if self._close:
+                    s.close()
 
     def __del__(self):
         try:

File lib-python/2.7/ssl.py

View file
  • Ignore whitespace
                  suppress_ragged_eofs=True, ciphers=None):
         socket.__init__(self, _sock=sock._sock)
 
+        # "close" the original socket: it is not usable any more.
+        # this only calls _drop(), which should not actually call
+        # the operating system's close() because the reference
+        # counter is greater than 1 (we hold one too).
+        sock.close()
+
         if ciphers is None and ssl_version != _SSLv2_IF_EXISTS:
             ciphers = _DEFAULT_CIPHERS
 
         works with the SSL connection.  Just use the code
         from the socket module."""
 
-        self._makefile_refs += 1
         # close=True so as to decrement the reference count when done with
         # the file-like object.
         return _fileobject(self, mode, bufsize, close=True)
 
+    def _reuse(self):
+        self._makefile_refs += 1
+
+    def _drop(self):
+        if self._makefile_refs < 1:
+            self.close()
+        else:
+            self._makefile_refs -= 1
+
 
 
 def wrap_socket(sock, keyfile=None, certfile=None,

File lib-python/2.7/test/test_socket.py

View file
  • Ignore whitespace
         def recv(self, size):
             return self._recv_step.next()()
 
+        def _reuse(self): pass
+        def _drop(self): pass
+
     @staticmethod
     def _raise_eintr():
         raise socket.error(errno.EINTR)
             closed = False
             def flush(self): pass
             def close(self): self.closed = True
-            def _decref_socketios(self): pass
+            def _reuse(self): pass
+            def _drop(self): pass
 
         # must not close unless we request it: the original use of _fileobject
         # by module socket requires that the underlying socket not be closed until

File lib-python/2.7/test/test_urllib2.py

View file
  • Ignore whitespace
         self.reason = reason
     def read(self):
         return ''
+    def _reuse(self): pass
+    def _drop(self): pass
 
 class MockHTTPClass:
     def __init__(self):

File lib-python/2.7/urllib2.py

View file
  • Ignore whitespace
         # out of socket._fileobject() and into a base class.
 
         r.recv = r.read
+        r._reuse = lambda: None
+        r._drop = lambda: None
         fp = socket._fileobject(r, close=True)
 
         resp = addinfourl(fp, r.msg, req.get_full_url())

File lib-python/3/site.py

View file
  • Ignore whitespace
 import builtins
 import traceback
 
+is_pypy = '__pypy__' in sys.builtin_module_names
+
 # Prefixes for site-packages; add additional prefixes like /usr/local here
 PREFIXES = [sys.prefix, sys.exec_prefix]
 # Enable per user site-packages directory
 
         if sys.platform in ('os2emx', 'riscos'):
             sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
+        elif is_pypy:
+            from distutils.sysconfig import get_python_lib
+            sitepackages.append(get_python_lib(standard_lib=False,
+                                               prefix=prefix))
         elif os.sep == '/':
             sitepackages.append(os.path.join(prefix, "lib",
                                         "python" + sys.version[:3],
 
 def setcopyright():
     """Set 'copyright' and 'credits' in builtins"""
+    licenseargs = None
+    if is_pypy:
+        credits = "PyPy is maintained by the PyPy developers: http://pypy.org/"
+        license = "See https://bitbucket.org/pypy/pypy/src/default/LICENSE"
+        licenseargs = (license,)
+    elif sys.platform[:4] == 'java':
+        credits = ("Jython is maintained by the Jython developers "
+                   "(www.jython.org).")
+    else:
+        credits = """\
+    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
+    for supporting Python development.  See www.python.org for more information."""
+
     builtins.copyright = _Printer("copyright", sys.copyright)
-    if sys.platform[:4] == 'java':
-        builtins.credits = _Printer(
-            "credits",
-            "Jython is maintained by the Jython developers (www.jython.org).")
-    else:
-        builtins.credits = _Printer("credits", """\
-    Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
-    for supporting Python development.  See www.python.org for more information.""")
-    here = os.path.dirname(os.__file__)
-    builtins.license = _Printer(
-        "license", "See http://www.python.org/%.3s/license.html" % sys.version,
-        ["LICENSE.txt", "LICENSE"],
-        [os.path.join(here, os.pardir), here, os.curdir])
+    builtins.credits = _Printer("credits", credits)
+    if licenseargs is None:
+        here = os.path.dirname(os.__file__)
+        license = "See http://www.python.org/%.3s/license.html" % sys.version
+        licenseargs = (license, ["LICENSE.txt", "LICENSE"],
+                       [os.path.join(here, os.pardir), here, os.curdir])
+    builtins.license = _Printer("license", *licenseargs)
 
 
 class _Helper(object):

File lib-python/3/test/test_site.py

View file
  • Ignore whitespace
             self.assertEqual(len(dirs), 1)
             wanted = os.path.join('xoxo', 'Lib', 'site-packages')
             self.assertEqual(dirs[0], wanted)
+        elif '__pypy__' in sys.builtin_module_names:
+            self.assertEquals(len(dirs), 1)
+            wanted = os.path.join('xoxo', 'site-packages')
+            self.assertEquals(dirs[0], wanted)
         elif (sys.platform == "darwin" and
             sysconfig.get_config_var("PYTHONFRAMEWORK")):
             # OS X framework builds

File lib_pypy/_curses.py

View file
  • Ignore whitespace
     r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *")
     if lib.color_content(color, r, g, b) == lib.ERR:
         raise error("Argument 1 was out of range. Check value of COLORS.")
-    return (r, g, b)
+    return (r[0], g[0], b[0])
 
 
 def color_pair(n):
         term = ffi.NULL
     err = ffi.new("int *")
     if lib.setupterm(term, fd, err) == lib.ERR:
+        err = err[0]
         if err == 0:
             raise error("setupterm: could not find terminal")
         elif err == -1:

File lib_pypy/_sqlite3.py

  • Ignore whitespace
File contents unchanged.

File lib_pypy/cffi.egg-info

View file
  • Ignore whitespace
 Metadata-Version: 1.0
 Name: cffi
-Version: 0.6
+Version: 0.7
 Summary: Foreign Function Interface for Python calling C code.
 Home-page: http://cffi.readthedocs.org
 Author: Armin Rigo, Maciej Fijalkowski

File lib_pypy/readline.egg-info

View file
  • Ignore whitespace
+Metadata-Version: 1.0
+Name: readline
+Version: 6.2.4.1
+Summary: Hack to make "pip install readline" happy and do nothing
+Home-page: UNKNOWN
+Author: UNKNOWN
+Author-email: UNKNOWN
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN

File pypy/doc/_ref.txt

View file
  • Ignore whitespace
 .. _`rpython/rtyper/memory/gc/hybrid.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/hybrid.py
 .. _`rpython/rtyper/memory/gc/minimarkpage.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/minimarkpage.py
 .. _`rpython/rtyper/memory/gc/semispace.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/memory/gc/semispace.py
-.. _`rpython/rtyper/ootypesystem/`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/
-.. _`rpython/rtyper/ootypesystem/ootype.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/ootypesystem/ootype.py
 .. _`rpython/rtyper/rint.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rint.py
 .. _`rpython/rtyper/rlist.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rlist.py
 .. _`rpython/rtyper/rmodel.py`: https://bitbucket.org/pypy/pypy/src/default/rpython/rtyper/rmodel.py

File pypy/doc/coding-guide.rst

View file
  • Ignore whitespace
 
 + methods and other class attributes do not change after startup
 + single inheritance is fully supported
-+ simple mixins somewhat work too, but the mixed in class needs a
-  ``_mixin_ = True`` class attribute. isinstance checks against the
-  mixin type will fail when translated.
++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class
+  body to copy the whole content of a class `M`.  This can be used
+  to implement mixins: functions and staticmethods are duplicated
+  (the other class attributes are just copied unmodified).
 
 + classes are first-class objects too
 

File pypy/doc/conf.py

View file
  • Ignore whitespace
 # built documents.
 #
 # The short X.Y version.
-version = '2.0'
+version = '2.1'
 # The full version, including alpha/beta/rc tags.
-release = '2.0.2'
+release = '2.1.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

File pypy/doc/cppyy.rst

View file
  • Ignore whitespace
 the selection of scientific software) will also work for a build with the
 builtin backend.
 
-.. _`download`: http://cern.ch/wlav/reflex-2013-04-23.tar.bz2
+.. _`download`: http://cern.ch/wlav/reflex-2013-08-14.tar.bz2
 .. _`ROOT`: http://root.cern.ch/
 
 Besides Reflex, you probably need a version of `gccxml`_ installed, which is
 
 To install the standalone version of Reflex, after download::
 
-    $ tar jxf reflex-2013-04-23.tar.bz2
-    $ cd reflex-2013-04-23
+    $ tar jxf reflex-2013-08-14.tar.bz2
+    $ cd reflex-2013-08-14
     $ ./build/autogen
     $ ./configure <usual set of options such as --prefix>
     $ make && make install

File pypy/doc/getting-started-python.rst

View file
  • Ignore whitespace
      zlib-devel bzip2-devel ncurses-devel expat-devel \
      openssl-devel gc-devel python-sphinx python-greenlet
 
+   On SLES11:
+
+     $ sudo zypper install gcc make python-devel pkg-config \
+     zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
+     libexpat-devel libffi-devel python-curses
+
    The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones.
 
    * ``pkg-config`` (to help us locate libffi files)
 executable. The executable behaves mostly like a normal Python interpreter::
 
     $ ./pypy-c
-    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
-    [PyPy 2.0.0 with GCC 4.7.1] on linux2
+    Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31)
+    [PyPy 2.1.0 with GCC 4.7.1] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``RPython magically makes you rich
     and famous (says so on the tin)''
 the ``bin/pypy`` executable.
 
 To install PyPy system wide on unix-like systems, it is recommended to put the
-whole hierarchy alone (e.g. in ``/opt/pypy2.0``) and put a symlink to the
+whole hierarchy alone (e.g. in ``/opt/pypy2.1``) and put a symlink to the
 ``pypy`` executable into ``/usr/bin`` or ``/usr/local/bin``
 
 If the executable fails to find suitable libraries, it will report

File pypy/doc/getting-started.rst

View file
  • Ignore whitespace
 PyPy is ready to be executed as soon as you unpack the tarball or the zip
 file, with no need to install it in any specific location::
 
-    $ tar xf pypy-2.0.tar.bz2
-    $ ./pypy-2.0/bin/pypy
-    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
-    [PyPy 2.0.0 with GCC 4.7.1] on linux2
+    $ tar xf pypy-2.1.tar.bz2
+    $ ./pypy-2.1/bin/pypy
+    Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31)
+    [PyPy 2.1.0 with GCC 4.4.3] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``PyPy is an exciting technology
     that lets you to write fast, portable, multi-platform interpreters with less
 
     $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
 
-    $ ./pypy-2.0/bin/pypy distribute_setup.py
+    $ ./pypy-2.1/bin/pypy distribute_setup.py
 
-    $ ./pypy-2.0/bin/pypy get-pip.py
+    $ ./pypy-2.1/bin/pypy get-pip.py
 
-    $ ./pypy-2.0/bin/pip install pygments  # for example
+    $ ./pypy-2.1/bin/pip install pygments  # for example
 
-3rd party libraries will be installed in ``pypy-2.0/site-packages``, and
-the scripts in ``pypy-2.0/bin``.
+3rd party libraries will be installed in ``pypy-2.1/site-packages``, and
+the scripts in ``pypy-2.1/bin``.
 
 Installing using virtualenv
 ---------------------------

File pypy/doc/index.rst

View file
  • Ignore whitespace
 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 2.0.2`_: the latest official release
+* `Release 2.1.0`_: 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.0.2`: http://pypy.org/download.html
+.. _`Release 2.1.0`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html

File pypy/doc/jit/index.rst

View file
  • Ignore whitespace
 
 - Hooks_ debugging facilities available to a python programmer
 
+- Virtualizable_ how virtualizables work and what they are (in other words how
+  to make frames more efficient).
 
 .. _Overview: overview.html
 .. _Notes: pyjitpl5.html
 .. _Hooks: ../jit-hooks.html
+.. _Virtualizable: virtualizable.html

File pypy/doc/jit/virtualizable.rst

View file
  • Ignore whitespace
+
+Virtualizables
+==============
+
+**Note:** this document does not have a proper introduction as to how
+to understand the basics. We should write some. If you happen to be here
+and you're missing context, feel free to pester us on IRC.
+
+Problem description
+-------------------
+
+The JIT is very good at making sure some objects are never allocated if they
+don't escape from the trace. Such objects are called ``virtuals``. However,
+if we're dealing with frames, virtuals are often not good enough. Frames
+can escape and they can also be allocated already at the moment we enter the
+JIT. In such cases we need some extra object that can still be optimized away,
+despite existing on the heap.
+
+Solution
+--------
+
+We introduce virtualizables. They're objects that exist on the heap, but their
+fields are not always in sync with whatever happens in the assembler. One
+example is that virtualizable fields can store virtual objects without
+forcing them. This is very useful for frames. Declaring an object to be
+virtualizable works like this:
+
+    class Frame(object):
+       _virtualizable_ = ['locals[*]', 'stackdepth']
+
+And we use them in ``JitDriver`` like this::
+
+    jitdriver = JitDriver(greens=[], reds=['frame'], virtualizables=['frame'])
+
+This declaration means that ``stackdepth`` is a virtualizable **field**, while
+``locals`` is a virtualizable **array** (a list stored on a virtualizable).
+There are various rules about using virtualizables, especially using
+virtualizable arrays that can be very confusing. Those will usually end
+up with a compile-time error (as opposed to strange behavior). The rules are:
+
+* Each array access must be with a known positive index that cannot raise
+  an ``IndexError``. Using ``no = jit.hint(no, promote=True)`` might be useful
+  to get a constant-number access. This is only safe if the index is actually
+  constant or changing rarely within the context of the user's code.
+
+* If you initialize a new virtualizable in the JIT, it has to be done like this
+  (for example if we're in ``Frame.__init__``)::
+
+    self = hint(self, access_directly=True, fresh_virtualizable=True)
+
+  that way you can populate the fields directly.
+
+* If you use virtualizable outside of the JIT – it's very expensive and
+  sometimes aborts tracing. Consider it carefully as to how do it only for
+  debugging purposes and not every time (e.g. ``sys._getframe`` call).
+
+* If you have something equivalent of a Python generator, where the
+  virtualizable survives for longer, you want to force it before returning.
+  It's better to do it that way than by an external call some time later.
+  It's done using ``jit.hint(frame, force_virtualizable=True)``

File pypy/doc/release-2.1.0.rst

View file
  • Ignore whitespace
+============================
+PyPy 2.1 - Considered ARMful
+============================
+
+We're pleased to announce PyPy 2.1, which targets version 2.7.3 of the Python
+language. This is the first release with official support for ARM processors in the JIT.
+This release also contains several bugfixes and performance improvements. 
+
+You can download the PyPy 2.1 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank the `Raspberry Pi Foundation`_ for supporting the work
+to finish PyPy's ARM support.
+
+.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org
+
+The first beta of PyPy3 2.1, targeting version 3 of the Python language, was
+just released, more details can be found `here`_.
+
+.. _`here`: http://morepypy.blogspot.com/2013/07/pypy3-21-beta-1.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.1 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 or Windows
+32. This release also supports ARM machines running Linux 32bit - anything with
+``ARMv6`` (like the Raspberry Pi) or ``ARMv7`` (like the Beagleboard,
+Chromebook, Cubieboard, etc.) that supports ``VFPv3`` should work. Both
+hard-float ``armhf/gnueabihf`` and soft-float ``armel/gnueabi`` builds are
+provided. ``armhf`` builds for Raspbian are created using the Raspberry Pi
+`custom cross-compilation toolchain <https://github.com/raspberrypi>`_
+based on ``gcc-arm-linux-gnueabihf`` and should work on ``ARMv6`` and
+``ARMv7`` devices running Debian or Raspbian. ``armel`` builds are built
+using the ``gcc-arm-linux-gnuebi`` toolchain provided by Ubuntu and
+currently target ``ARMv7``.
+
+Windows 64 work is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.1 and cpython 2.7.2`: http://speed.pypy.org
+
+Highlights
+==========
+
+* JIT support for ARM, architecture versions 6 and 7, hard- and soft-float ABI
+
+* Stacklet support for ARM
+
+* Support for os.statvfs and os.fstatvfs on unix systems
+
+* Improved logging performance
+
+* Faster sets for objects
+
+* Interpreter improvements
+
+* During packaging, compile the CFFI based TK extension
+
+* Pickling of numpy arrays and dtypes 
+
+* Subarrays for numpy
+
+* Bugfixes to numpy
+
+* Bugfixes to cffi and ctypes
+
+* Bugfixes to the x86 stacklet support
+
+* Fixed issue `1533`_: fix an RPython-level OverflowError for space.float_w(w_big_long_number). 
+
+* Fixed issue `1552`_: GreenletExit should inherit from BaseException.
+
+* Fixed issue `1537`_: numpypy __array_interface__
+  
+* Fixed issue `1238`_: Writing to an SSL socket in PyPy sometimes failed with a "bad write retry" message.
+
+.. _`1533`: https://bugs.pypy.org/issue1533
+.. _`1552`: https://bugs.pypy.org/issue1552
+.. _`1537`: https://bugs.pypy.org/issue1537
+.. _`1238`: https://bugs.pypy.org/issue1238
+
+Cheers,
+
+David Schneider for the PyPy team.

File pypy/doc/whatsnew-head.rst

View file
  • Ignore whitespace
 .. branch: fast-slowpath
 Added an abstraction for functions with a fast and slow path in the JIT. This
 speeds up list.append() and list.pop().
+
+.. branch: curses_fixes
+
+.. branch: foldable-getarrayitem-indexerror
+Constant-fold reading out of constant tuples in PyPy.
+
+.. branch: mro-reorder-numpypy-str
+No longer delegate numpy string_ methods to space.StringObject, in numpy
+this works by kind of by accident. Support for merging the refactor-str-types
+branch
+
+.. branch: kill-typesystem
+Remove the "type system" abstraction, now that there is only ever one kind of
+type system used.
+
+.. branch: kill-gen-store-back-in
+Kills gen_store_back_in_virtualizable - should improve non-inlined calls by
+a bit
+
+.. branch: dotviewer-linewidth
+.. branch: reflex-support
+.. branch: numpypy-inplace-op
+.. branch: rewritten-loop-logging

File pypy/doc/windows.rst

View file
  • Ignore whitespace
 The following text gives some hints about how to translate the PyPy
 interpreter.
 
+PyPy supports only being translated as a 32bit program, even on
+64bit Windows.  See at the end of this page for what is missing
+for a full 64bit translation.
+
 To build pypy-c you need a C compiler.  Microsoft Visual Studio is
 preferred, but can also use the mingw32 port of gcc.
 
 INCLUDE, LIB and PATH (for DLLs) environment variables appropriately.
 
 Abridged method (for -Ojit builds using Visual Studio 2008)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Download the versions of all the external packages
 from 
 https://bitbucket.org/pypy/pypy/downloads/local.zip
     nmake -f makefile.msc
     
 The sqlite3 database library
-~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract
 it into a directory under the base directory. Also get 
 http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll
 into the bin directory, and the sqlite3.def into the sources directory.
 Now build the import library so cffi can use the header and dll::
+
     lib /DEF:sqlite3.def" /OUT:sqlite3.lib"
     copy sqlite3.lib path\to\libs
 
 March 2012, --cc is not a valid option for pytest.py. However if you set an
 environment variable CC to the compliter exe, testing will use it.
 
-.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
+.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
 .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds
 .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29   
 .. _`libffi source files`: http://sourceware.org/libffi/
 .. _`RPython translation toolchain`: translation.html
+
+
+What is missing for a full 64-bit translation
+---------------------------------------------
+
+The main blocker is that we assume that the integer type of RPython is
+large enough to (occasionally) contain a pointer value cast to an
+integer.  The simplest fix is to make sure that it is so, but it will
+give the following incompatibility between CPython and PyPy on Win64:
+  
+CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1``
+
+PyPy: ``sys.maxint == sys.maxsize == 2**64-1``
+
+...and, correspondingly, PyPy supports ints up to the larger value of
+sys.maxint before they are converted to ``long``.  The first decision
+that someone needs to make is if this incompatibility is reasonable.
+
+Assuming that it is, the first thing to do is probably to hack *CPython*
+until it fits this model: replace the field in PyIntObject with a ``long
+long`` field, and change the value of ``sys.maxint``.  This might just
+work, even if half-brokenly: I'm sure you can crash it because of the
+precision loss that undoubtedly occurs everywhere, but try not to. :-)
+
+Such a hacked CPython is what you'll use in the next steps.  We'll call
+it CPython64/64.
+
+It is probably not too much work if the goal is only to get a translated
+PyPy executable, and to run all tests before transaction.  But you need
+to start somewhere, and you should start with some tests in
+rpython/translator/c/test/, like ``test_standalone.py`` and
+``test_newgc.py``: try to have them pass on top of CPython64/64.
+
+Keep in mind that this runs small translations, and some details may go
+wrong.  The most obvious one is to check that it produces C files that
+use the integer type ``Signed`` --- but what is ``Signed`` defined to?
+It should be equal to ``long`` on every other platforms, but on Win64 it
+should be something like ``long long``.
+
+What is more generally needed is to review all the C files in
+rpython/translator/c/src for the word ``long``, because this means a
+32-bit integer even on Win64.  Replace it with ``Signed`` most of the
+times.  You can replace one with the other without breaking anything on
+any other platform, so feel free to.
+
+Then, these two C types have corresponding RPython types: ``rffi.LONG``
+and ``lltype.Signed`` respectively.  The first should really correspond
+to the C ``long``.  Add tests that check that integers casted to one
+type or the other really have 32 and 64 bits respectively, on Win64.
+
+Once these basic tests work, you need to review ``rpython/rlib/`` for
+usages of ``rffi.LONG`` versus ``lltype.Signed``.  The goal would be to
+fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as
+always run on top of CPython64/64.  Note that there was some early work
+done in ``rpython/rlib/rarithmetic`` with the goal of running all the
+tests on Win64 on the regular CPython, but I think by now that it's a
+bad idea.  Look only at CPython64/64.
+
+The major intermediate goal is to get a translation of PyPy with ``-O2``
+with a minimal set of modules, starting with ``--no-allworkingmodules``;
+you need to use CPython64/64 to run this translation too.  Check
+carefully the warnings of the C compiler at the end.  I think that MSVC
+is "nice" in the sense that by default a lot of mismatches of integer
+sizes are reported as warnings.
+
+Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed``
+issues.  At some time during this review, we get a working translated
+PyPy on Windows 64 that includes all ``--translationmodules``, i.e.
+everything needed to run translations.  When we are there, the hacked
+CPython64/64 becomes much less important, because we can run future
+translations on top of this translated PyPy.  As soon as we get there,
+please *distribute* the translated PyPy.  It's an essential component
+for anyone else that wants to work on Win64!  We end up with a strange
+kind of dependency --- we need a translated PyPy in order to translate a
+PyPy ---, but I believe it's ok here, as Windows executables are
+supposed to never be broken by newer versions of Windows.
+
+Happy hacking :-)

File pypy/interpreter/app_main.py

View file
  • Ignore whitespace
     except BaseException as e:
         try:
             stderr = sys.stderr
-        except AttributeError:
-            pass   # too bad
-        else:
             print('Error calling sys.excepthook:', file=stderr)
             originalexcepthook(type(e), e, e.__traceback__)
             print(file=stderr)
             print('Original exception was:', file=stderr)
+        except:
+            pass   # too bad
 
     # we only get here if sys.excepthook didn't do its job
     originalexcepthook(etype, evalue, etraceback)

File pypy/interpreter/astcompiler/astbuilder.py

View file
  • Ignore whitespace
 from pypy.interpreter.pyparser.pygram import syms, tokens
 from pypy.interpreter.pyparser.error import SyntaxError
 from pypy.interpreter.pyparser import parsestring
-from rpython.rlib.objectmodel import specialize
 
 
 def ast_from_node(space, node, compile_info):
             return self.handle_genexp(gexp_node)
         return self.handle_testlist(gexp_node)
 
-    def count_comp_fors(self, comp_node, for_type, if_type):
+    def count_comp_fors(self, comp_node):
         count = 0
         current_for = comp_node
         while True:
                 return count
             while True:
                 first_child = current_iter.children[0]
-                if first_child.type == for_type:
+                if first_child.type == syms.comp_for:
                     current_for = current_iter.children[0]
                     break
-                elif first_child.type == if_type:
+                elif first_child.type == syms.comp_if:
                     if len(first_child.children) == 3:
                         current_iter = first_child.children[2]
                     else:
                 else:
                     raise AssertionError("should not reach here")
 
-    def count_comp_ifs(self, iter_node, for_type):
+    def count_comp_ifs(self, iter_node):
         count = 0
         while True:
             first_child = iter_node.children[0]
-            if first_child.type == for_type:
+            if first_child.type == syms.comp_for:
                 return count
             count += 1
             if len(first_child.children) == 2:
                 return count
             iter_node = first_child.children[2]
 
-    @specialize.arg(2)
-    def comprehension_helper(self, comp_node,
-                             handle_source_expr_meth="handle_expr",
-                             for_type=syms.comp_for, if_type=syms.comp_if,
-                             iter_type=syms.comp_iter,
-                             comp_fix_unamed_tuple_location=False):
-        handle_source_expression = getattr(self, handle_source_expr_meth)
-        fors_count = self.count_comp_fors(comp_node, for_type, if_type)
+    def comprehension_helper(self, comp_node):
+        fors_count = self.count_comp_fors(comp_node)
         comps = []
         for i in range(fors_count):
             for_node = comp_node.children[1]
             for_targets = self.handle_exprlist(for_node, ast.Store)
-            expr = handle_source_expression(comp_node.children[3])
+            expr = self.handle_expr(comp_node.children[3])
             assert isinstance(expr, ast.expr)
             if len(for_node.children) == 1:
                 comp = ast.comprehension(for_targets[0], expr, None)
             else:
-                col = comp_node.column
-                line = comp_node.lineno
                 # Modified in python2.7, see http://bugs.python.org/issue6704
-                if comp_fix_unamed_tuple_location:
-                    expr_node = for_targets[0]
-                    assert isinstance(expr_node, ast.expr)
-                    col = expr_node.col_offset
-                    line = expr_node.lineno
+                # Fixing unamed tuple location
+                expr_node = for_targets[0]
+                assert isinstance(expr_node, ast.expr)
+                col = expr_node.col_offset
+                line = expr_node.lineno
                 target = ast.Tuple(for_targets, ast.Store, line, col)
                 comp = ast.comprehension(target, expr, None)
             if len(comp_node.children) == 5:
                 comp_node = comp_iter = comp_node.children[4]
-                assert comp_iter.type == iter_type
-                ifs_count = self.count_comp_ifs(comp_iter, for_type)
+                assert comp_iter.type == syms.comp_iter
+                ifs_count = self.count_comp_ifs(comp_iter)
                 if ifs_count:
                     ifs = []
                     for j in range(ifs_count):
                         if len(comp_if.children) == 3:
                             comp_node = comp_iter = comp_if.children[2]
                     comp.ifs = ifs
-                if comp_node.type == iter_type:
+                if comp_node.type == syms.comp_iter:
                     comp_node = comp_node.children[0]
             assert isinstance(comp, ast.comprehension)
             comps.append(comp)
 
     def handle_genexp(self, genexp_node):
         elt = self.handle_expr(genexp_node.children[0])
-        comps = self.comprehension_helper(genexp_node.children[1],
-                                          comp_fix_unamed_tuple_location=True)
+        comps = self.comprehension_helper(genexp_node.children[1])
         return ast.GeneratorExp(elt, comps, genexp_node.lineno,
                                 genexp_node.column)
 
     def handle_listcomp(self, listcomp_node):
         elt = self.handle_expr(listcomp_node.children[0])
-        comps = self.comprehension_helper(listcomp_node.children[1],
-                                          "handle_testlist",
-                                          syms.comp_for, syms.comp_if,
-                                          syms.comp_iter,
-                                          comp_fix_unamed_tuple_location=True)
+        comps = self.comprehension_helper(listcomp_node.children[1])
         return ast.ListComp(elt, comps, listcomp_node.lineno,
                             listcomp_node.column)
 
     def handle_setcomp(self, set_maker):
         elt = self.handle_expr(set_maker.children[0])
-        comps = self.comprehension_helper(set_maker.children[1],
-                                          comp_fix_unamed_tuple_location=True)
-        return ast.SetComp(elt, comps, set_maker.lineno, set_maker.column)
+        comps = self.comprehension_helper(set_maker.children[1])
+        return ast.SetComp(elt, comps, set_maker.lineno,
+                           set_maker.column)
 
     def handle_dictcomp(self, dict_maker):
         key = self.handle_expr(dict_maker.children[0])
         value = self.handle_expr(dict_maker.children[2])
-        comps = self.comprehension_helper(dict_maker.children[3],
-                                          comp_fix_unamed_tuple_location=True)
+        comps = self.comprehension_helper(dict_maker.children[3])
         return ast.DictComp(key, value, comps, dict_maker.lineno,
                             dict_maker.column)
 

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

View file
  • Ignore whitespace
         if1, if2 = comps[0].ifs
         assert isinstance(if1, ast.Name)
         assert isinstance(if2, ast.Name)
+        gen = self.get_first_expr(brack("x for x in y or z"))
+        comp = gen.generators[0]
+        assert isinstance(comp.iter, ast.BoolOp)
+        assert len(comp.iter.values) == 2
+        assert isinstance(comp.iter.values[0], ast.Name)
+        assert isinstance(comp.iter.values[1], ast.Name)
 
     def test_genexp(self):
         self.check_comprehension("(%s)", ast.GeneratorExp)

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

View file
  • Ignore whitespace
                              None).value
         assert exc.msg == "too many expressions in star-unpacking assignment"
 
+    def test_list_compr_or(self):
+        yield self.st, 'x = list(d for d in [1] or [])', 'x', [1]
+        yield self.st, 'y = [d for d in [1] or []]', 'y', [1]
+
 
 class AppTestCompiler:
 

File pypy/interpreter/buffer.py

View file
  • Ignore whitespace
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import compute_hash
+from rpython.rlib.objectmodel import compute_hash, import_from_mixin
 from rpython.rlib.rstring import StringBuilder
 
 
 # ____________________________________________________________
 
 class SubBufferMixin(object):
-    _mixin_ = True
-
     def __init__(self, buffer, offset, size, format, itemsize):
         self.buffer = buffer
         self.offset = offset
                           # out of bounds
         return self.buffer.getslice(self.offset + start, self.offset + stop, step, size)
 
-class SubBuffer(SubBufferMixin, Buffer):
-    pass
+class SubBuffer(Buffer):
+    import_from_mixin(SubBufferMixin)
 
-class RWSubBuffer(SubBufferMixin, RWBuffer):
+class RWSubBuffer(RWBuffer):
+    import_from_mixin(SubBufferMixin)
 
     def setitem(self, index, char):
         self.buffer.setitem(self.offset + index, char)

File pypy/interpreter/generator.py

  • Ignore whitespace
File contents unchanged.

File pypy/interpreter/pycode.py

  • Ignore whitespace
File contents unchanged.

File pypy/interpreter/pyframe.py

View file
  • Ignore whitespace
         # CO_OPTIMIZED: no locals dict needed at all
         # NB: this method is overridden in nestedscope.py
         flags = code.co_flags
-        if flags & pycode.CO_OPTIMIZED: 
-            return 
+        if flags & pycode.CO_OPTIMIZED:
+            return
         if flags & pycode.CO_NEWLOCALS:
             self.w_locals = self.space.newdict(module=True)
         else:
                 executioncontext.return_trace(self, self.space.w_None)
                 raise
             executioncontext.return_trace(self, w_exitvalue)
-            # clean up the exception, might be useful for not
-            # allocating exception objects in some cases
-            # if it's a generator, we have to preserve the exception state
-            if not self.is_generator():
-                self.last_exception = None
+            # it used to say self.last_exception = None
+            # this is now done by the code in pypyjit module
+            # since we don't want to invalidate the virtualizable
+            # for no good reason
             got_exception = False
         finally:
             executioncontext.leave(self, w_exitvalue, got_exception)
                 break
             w_value = self.peekvalue(delta)
             self.pushvalue(w_value)
-        
+
     def peekvalue(self, index_from_top=0):
         # NOTE: top of the stack is peekvalue(0).
         # Contrast this with CPython where it's PEEK(-1).
         nlocals = self.pycode.co_nlocals
         values_w = self.locals_stack_w[nlocals:self.valuestackdepth]
         w_valuestack = maker.slp_into_tuple_with_nulls(space, values_w)
-        
+
         w_blockstack = nt([block._get_state_(space) for block in self.get_blocklist()])
         w_fastlocals = maker.slp_into_tuple_with_nulls(
             space, self.locals_stack_w[:nlocals])
         else:
             w_exc_value = self.last_exception.get_w_value(space)
             w_tb = w(self.last_exception.get_traceback())
-        
+
         tup_state = [
             w(self.f_backref()),
             w(self.get_builtin()),
             w(f_lineno),
             w_fastlocals,
             space.w_None,           #XXX placeholder for f_locals
-            
+
             #f_restricted requires no additional data!
             space.w_None, ## self.w_f_trace,  ignore for now
 
             ncellvars = len(pycode.co_cellvars)
             cellvars = cells[:ncellvars]
             closure = cells[ncellvars:]
-        
+
         # do not use the instance's __init__ but the base's, because we set
         # everything like cells from here
         # XXX hack
 
     ### line numbers ###
 
-    def fget_f_lineno(self, space): 
+    def fget_f_lineno(self, space):
         "Returns the line number of the instruction currently being executed."
         if self.w_f_trace is None:
             return space.wrap(self.get_last_lineno())
         except OperationError, e:
             raise OperationError(space.w_ValueError,
                                  space.wrap("lineno must be an integer"))
-            
+
         if self.w_f_trace is None:
             raise OperationError(space.w_ValueError,
                   space.wrap("f_lineno can only be set by a trace function."))
         if ord(code[new_lasti]) in (DUP_TOP, POP_TOP):
             raise OperationError(space.w_ValueError,
                   space.wrap("can't jump to 'except' line as there's no exception"))
-            
+
         # Don't jump into or out of a finally block.
         f_lasti_setup_addr = -1
         new_lasti_setup_addr = -1
                         if addr == self.last_instr:
                             f_lasti_setup_addr = setup_addr
                         break
-                    
+
             if op >= HAVE_ARGUMENT:
                 addr += 3
             else:
                 addr += 1
-                
+
         assert len(blockstack) == 0
 
         if new_lasti_setup_addr != f_lasti_setup_addr:
             block = self.pop_block()
             block.cleanup(self)
             f_iblock -= 1
-            
+
         self.f_lineno = new_lineno
         self.last_instr = new_lasti
-            
+
     def get_last_lineno(self):
         "Returns the line number of the instruction currently being executed."
         return pytraceback.offset2lineno(self.pycode, self.last_instr)
             self.f_lineno = self.get_last_lineno()
             space.frame_trace_action.fire()
 
-    def fdel_f_trace(self, space): 
-        self.w_f_trace = None 
+    def fdel_f_trace(self, space):
+        self.w_f_trace = None
 
     def fget_f_exc_type(self, space):
         if self.last_exception is not None:
             if f is not None:
                 return f.last_exception.w_type
         return space.w_None
-         
+
     def fget_f_exc_value(self, space):
         if self.last_exception is not None:
             f = self.f_backref()
             if f is not None:
                 return space.wrap(f.last_exception.get_traceback())
         return space.w_None
-         
+
     def fget_f_restricted(self, space):
         if space.config.objspace.honor__builtins__:
             return space.wrap(self.builtin is not space.builtin)

File pypy/interpreter/typedef.py

View file
  • Ignore whitespace
                     instance=True)
                 base_user_setup(self, space, w_subtype)
 
-            def setclass(self, space, w_subtype):
-                # only used by descr_set___class__
-                self.w__class__ = w_subtype
-
         add(Proto)
 
     subcls = type(name, (supercls,), body)

File pypy/module/__pypy__/test/test_signal.py

View file
  • Ignore whitespace
         import __pypy__, _thread, signal, time, sys
 
         def subthread():
+            print('subthread started')
             try:
                 with __pypy__.thread.signals_enabled:
                     _thread.interrupt_main()
                     for i in range(10):
                         print('x')
-                        time.sleep(0.1)
+                        time.sleep(0.25)
             except BaseException as e:
                 interrupted.append(e)
             finally:
+                print('subthread stops, interrupted=%r' % (interrupted,))
                 done.append(None)
 
         # This is normally called by app_main.py
             try:
                 done = []
                 interrupted = []
+                print('--- start ---')
                 _thread.start_new_thread(subthread, ())
                 for j in range(10):
                     if len(done): break
                     print('.')
-                    time.sleep(0.1)
+                    time.sleep(0.25)
+                print('main thread loop done')
                 assert len(done) == 1
                 assert len(interrupted) == 1
                 assert 'KeyboardInterrupt' in interrupted[0].__class__.__name__
 
         def subthread():
             try:
-                time.sleep(0.25)
+                time.sleep(0.5)
                 with __pypy__.thread.signals_enabled:
                     _thread.interrupt_main()
             except BaseException as e:

File pypy/module/array/interp_array.py

View file
  • Ignore whitespace
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.objectmodel import keepalive_until_here
 from rpython.rtyper.lltypesystem import lltype, rffi
-
+from pypy.objspace.std.floatobject import W_FloatObject
 
 @unwrap_spec(typecode=str)
 def w_array(space, w_cls, typecode, __args__):
 def descr_typecode(space, self):
     return space.wrap(self.typecode)
 
-arr_eq_driver = jit.JitDriver(greens = ['comp_func'], reds = 'auto')
+arr_eq_driver = jit.JitDriver(name='array_eq_driver', greens = ['comp_func'], reds = 'auto')
 EQ, NE, LT, LE, GT, GE = range(6)
 
 def compare_arrays(space, arr1, arr2, comp_op):
 
 
 class TypeCode(object):
-    def __init__(self, itemtype, unwrap, canoverflow=False, signed=False):
+    def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'):
         self.itemtype = itemtype
         self.bytes = rffi.sizeof(itemtype)
         self.arraytype = lltype.Array(itemtype, hints={'nolength': True})
         self.signed = signed
         self.canoverflow = canoverflow
         self.w_class = None
+        self.method = method
 
         if self.canoverflow:
             assert self.bytes <= rffi.sizeof(rffi.ULONG)
 
 
 types = {
-    'u': TypeCode(lltype.UniChar,     'unicode_w'),
+    'u': TypeCode(lltype.UniChar,     'unicode_w', method=''),
     'b': TypeCode(rffi.SIGNEDCHAR,    'int_w', True, True),
     'B': TypeCode(rffi.UCHAR,         'int_w', True),
     'h': TypeCode(rffi.SHORT,         'int_w', True, True),
                                                     # rbigint.touint() which
                                                     # corresponds to the
                                                     # C-type unsigned long
-    'f': TypeCode(lltype.SingleFloat, 'float_w'),
-    'd': TypeCode(lltype.Float,       'float_w'),
+    'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'),
+    'd': TypeCode(lltype.Float,       'float_w', method='__float__'),
     }
 for k, v in types.items():
     v.typecode = k
         def item_w(self, w_item):
             space = self.space
             unwrap = getattr(space, mytype.unwrap)
-            item = unwrap(w_item)
+            try:
+                item = unwrap(w_item)
+            except OperationError, e:
+                if isinstance(w_item, W_FloatObject): # Odd special case from cpython
+                    raise
+                if mytype.method != '' and e.match(space, space.w_TypeError):
+                    try:
+                        item = unwrap(space.call_method(w_item, mytype.method))
+                    except OperationError:
+                        msg = 'array item must be ' + mytype.unwrap[:-2]
+                        raise OperationError(space.w_TypeError, space.wrap(msg))                        
+                else:
+                    raise
             if mytype.unwrap == 'bigint_w':
                 try:
                     item = item.touint()

File pypy/module/array/test/test_array.py

View file
  • Ignore whitespace
         assert l
         assert l[0] is None or len(l[0]) == 0
 
+    def test_assign_object_with_special_methods(self):
+        from array import array
+        
+        class Num(object):
+            def __float__(self):
+                return 5.25
+                
+            def __int__(self):
+                return 7
+                
+        class NotNum(object):
+            pass
+        
+        class Silly(object):
+            def __float__(self):
+                return None
+                
+            def __int__(self):
+                return None         
+
+        class OldNum:
+            def __float__(self):
+                return 6.25
+                
+            def __int__(self):
+                return 8
+                
+        class OldNotNum:
+            pass
+        
+        class OldSilly:
+            def __float__(self):
+                return None
+                
+            def __int__(self):
+                return None
+                
+        for tc in 'bBhHiIlL':
+            a = array(tc, [0])
+            raises(TypeError, a.__setitem__, 0, 1.0)
+            a[0] = 1
+            a[0] = Num()
+            assert a[0] == 7
+            raises(TypeError, a.__setitem__, NotNum())
+            a[0] = OldNum()
+            assert a[0] == 8
+            raises(TypeError, a.__setitem__, OldNotNum())
+            raises(TypeError, a.__setitem__, Silly())
+            raises(TypeError, a.__setitem__, OldSilly())
+
+        for tc in 'fd':
+            a = array(tc, [0])
+            a[0] = 1.0
+            a[0] = 1
+            a[0] = Num()        
+            assert a[0] == 5.25
+            raises(TypeError, a.__setitem__, NotNum())
+            a[0] = OldNum()
+            assert a[0] == 6.25
+            raises(TypeError, a.__setitem__, OldNotNum())
+            raises(TypeError, a.__setitem__, Silly())
+            raises(TypeError, a.__setitem__, OldSilly())
+            
+        a = array('u', 'hi')
+        a[0] = 'b'
+        assert a[0] == 'b'
+        
     def test_bytearray(self):
         a = self.array('u', 'hi')
         b = self.array('u')

File pypy/module/binascii/interp_uu.py

View file
  • Ignore whitespace
         return ord(bin[i])
     except IndexError:
         return 0
-_a2b_read._always_inline_ = True
+_b2a_read._always_inline_ = True
 
 @unwrap_spec(bin='bufferstr')
 def b2a_uu(space, bin):

File pypy/module/cppyy/genreflex-methptrgetter.patch

View file
  • Ignore whitespace
      # The next is to avoid a known problem with gccxml that it generates a
      # references to id equal '_0' which is not defined anywhere
      self.xref['_0'] = {'elem':'Unknown', 'attrs':{'id':'_0','name':''}, 'subelems':[]}
-@@ -1306,6 +1307,8 @@
+@@ -1328,6 +1329,8 @@
      bases = self.getBases( attrs['id'] )
      if inner and attrs.has_key('demangled') and self.isUnnamedType(attrs['demangled']) :
        cls = attrs['demangled']
        clt = ''
      else:
        cls = self.genTypeName(attrs['id'],const=True,colon=True)
-@@ -1343,7 +1346,7 @@
+@@ -1365,7 +1368,7 @@
        # Inner class/struct/union/enum.
        for m in memList :
          member = self.xref[m]
             and member['attrs'].get('access') in ('private','protected') \
             and not self.isUnnamedType(member['attrs'].get('demangled')):
            cmem = self.genTypeName(member['attrs']['id'],const=True,colon=True)
-@@ -1981,8 +1984,15 @@
+@@ -2003,8 +2006,15 @@
      else    : params  = '0'
      s = '  .AddFunctionMember(%s, Reflex::Literal("%s"), %s%s, 0, %s, %s)' % (self.genTypeID(id), name, type, id, params, mod)
      s += self.genCommentProperty(attrs)
    def genMCODef(self, type, name, attrs, args):
      id       = attrs['id']
      cl       = self.genTypeName(attrs['context'],colon=True)
-@@ -2049,8 +2059,44 @@
+@@ -2071,8 +2081,44 @@
            if returns == 'void' : body += '  }\n'
            else :                 body += '  }\n'
      body += '}\n'
        -h, --help
           Print this help\n
       """ 
-@@ -127,7 +131,8 @@
-       opts, args = getopt.getopt(options, 'ho:s:c:I:U:D:PC', \
+@@ -128,7 +132,7 @@
        ['help','debug=', 'output=','selection_file=','pool','dataonly','interpreteronly','deep','gccxmlpath=',
         'capabilities=','rootmap=','rootmap-lib=','comme