[pypy-commit] pypy improve-docs: hg merge default: probably the most annoying merge I ever did.

Manuel Jacob noreply at buildbot.pypy.org
Mon Aug 26 02:48:33 CEST 2013


Author: Manuel Jacob
Branch: improve-docs
Changeset: r66314:60f07e7ea8cd
Date: 2013-08-26 01:49 +0100
http://bitbucket.org/pypy/pypy/changeset/60f07e7ea8cd/

Log:	hg merge default: probably the most annoying merge I ever did.

diff too long, truncating to 2000 out of 80816 lines

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -6,6 +6,7 @@
 .idea
 .project
 .pydevproject
+__pycache__
 
 syntax: regexp
 ^testresult$
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -3,3 +3,6 @@
 d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6
 ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7
 07e08e9c885ca67d89bcc304e45a32346daea2fa release-2.0-beta-1
+9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
+9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
+ab0dd631c22015ed88e583d9fdd4c43eebf0be21 pypy-2.1-beta1-arm
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -2,9 +2,9 @@
 =======
 
 Except when otherwise stated (look for LICENSE files in directories or
-information at the beginning of each file) all software and
-documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo',
-and 'lib_pypy' directories is licensed as follows: 
+information at the beginning of each file) all software and documentation in
+the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', and 'lib_pypy'
+directories is licensed as follows: 
 
     The MIT License
 
@@ -38,176 +38,239 @@
     Armin Rigo
     Maciej Fijalkowski
     Carl Friedrich Bolz
+    Antonio Cuni
     Amaury Forgeot d'Arc
-    Antonio Cuni
     Samuele Pedroni
+    Alex Gaynor
     Michael Hudson
+    David Schneider
     Holger Krekel
-    Alex Gaynor
     Christian Tismer
     Hakan Ardo
     Benjamin Peterson
-    David Schneider
+    Matti Picus
+    Philip Jenvey
+    Anders Chrigstrom
+    Brian Kearns
     Eric van Riet Paap
-    Anders Chrigstrom
     Richard Emslie
+    Alexander Schremmer
+    Wim Lavrijsen
     Dan Villiom Podlaski Christiansen
-    Alexander Schremmer
+    Manuel Jacob
     Lukas Diekmann
+    Sven Hager
+    Anders Lehmann
     Aurelien Campeas
-    Anders Lehmann
+    Niklaus Haldimann
+    Ronan Lamy
     Camillo Bruni
-    Niklaus Haldimann
-    Sven Hager
+    Laura Creighton
+    Toon Verwaest
     Leonardo Santagada
-    Toon Verwaest
     Seo Sanghyeon
     Justin Peel
+    Ronny Pfannschmidt
+    David Edelsohn
+    Anders Hammarquist
+    Jakub Gustak
+    Guido Wesdorp
     Lawrence Oluyede
     Bartosz Skowron
-    Jakub Gustak
-    Guido Wesdorp
     Daniel Roberts
-    Laura Creighton
+    Niko Matsakis
     Adrien Di Mascio
     Ludovic Aubry
-    Niko Matsakis
-    Wim Lavrijsen
-    Matti Picus
+    Alexander Hesse
+    Jacob Hallen
+    Romain Guillebert
     Jason Creighton
-    Jacob Hallen
     Alex Martelli
-    Anders Hammarquist
+    Michal Bendowski
     Jan de Mooij
+    Michael Foord
     Stephan Diehl
-    Michael Foord
     Stefan Schwarzer
+    Valentino Volonghi
     Tomek Meka
     Patrick Maupin
+    stian
     Bob Ippolito
     Bruno Gola
+    Jean-Paul Calderone
+    Timo Paulssen
     Alexandre Fayolle
+    Simon Burton
     Marius Gedminas
-    Simon Burton
-    David Edelsohn
-    Jean-Paul Calderone
     John Witulski
-    Timo Paulssen
-    holger krekel
+    Greg Price
     Dario Bertini
     Mark Pearse
+    Simon Cross
+    Konstantin Lopuhin
     Andreas Stührk
     Jean-Philippe St. Pierre
     Guido van Rossum
     Pavel Vinogradov
-    Valentino Volonghi
     Paul deGrandis
     Ilya Osadchiy
-    Ronny Pfannschmidt
     Adrian Kuhn
+    Boris Feigin
     tav
     Georg Brandl
-    Philip Jenvey
+    Bert Freudenberg
+    Stian Andreassen
+    Stefano Rivera
+    Wanja Saatkamp
     Gerald Klix
-    Wanja Saatkamp
-    Boris Feigin
+    Mike Blume
+    Taavi Burns
     Oscar Nierstrasz
     David Malcolm
     Eugene Oden
     Henry Mason
+    Preston Timmons
     Jeff Terrace
+    David Ripton
+    Dusty Phillips
     Lukas Renggli
     Guenter Jantzen
+    Tobias Oberstein
+    Remi Meier
     Ned Batchelder
-    Bert Freudenberg
     Amit Regmi
     Ben Young
     Nicolas Chauvat
     Andrew Durdin
     Michael Schneider
     Nicholas Riley
+    Jason Chu
+    Igor Trindade Oliveira
+    Jeremy Thurgood
     Rocco Moretti
     Gintautas Miliauskas
     Michael Twomey
-    Igor Trindade Oliveira
     Lucian Branescu Mihaila
+    Tim Felgentreff
+    Tyler Wade
+    Gabriel Lavoie
     Olivier Dormond
     Jared Grubb
     Karl Bartel
-    Gabriel Lavoie
+    Brian Dorsey
     Victor Stinner
-    Brian Dorsey
     Stuart Williams
+    Jasper Schulz
     Toby Watson
     Antoine Pitrou
+    Aaron Iles
+    Michael Cheng
     Justas Sadzevicius
+    Gasper Zejn
     Neil Shepperd
     Mikael Schönenberg
-    Gasper Zejn
+    Elmo Mäntynen
+    Tobias Pape
     Jonathan David Riehl
-    Elmo Mäntynen
+    Stanislaw Halik
     Anders Qvist
+    Chirag Jadwani
     Beatrice During
+    Alex Perry
+    Vincent Legoll
+    Alan McIntyre
     Alexander Sedov
     Corbin Simpson
-    Vincent Legoll
-    Romain Guillebert
-    Alan McIntyre
-    Alex Perry
+    Christopher Pope
+    Laurence Tratt
+    Guillebert Romain
+    Christian Tismer 
+    Dan Stromberg
+    Stefano Parmesan
+    Christian Hudon
+    Alexis Daboville
     Jens-Uwe Mager
-    Simon Cross
-    Dan Stromberg
-    Guillebert Romain
     Carl Meyer
+    Karl Ramm
     Pieter Zieschang
+    Gabriel
+    Paweł Piotr Przeradowski
+    Andrew Dalke
+    Sylvain Thenault
+    Nathan Taylor
+    Vladimir Kryachko
+    Jacek Generowicz
     Alejandro J. Cura
-    Sylvain Thenault
-    Christoph Gerum
+    Jacob Oscarson
     Travis Francis Athougies
+    Kristjan Valur Jonsson
+    Neil Blakey-Milner
+    Lutz Paelike
+    Lucio Torre
+    Lars Wassermann
     Henrik Vendelbo
-    Lutz Paelike
-    Jacob Oscarson
-    Martin Blais
-    Lucio Torre
-    Lene Wagner
+    Dan Buch
     Miguel de Val Borro
     Artur Lisiecki
-    Bruno Gola
+    Sergey Kishchenko
     Ignas Mikalajunas
-    Stefano Rivera
+    Christoph Gerum
+    Martin Blais
+    Lene Wagner
+    Tomo Cocoa
+    Andrews Medina
+    roberto at goyle
+    William Leslie
+    Bobby Impollonia
+    timo at eistee.fritz.box
+    Andrew Thompson
+    Yusei Tahara
+    Roberto De Ioris
+    Juan Francisco Cantero Hurtado
+    Godefroid Chappelle
     Joshua Gilbert
-    Godefroid Chappelle
-    Yusei Tahara
+    Dan Colish
     Christopher Armstrong
+    Michael Hudson-Doyle
+    Anders Sigfridsson
+    Yasir Suhail
+    Floris Bruynooghe
+    Akira Li
+    Gustavo Niemeyer
     Stephan Busemann
-    Gustavo Niemeyer
-    William Leslie
-    Akira Li
-    Kristjan Valur Jonsson
-    Bobby Impollonia
-    Michael Hudson-Doyle
-    Laurence Tratt
-    Yasir Suhail
-    Andrew Thompson
-    Anders Sigfridsson
-    Floris Bruynooghe
-    Jacek Generowicz
-    Dan Colish
-    Zooko Wilcox-O Hearn
-    Dan Loewenherz
+    Anna Katrina Dominguez
+    Christian Muirhead
+    James Lan
+    shoma hosaka
+    Daniel Neuhäuser
+    Buck Golemon
+    Konrad Delong
+    Dinu Gherman
     Chris Lambacher
-    Dinu Gherman
-    Brett Cannon
-    Daniel Neuhäuser
-    Michael Chermside
-    Konrad Delong
-    Anna Ravencroft
-    Greg Price
-    Armin Ronacher
-    Christian Muirhead
+    coolbutuseless at gmail.com
     Jim Baker
     Rodrigo Araújo
-    Romain Guillebert
+    Armin Ronacher
+    Brett Cannon
+    yrttyr
+    Zooko Wilcox-O Hearn
+    Tomer Chachamu
+    Christopher Groskopf
+    opassembler.py
+    Antony Lee
+    Jim Hunziker
+    Markus Unterwaditzer
+    Even Wiik Thomassen
+    jbs
+    soareschen
+    Flavio Percoco
+    Kristoffer Kleine
+    yasirs
+    Michael Chermside
+    Anna Ravencroft
+    Andrew Chambers
+    Julien Phalip
+    Dan Loewenherz
 
     Heinrich-Heine University, Germany 
     Open End AB (formerly AB Strakt), Sweden
@@ -218,45 +281,22 @@
     Impara, Germany
     Change Maker, Sweden 
     University of California Berkeley, USA
+    Google Inc.
+    King's College London
 
 The PyPy Logo as used by http://speed.pypy.org and others was created
 by Samuel Reis and is distributed on terms of Creative Commons Share Alike
 License.
  
-License for 'lib-python/2.7.0' and 'lib-python/2.7.0-modified'
-============================================================== 
+License for 'lib-python/2.7'
+============================
 
-Except when otherwise stated (look for LICENSE files or
-copyright/license information at the beginning of each file) the files
-in the 'lib-python/2.7.0' and 'lib-python/2.7.0-modified' directories
-are all copyrighted by the Python Software Foundation and licensed under
-the Python Software License of which you can find a copy here:
+Except when otherwise stated (look for LICENSE files or copyright/license
+information at the beginning of each file) the files in the 'lib-python/2.7'
+directory are all copyrighted by the Python Software Foundation and licensed
+under the Python Software License of which you can find a copy here:
 http://www.python.org/doc/Copyright.html 
 
-License for 'pypy/translator/jvm/src/jna.jar'
-=============================================
-
-The file 'pypy/translator/jvm/src/jna.jar' is licensed under the GNU
-Lesser General Public License of which you can find a copy here:
-http://www.gnu.org/licenses/lgpl.html
-
-License for 'pypy/translator/jvm/src/jasmin.jar'
-================================================
-
-The file 'pypy/translator/jvm/src/jasmin.jar' is copyright (c) 1996-2004 Jon Meyer
-and distributed with permission.  The use of Jasmin by PyPy does not imply
-that PyPy is endorsed by Jon Meyer nor any of Jasmin's contributors.  Furthermore,
-the following disclaimer applies to Jasmin:
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 License for 'pypy/module/unicodedata/'
 ======================================
 
diff --git a/dotviewer/drawgraph.py b/dotviewer/drawgraph.py
--- a/dotviewer/drawgraph.py
+++ b/dotviewer/drawgraph.py
@@ -22,6 +22,7 @@
     '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
@@ -138,6 +139,13 @@
             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
@@ -520,8 +528,8 @@
                 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()]
diff --git a/dotviewer/graphparse.py b/dotviewer/graphparse.py
--- a/dotviewer/graphparse.py
+++ b/dotviewer/graphparse.py
@@ -152,7 +152,8 @@
         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))
diff --git a/dotviewer/test/test_interactive.py b/dotviewer/test/test_interactive.py
--- a/dotviewer/test/test_interactive.py
+++ b/dotviewer/test/test_interactive.py
@@ -34,6 +34,23 @@
 }
 '''
 
+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")
@@ -161,3 +178,10 @@
     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)
diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -12,6 +12,7 @@
 
 import sys
 import os
+import shlex
 
 from distutils.errors import DistutilsPlatformError
 
@@ -124,11 +125,19 @@
     if compiler.compiler_type == "unix":
         compiler.compiler_so.extend(['-O2', '-fPIC', '-Wimplicit'])
         compiler.shared_lib_extension = get_config_var('SO')
+        if "CPPFLAGS" in os.environ:
+            cppflags = shlex.split(os.environ["CPPFLAGS"])
+            compiler.compiler.extend(cppflags)
+            compiler.compiler_so.extend(cppflags)
+            compiler.linker_so.extend(cppflags)
         if "CFLAGS" in os.environ:
-            cflags = os.environ["CFLAGS"].split()
+            cflags = shlex.split(os.environ["CFLAGS"])
             compiler.compiler.extend(cflags)
             compiler.compiler_so.extend(cflags)
             compiler.linker_so.extend(cflags)
+        if "LDFLAGS" in os.environ:
+            ldflags = shlex.split(os.environ["LDFLAGS"])
+            compiler.linker_so.extend(ldflags)
 
 
 from sysconfig_cpython import (
diff --git a/lib-python/2.7/json/__init__.py b/lib-python/2.7/json/__init__.py
--- a/lib-python/2.7/json/__init__.py
+++ b/lib-python/2.7/json/__init__.py
@@ -105,6 +105,12 @@
 
 __author__ = 'Bob Ippolito <bob at redivi.com>'
 
+try:
+    # PyPy speedup, the interface is different than CPython's _json
+    import _pypyjson
+except ImportError:
+    _pypyjson = None
+
 from .decoder import JSONDecoder
 from .encoder import JSONEncoder
 
@@ -241,7 +247,6 @@
 _default_decoder = JSONDecoder(encoding=None, object_hook=None,
                                object_pairs_hook=None)
 
-
 def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
         parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
     """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
@@ -323,7 +328,10 @@
     if (cls is None and encoding is None and object_hook is None and
             parse_int is None and parse_float is None and
             parse_constant is None and object_pairs_hook is None and not kw):
-        return _default_decoder.decode(s)
+        if _pypyjson and not isinstance(s, unicode):
+            return _pypyjson.loads(s)
+        else:
+            return _default_decoder.decode(s)
     if cls is None:
         cls = JSONDecoder
     if object_hook is not None:
diff --git a/lib-python/2.7/logging/__init__.py b/lib-python/2.7/logging/__init__.py
--- a/lib-python/2.7/logging/__init__.py
+++ b/lib-python/2.7/logging/__init__.py
@@ -134,6 +134,11 @@
 DEBUG = 10
 NOTSET = 0
 
+# NOTE(flaper87): This is different from
+# python's stdlib module since pypy's
+# dicts are much faster when their
+# keys are all of the same type.
+# Introduced in commit 9de7b40c586f
 _levelToName = {
     CRITICAL: 'CRITICAL',
     ERROR: 'ERROR',
@@ -168,7 +173,11 @@
 
     Otherwise, the string "Level %s" % level is returned.
     """
-    return _levelToName.get(level, ("Level %s" % level))
+
+    # NOTE(flaper87): Check also in _nameToLevel
+    # if value is None.
+    return (_levelToName.get(level) or
+            _nameToLevel.get(level, ("Level %s" % level)))
 
 def addLevelName(level, levelName):
     """
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -165,6 +165,8 @@
     # 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
@@ -179,12 +181,21 @@
     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):
@@ -216,9 +227,8 @@
 
     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):
@@ -280,8 +290,14 @@
                  "_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:
@@ -317,11 +333,11 @@
                 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:
diff --git a/lib-python/2.7/ssl.py b/lib-python/2.7/ssl.py
--- a/lib-python/2.7/ssl.py
+++ b/lib-python/2.7/ssl.py
@@ -110,6 +110,12 @@
                  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
 
@@ -352,11 +358,19 @@
         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,
diff --git a/lib-python/2.7/test/test_logging.py b/lib-python/2.7/test/test_logging.py
--- a/lib-python/2.7/test/test_logging.py
+++ b/lib-python/2.7/test/test_logging.py
@@ -278,6 +278,24 @@
     def test_invalid_name(self):
         self.assertRaises(TypeError, logging.getLogger, any)
 
+    def test_get_level_name(self):
+        """Test getLevelName returns level constant."""
+        # NOTE(flaper87): Bug #1517
+        self.assertEqual(logging.getLevelName('NOTSET'), 0)
+        self.assertEqual(logging.getLevelName('DEBUG'), 10)
+        self.assertEqual(logging.getLevelName('INFO'), 20)
+        self.assertEqual(logging.getLevelName('WARN'), 30)
+        self.assertEqual(logging.getLevelName('WARNING'), 30)
+        self.assertEqual(logging.getLevelName('ERROR'), 40)
+        self.assertEqual(logging.getLevelName('CRITICAL'), 50)
+
+        self.assertEqual(logging.getLevelName(0), 'NOTSET')
+        self.assertEqual(logging.getLevelName(10), 'DEBUG')
+        self.assertEqual(logging.getLevelName(20), 'INFO')
+        self.assertEqual(logging.getLevelName(30), 'WARNING')
+        self.assertEqual(logging.getLevelName(40), 'ERROR')
+        self.assertEqual(logging.getLevelName(50), 'CRITICAL')
+
 class BasicFilterTest(BaseTest):
 
     """Test the bundled Filter class."""
diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -275,7 +275,7 @@
         try:
             result.f_bfree = 1
             self.fail("No exception thrown")
-        except TypeError:
+        except (TypeError, AttributeError):
             pass
 
         try:
diff --git a/lib-python/2.7/test/test_socket.py b/lib-python/2.7/test/test_socket.py
--- a/lib-python/2.7/test/test_socket.py
+++ b/lib-python/2.7/test/test_socket.py
@@ -1066,6 +1066,9 @@
         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)
@@ -1321,7 +1324,8 @@
             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
diff --git a/lib-python/2.7/test/test_urllib2.py b/lib-python/2.7/test/test_urllib2.py
--- a/lib-python/2.7/test/test_urllib2.py
+++ b/lib-python/2.7/test/test_urllib2.py
@@ -270,6 +270,8 @@
         self.reason = reason
     def read(self):
         return ''
+    def _reuse(self): pass
+    def _drop(self): pass
 
 class MockHTTPClass:
     def __init__(self):
diff --git a/lib-python/2.7/urllib2.py b/lib-python/2.7/urllib2.py
--- a/lib-python/2.7/urllib2.py
+++ b/lib-python/2.7/urllib2.py
@@ -1193,6 +1193,8 @@
         # 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())
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -20,7 +20,7 @@
                 or tp._type_ not in "iIhHbBlLqQ"):
                 #XXX: are those all types?
                 #     we just dont get the type name
-                #     in the interp levle thrown TypeError
+                #     in the interp level thrown TypeError
                 #     from rawffi if there are more
                 raise TypeError('bit fields not allowed for type ' + tp.__name__)
 
diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -476,6 +476,15 @@
 def _chtype(ch):
     return int(ffi.cast("chtype", ch))
 
+def _texttype(text):
+    if isinstance(text, str):
+        return text
+    elif isinstance(text, unicode):
+        return str(text)   # default encoding
+    else:
+        raise TypeError("str or unicode expected, got a '%s' object"
+                        % (type(text).__name__,))
+
 
 def _extract_yx(args):
     if len(args) >= 2:
@@ -589,6 +598,7 @@
 
     @_argspec(1, 1, 2)
     def addstr(self, y, x, text, attr=None):
+        text = _texttype(text)
         if attr is not None:
             attr_old = lib.getattrs(self._win)
             lib.wattrset(self._win, attr)
@@ -602,6 +612,7 @@
 
     @_argspec(2, 1, 2)
     def addnstr(self, y, x, text, n, attr=None):
+        text = _texttype(text)
         if attr is not None:
             attr_old = lib.getattrs(self._win)
             lib.wattrset(self._win, attr)
@@ -780,6 +791,7 @@
 
     @_argspec(1, 1, 2)
     def insstr(self, y, x, text, attr=None):
+        text = _texttype(text)
         if attr is not None:
             attr_old = lib.getattrs(self._win)
             lib.wattrset(self._win, attr)
@@ -793,6 +805,7 @@
 
     @_argspec(2, 1, 2)
     def insnstr(self, y, x, text, n, attr=None):
+        text = _texttype(text)
         if attr is not None:
             attr_old = lib.getattrs(self._win)
             lib.wattrset(self._win, attr)
@@ -953,7 +966,7 @@
     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):
@@ -1108,6 +1121,7 @@
         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:
@@ -1197,6 +1211,7 @@
 
 
 def putp(text):
+    text = _texttype(text)
     return _check_ERR(lib.putp(text), "putp")
 
 
diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py
--- a/lib_pypy/_pypy_irc_topic.py
+++ b/lib_pypy/_pypy_irc_topic.py
@@ -165,6 +165,63 @@
 Nyy rkprcgoybpxf frrz fnar.
 N cvax tyvggrel ebgngvat ynzoqn
 "vg'f yvxryl grzcbenel hagvy sberire" nevtb
+"Lbh xabj jung'f avpr nobhg EClguba?  Ybatre fjbeq svtugf."
+nccneragyl pbashfvba vf n srngher
+nccneragyl pbashfvba vf n srngher... be vf vg?
+ClCl 1.7 eryrnfrq
+vs lbh jnag gb or penml, lbh qba'g unir gb sbepr vg
+vs lbh jnag vg gb or iveghny, lbh fubhyq abg sbepr vg
+<Nyrk_Tnlabe> svwny: V whfg... fgnegrq pbqvat naq fhqqragyl... nobzvangvba
+fabj, fabj! :-)
+fabj, fabj, fabj, fabj
+clcl 1.8 eryrnfrq
+vg jnf srj lnxf gbb yngr
+ClCl vf n enpr orgjrra hf funivat lnxf, naq gur havirefr gelvat gb cebqhpr zber naq zber lnxf
+Jevgvat na SC7 nabalzbhf cebcbfny sbe ClCl vf yvxr znxvat n gi nq sbe n uvtu cresbeznapr fcbegf pne jvgubhg orvat noyr gb zragvba vgf zbqry be znahsnpghere
+Fabj, fabj (ntnva)
+Fgvyy fabjvat
+thrff jung, fabj
+"lbh haqrerfgvzngr gur vzcbegnapr bs zvpebnepuvgrpgher" "ab, vg'f zber gung jr ner fgvyy unccvyl va gur ynaq bs ernpunoyr sehvg"
+Jub nz V?  Naq vs lrf, ubj znal?
+ClCl vf nyjnlf n cynfzn
+"genafyngvba gbbypunva" = "EClgure"?  gb jevgr vagrEClguref va
+"sberire" va clcl grezf zrnaf yvxr srj zbaguf :)
+"Onu.  PClguba bofphevgl. - Nezva Evtb"
+svwny: pna V vavgvngr lbh ba gur (rnfl ohg) aba-gevivny gbcvp bs jevgvat P shapgvba glcrf? :-)
+nyy fbsgjner vzcebirzragf unccra ol n ovg
+gur genprf qba'g yvr
+:-) be engure ":-/" bss-ol-bar-xrl reebe
+Be Nezva Evtb. V guvax ur'f noyr gb haqrefgnaq k86 gur jnl Plcure pna frr jbzra va gur zngevk.
+V zvtug, ohg abobql erfcrpgf zr
+cerohvyg vafgnapr Ryyvcfvf unf ab nggevohgr 'reeab'
+guvf frnfba'f svefg "fabj! fabj!" vf urer
+ClCl 2.0 orgn1 eryrnfrq - orggre yngr guna arire
+Fjvgreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq
+Fjvgmreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq
+<nevtngb> n sngny reebe, ol qrsvavgvba, vf sngny
+<nagbphav> V'z tynq gung jr cebtenz va Clguba naq jr qba'g qrny jvgu gubfr vffhrf rirel qnl. Ncneg gur snpg gung jr unir gb qrny jvgu gurz naljnl, vg frrzf
+unccl arj lrne!
+"zrffl" vf abg n whqtrzrag, ohg whfg n snpg bs pbzcyvpngrqarff
+n ybg bs fabj
+qb lbh xabj nobhg n gbnfgre jvgu 8XO bs ENZ naq 64XO bs EBZ?
+vg'f orra fabjvat rirelqnl sbe n juvyr, V pna'g whfg chg "fabj, fabj" hc urer rirel qnl
+fabjonyy svtugf!
+sbejneq pbzcngvovyvgl jvgu bcgvzvmngvbaf gung unira'g orra vairagrq lrg
+jr fgvyy unir gb jevgr fbsgjner jvgu n zrgnfcnpr ohooyr va vg
+cebonoyl gur ynfg gvzr va gur frnfba, ohg: fabj, fabj!
+ClCl 2.0-orgn2 eryrnfrq
+Gur ceboyrz vf gung sbe nyzbfg nal aba-gevivny cebtenz, vg'f abg pyrne jung 'pbeerpg' zrnaf.
+ClCl 2.0 nyzbfg eryrnfrq
+ClCl 2.0 eryrnfrq
+WVG pbzcvyref fubhyq or jevggra ol crbcyr jub npghnyyl unir snvgu va WVG pbzcvyref' novyvgl gb znxrf guvatf tb fpernzvat snfg
+ClCl 2.0.1 eryrnfrq
+arire haqrerfgvzngr gur vzcebonoyr jura lbh qb fbzrguvat ng 2TUm
+ClCl 2.0.2 eryrnfrq
+nyy jr arrq vf n angvir Cebybt znpuvar
+V haqrefgnaq ubj qravnyvfz vf n onq qrohttvat grpuavdhr
+rirel IZ fubhyq pbzr jvgu arheny argjbex genvarq gb erpbtavmr zvpeborapuznexf naq enaqbzyl syhpghngr gurz +/-9000%
+lbh qvq abg nccebnpu clcl sebz gur rnfl raq: fgz, gura wvg. vg'f n ovg gur Abegu snpr
+va ClCl orvat bayl zbqrengryl zntvp vf n tbbq guvat <psobym>
 """
 
 from string import ascii_uppercase, ascii_lowercase
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1305,7 +1305,7 @@
         for i in xrange(_lib.sqlite3_column_count(self._statement)):
             name = _lib.sqlite3_column_name(self._statement, i)
             if name:
-                name = _ffi.string(name).decode('utf-8').split("[")[0].strip()
+                name = _ffi.string(name).split("[")[0].strip()
             desc.append((name, None, None, None, None, None, None))
         return desc
 
diff --git a/lib_pypy/_tkinter/__init__.py b/lib_pypy/_tkinter/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/__init__.py
@@ -0,0 +1,48 @@
+# _tkinter package -- low-level interface to libtk and libtcl.
+#
+# This is an internal module, applications should "import Tkinter" instead.
+#
+# This version is based on cffi, and is a translation of _tkinter.c
+# from CPython, version 2.7.4.
+
+class TclError(Exception):
+    pass
+
+import cffi
+try:
+    from .tklib import tklib, tkffi
+except cffi.VerificationError:
+    raise ImportError("Tk headers and development libraries are required")
+
+from .app import TkApp
+
+TK_VERSION = tkffi.string(tklib.get_tk_version())
+TCL_VERSION = tkffi.string(tklib.get_tcl_version())
+
+READABLE = tklib.TCL_READABLE
+WRITABLE = tklib.TCL_WRITABLE
+EXCEPTION = tklib.TCL_EXCEPTION
+
+def create(screenName=None, baseName=None, className=None,
+           interactive=False, wantobjects=False, wantTk=True,
+           sync=False, use=None):
+    return TkApp(screenName, baseName, className,
+                 interactive, wantobjects, wantTk, sync, use)
+
+def _flatten(item):
+    def _flatten1(output, item, depth):
+        if depth > 1000:
+            raise ValueError("nesting too deep in _flatten")
+        if not isinstance(item, (list, tuple)):
+            raise TypeError("argument must be sequence")
+        # copy items to output tuple
+        for o in item:
+            if isinstance(o, (list, tuple)):
+                _flatten1(output, o, depth + 1)
+            elif o is not None:
+                output.append(o)
+
+    result = []
+    _flatten1(result, item, 0)
+    return tuple(result)
+    
diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/app.py
@@ -0,0 +1,389 @@
+# The TkApp class.
+
+from .tklib import tklib, tkffi
+from . import TclError
+from .tclobj import TclObject, FromObj, AsObj, TypeCache
+
+import sys
+
+def varname_converter(input):
+    if isinstance(input, TclObject):
+        return input.string
+    return input
+
+
+def Tcl_AppInit(app):
+    if tklib.Tcl_Init(app.interp) == tklib.TCL_ERROR:
+        app.raiseTclError()
+    skip_tk_init = tklib.Tcl_GetVar(
+        app.interp, "_tkinter_skip_tk_init", tklib.TCL_GLOBAL_ONLY)
+    if skip_tk_init and tkffi.string(skip_tk_init) == "1":
+        return
+
+    if tklib.Tk_Init(app.interp) == tklib.TCL_ERROR:
+        app.raiseTclError()
+
+class _CommandData(object):
+    def __new__(cls, app, name, func):
+        self = object.__new__(cls)
+        self.app = app
+        self.name = name
+        self.func = func
+        handle = tkffi.new_handle(self)
+        app._commands[name] = handle  # To keep the command alive
+        return tkffi.cast("ClientData", handle)
+
+    @tkffi.callback("Tcl_CmdProc")
+    def PythonCmd(clientData, interp, argc, argv):
+        self = tkffi.from_handle(clientData)
+        assert self.app.interp == interp
+        try:
+            args = [tkffi.string(arg) for arg in argv[1:argc]]
+            result = self.func(*args)
+            obj = AsObj(result)
+            tklib.Tcl_SetObjResult(interp, obj)
+        except:
+            self.app.errorInCmd = True
+            self.app.exc_info = sys.exc_info()
+            return tklib.TCL_ERROR
+        else:
+            return tklib.TCL_OK
+
+    @tkffi.callback("Tcl_CmdDeleteProc")
+    def PythonCmdDelete(clientData):
+        self = tkffi.from_handle(clientData)
+        app = self.app
+        del app._commands[self.name]
+        return
+
+
+class TkApp(object):
+    def __new__(cls, screenName, baseName, className,
+                interactive, wantobjects, wantTk, sync, use):
+        if not wantobjects:
+            raise NotImplementedError("wantobjects=True only")
+        self = object.__new__(cls)
+        self.interp = tklib.Tcl_CreateInterp()
+        self._wantobjects = wantobjects
+        self.threaded = bool(tklib.Tcl_GetVar2Ex(
+            self.interp, "tcl_platform", "threaded",
+            tklib.TCL_GLOBAL_ONLY))
+        self.thread_id = tklib.Tcl_GetCurrentThread()
+        self.dispatching = False
+        self.quitMainLoop = False
+        self.errorInCmd = False
+
+        self._typeCache = TypeCache()
+        self._commands = {}
+
+        # Delete the 'exit' command, which can screw things up
+        tklib.Tcl_DeleteCommand(self.interp, "exit")
+
+        if screenName is not None:
+            tklib.Tcl_SetVar2(self.interp, "env", "DISPLAY", screenName,
+                              tklib.TCL_GLOBAL_ONLY)
+
+        if interactive:
+            tklib.Tcl_SetVar(self.interp, "tcl_interactive", "1",
+                             tklib.TCL_GLOBAL_ONLY)
+        else:
+            tklib.Tcl_SetVar(self.interp, "tcl_interactive", "0",
+                             tklib.TCL_GLOBAL_ONLY)
+
+        # This is used to get the application class for Tk 4.1 and up
+        argv0 = className.lower()
+        tklib.Tcl_SetVar(self.interp, "argv0", argv0,
+                         tklib.TCL_GLOBAL_ONLY)
+
+        if not wantTk:
+            tklib.Tcl_SetVar(self.interp, "_tkinter_skip_tk_init", "1",
+                             tklib.TCL_GLOBAL_ONLY)
+
+        # some initial arguments need to be in argv
+        if sync or use:
+            args = ""
+            if sync:
+                args += "-sync"
+            if use:
+                if sync:
+                    args += " "
+                args += "-use " + use
+
+            tklib.Tcl_SetVar(self.interp, "argv", args,
+                             tklib.TCL_GLOBAL_ONLY)
+
+        Tcl_AppInit(self)
+        # EnableEventHook()
+        return self
+
+    def __del__(self):
+        tklib.Tcl_DeleteInterp(self.interp)
+        # DisableEventHook()
+
+    def raiseTclError(self):
+        if self.errorInCmd:
+            self.errorInCmd = False
+            raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
+        raise TclError(tkffi.string(tklib.Tcl_GetStringResult(self.interp)))
+
+    def wantobjects(self):
+        return self._wantobjects
+
+    def _check_tcl_appartment(self):
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            raise RuntimeError("Calling Tcl from different appartment")
+
+    def loadtk(self):
+        # We want to guard against calling Tk_Init() multiple times
+        err = tklib.Tcl_Eval(self.interp, "info exists     tk_version")
+        if err == tklib.TCL_ERROR:
+            self.raiseTclError()
+        tk_exists = tklib.Tcl_GetStringResult(self.interp)
+        if not tk_exists or tkffi.string(tk_exists) != "1":
+            err = tklib.Tk_Init(self.interp)
+            if err == tklib.TCL_ERROR:
+                self.raiseTclError()
+
+    def _var_invoke(self, func, *args, **kwargs):
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            # The current thread is not the interpreter thread.
+            # Marshal the call to the interpreter thread, then wait
+            # for completion.
+            raise NotImplementedError("Call from another thread")
+        return func(*args, **kwargs)
+
+    def _getvar(self, name1, name2=None, global_only=False):
+        name1 = varname_converter(name1)
+        if not name2:
+            name2 = tkffi.NULL
+        flags=tklib.TCL_LEAVE_ERR_MSG
+        if global_only:
+            flags |= tklib.TCL_GLOBAL_ONLY
+        res = tklib.Tcl_GetVar2Ex(self.interp, name1, name2, flags)
+        if not res:
+            self.raiseTclError()
+        assert self._wantobjects
+        return FromObj(self, res)
+
+    def _setvar(self, name1, value, global_only=False):
+        name1 = varname_converter(name1)
+        newval = AsObj(value)
+        flags=tklib.TCL_LEAVE_ERR_MSG
+        if global_only:
+            flags |= tklib.TCL_GLOBAL_ONLY
+        res = tklib.Tcl_SetVar2Ex(self.interp, name1, tkffi.NULL,
+                                  newval, flags)
+        if not res:
+            self.raiseTclError()
+
+    def _unsetvar(self, name1, name2=None, global_only=False):
+        name1 = varname_converter(name1)
+        if not name2:
+            name2 = tkffi.NULL
+        flags=tklib.TCL_LEAVE_ERR_MSG
+        if global_only:
+            flags |= tklib.TCL_GLOBAL_ONLY
+        res = tklib.Tcl_UnsetVar2(self.interp, name1, name2, flags)
+        if res == tklib.TCL_ERROR:
+            self.raiseTclError()
+
+    def getvar(self, name1, name2=None):
+        return self._var_invoke(self._getvar, name1, name2)
+
+    def globalgetvar(self, name1, name2=None):
+        return self._var_invoke(self._getvar, name1, name2, global_only=True)
+
+    def setvar(self, name1, value):
+        return self._var_invoke(self._setvar, name1, value)
+
+    def globalsetvar(self, name1, value):
+        return self._var_invoke(self._setvar, name1, value, global_only=True)
+
+    def unsetvar(self, name1, name2=None):
+        return self._var_invoke(self._unsetvar, name1, name2)
+
+    def globalunsetvar(self, name1, name2=None):
+        return self._var_invoke(self._unsetvar, name1, name2, global_only=True)
+
+    # COMMANDS
+
+    def createcommand(self, cmdName, func):
+        if not callable(func):
+            raise TypeError("command not callable")
+
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            raise NotImplementedError("Call from another thread")
+
+        clientData = _CommandData(self, cmdName, func)
+
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            raise NotImplementedError("Call from another thread")
+
+        res = tklib.Tcl_CreateCommand(
+            self.interp, cmdName, _CommandData.PythonCmd,
+            clientData, _CommandData.PythonCmdDelete)
+        if not res:
+            raise TclError("can't create Tcl command")
+
+    def deletecommand(self, cmdName):
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            raise NotImplementedError("Call from another thread")
+
+        res = tklib.Tcl_DeleteCommand(self.interp, cmdName)
+        if res == -1:
+            raise TclError("can't delete Tcl command")
+
+    def call(self, *args):
+        flags = tklib.TCL_EVAL_DIRECT | tklib.TCL_EVAL_GLOBAL
+
+        # If args is a single tuple, replace with contents of tuple
+        if len(args) == 1 and isinstance(args[0], tuple):
+            args = args[0]
+
+        if self.threaded and self.thread_id != tklib.Tcl_GetCurrentThread():
+            # We cannot call the command directly. Instead, we must
+            # marshal the parameters to the interpreter thread.
+            raise NotImplementedError("Call from another thread")
+
+        objects = tkffi.new("Tcl_Obj*[]", len(args))
+        argc = len(args)
+        try:
+            for i, arg in enumerate(args):
+                if arg is None:
+                    argc = i
+                    break
+                obj = AsObj(arg)
+                tklib.Tcl_IncrRefCount(obj)
+                objects[i] = obj
+
+            res = tklib.Tcl_EvalObjv(self.interp, argc, objects, flags)
+            if res == tklib.TCL_ERROR:
+                self.raiseTclError()
+            else:
+                result = self._callResult()
+        finally:
+            for obj in objects:
+                if obj:
+                    tklib.Tcl_DecrRefCount(obj)
+        return result
+
+    def _callResult(self):
+        assert self._wantobjects
+        value = tklib.Tcl_GetObjResult(self.interp)
+        # Not sure whether the IncrRef is necessary, but something
+        # may overwrite the interpreter result while we are
+        # converting it.
+        tklib.Tcl_IncrRefCount(value)
+        res = FromObj(self, value)
+        tklib.Tcl_DecrRefCount(value)
+        return res
+
+    def eval(self, script):
+        self._check_tcl_appartment()
+        res = tklib.Tcl_Eval(self.interp, script)
+        if res == tklib.TCL_ERROR:
+            self.raiseTclError()
+        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+
+    def evalfile(self, filename):
+        self._check_tcl_appartment()
+        res = tklib.Tcl_EvalFile(self.interp, filename)
+        if res == tklib.TCL_ERROR:
+            self.raiseTclError()
+        return tkffi.string(tklib.Tcl_GetStringResult(self.interp))
+
+    def split(self, arg):
+        if isinstance(arg, tuple):
+            return self._splitObj(arg)
+        else:
+            return self._split(arg)
+
+    def splitlist(self, arg):
+        if isinstance(arg, tuple):
+            return arg
+        if isinstance(arg, unicode):
+            arg = arg.encode('utf8')
+
+        argc = tkffi.new("int*")
+        argv = tkffi.new("char***")
+        res = tklib.Tcl_SplitList(self.interp, arg, argc, argv)
+        if res == tklib.TCL_ERROR:
+            self.raiseTclError()
+
+        result = tuple(tkffi.string(argv[0][i])
+                       for i in range(argc[0]))
+        tklib.Tcl_Free(argv[0])
+        return result
+
+    def _splitObj(self, arg):
+        if isinstance(arg, tuple):
+            size = len(arg)
+            # Recursively invoke SplitObj for all tuple items.
+            # If this does not return a new object, no action is
+            # needed.
+            result = None
+            newelems = (self._splitObj(elem) for elem in arg)
+            for elem, newelem in zip(arg, newelems):
+                if elem is not newelem:
+                    return newelems
+        elif isinstance(arg, str):
+            argc = tkffi.new("int*")
+            argv = tkffi.new("char***")
+            res = tklib.Tcl_SplitList(tkffi.NULL, arg, argc, argv)
+            if res == tklib.TCL_ERROR:
+                return arg
+            tklib.Tcl_Free(argv[0])
+            if argc[0] > 1:
+                return self._split(arg)
+        return arg
+
+    def _split(self, arg):
+        argc = tkffi.new("int*")
+        argv = tkffi.new("char***")
+        res = tklib.Tcl_SplitList(tkffi.NULL, arg, argc, argv)
+        if res == tklib.TCL_ERROR:
+            # Not a list.
+            # Could be a quoted string containing funnies, e.g. {"}.
+            # Return the string itself.
+            return arg
+
+        try:
+            if argc[0] == 0:
+                return ""
+            elif argc[0] == 1:
+                return argv[0][0]
+            else:
+                return (self._split(argv[0][i])
+                        for i in range(argc[0]))
+        finally:
+            tklib.Tcl_Free(argv[0])
+
+    def getboolean(self, s):
+        if isinstance(s, int):
+            return s
+        v = tkffi.new("int*")
+        res = tklib.Tcl_GetBoolean(self.interp, s, v)
+        if res == tklib.TCL_ERROR:
+            self.raiseTclError()
+
+    def mainloop(self, threshold):
+        self._check_tcl_appartment()
+        self.dispatching = True
+        while (tklib.Tk_GetNumMainWindows() > threshold and
+               not self.quitMainLoop and not self.errorInCmd):
+
+            if self.threaded:
+                result = tklib.Tcl_DoOneEvent(0)
+            else:
+                raise NotImplementedError("TCL configured without threads")
+
+            if result < 0:
+                break
+        self.dispatching = False
+        self.quitMainLoop = False
+        if self.errorInCmd:
+            self.errorInCmd = False
+            raise self.exc_info[0], self.exc_info[1], self.exc_info[2]
+
+    def quit(self):
+        self.quitMainLoop = True
diff --git a/lib_pypy/_tkinter/tclobj.py b/lib_pypy/_tkinter/tclobj.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/tclobj.py
@@ -0,0 +1,114 @@
+# TclObject, conversions with Python objects
+
+from .tklib import tklib, tkffi
+
+class TypeCache(object):
+    def __init__(self):
+        self.BooleanType = tklib.Tcl_GetObjType("boolean")
+        self.ByteArrayType = tklib.Tcl_GetObjType("bytearray")
+        self.DoubleType = tklib.Tcl_GetObjType("double")
+        self.IntType = tklib.Tcl_GetObjType("int")
+        self.ListType = tklib.Tcl_GetObjType("list")
+        self.ProcBodyType = tklib.Tcl_GetObjType("procbody")
+        self.StringType = tklib.Tcl_GetObjType("string")
+        
+
+def FromObj(app, value):
+    """Convert a TclObj pointer into a Python object."""
+    typeCache = app._typeCache
+    if not value.typePtr:
+        buf = tkffi.buffer(value.bytes, value.length)
+        result = buf[:]
+        # If the result contains any bytes with the top bit set, it's
+        # UTF-8 and we should decode it to Unicode.
+        try:
+            result.decode('ascii')
+        except UnicodeDecodeError:
+            result = result.decode('utf8')
+        return result
+
+    elif value.typePtr == typeCache.BooleanType:
+        return result
+    elif value.typePtr == typeCache.ByteArrayType:
+        return result
+    elif value.typePtr == typeCache.DoubleType:
+        return value.internalRep.doubleValue
+    elif value.typePtr == typeCache.IntType:
+        return value.internalRep.longValue
+    elif value.typePtr == typeCache.ListType:
+        size = tkffi.new('int*')
+        status = tklib.Tcl_ListObjLength(app.interp, value, size)
+        if status == tklib.TCL_ERROR:
+            app.raiseTclError()
+        result = []
+        tcl_elem = tkffi.new("Tcl_Obj**")
+        for i in range(size[0]):
+            status = tklib.Tcl_ListObjIndex(app.interp,
+                                            value, i, tcl_elem)
+            if status == tklib.TCL_ERROR:
+                app.raiseTclError()
+            result.append(FromObj(app, tcl_elem[0]))
+        return tuple(result)
+    elif value.typePtr == typeCache.ProcBodyType:
+        return result
+    elif value.typePtr == typeCache.StringType:
+        buf = tklib.Tcl_GetUnicode(value)
+        length = tklib.Tcl_GetCharLength(value)
+        buf = tkffi.buffer(tkffi.cast("char*", buf), length*2)[:]
+        return buf.decode('utf-16')
+
+    return TclObject(value)
+
+def AsObj(value):
+    if isinstance(value, str):
+        return tklib.Tcl_NewStringObj(value, len(value))
+    elif isinstance(value, bool):
+        return tklib.Tcl_NewBooleanObj(value)
+    elif isinstance(value, int):
+        return tklib.Tcl_NewLongObj(value)
+    elif isinstance(value, float):
+        return tklib.Tcl_NewDoubleObj(value)
+    elif isinstance(value, tuple):
+        argv = tkffi.new("Tcl_Obj*[]", len(value))
+        for i in range(len(value)):
+            argv[i] = AsObj(value[i])
+        return tklib.Tcl_NewListObj(len(value), argv)
+    elif isinstance(value, unicode):
+        encoded = value.encode('utf-16')[2:]
+        buf = tkffi.new("char[]", encoded)
+        inbuf = tkffi.cast("Tcl_UniChar*", buf)
+        return tklib.Tcl_NewUnicodeObj(buf, len(encoded)/2)
+    elif isinstance(value, TclObject):
+        tklib.Tcl_IncrRefCount(value._value)
+        return value._value
+    else:
+        return AsObj(str(value))
+
+class TclObject(object):
+    def __new__(cls, value):
+        self = object.__new__(cls)
+        tklib.Tcl_IncrRefCount(value)
+        self._value = value
+        self._string = None
+        return self
+
+    def __del__(self):
+        tklib.Tcl_DecrRefCount(self._value)
+
+    def __str__(self):
+        if self._string and isinstance(self._string, str):
+            return self._string
+        return tkffi.string(tklib.Tcl_GetString(self._value))
+
+    @property
+    def string(self):
+        if self._string is None:
+            length = tkffi.new("int*")
+            s = tklib.Tcl_GetStringFromObj(self._value, length)
+            value = tkffi.buffer(s, length[0])[:]
+            try:
+                value.decode('ascii')
+            except UnicodeDecodeError:
+                value = value.decode('utf8')
+            self._string = value
+        return self._string
diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_tkinter/tklib.py
@@ -0,0 +1,114 @@
+# C bindings with libtcl and libtk.
+
+from cffi import FFI
+
+tkffi = FFI()
+
+tkffi.cdef("""
+char *get_tk_version();
+char *get_tcl_version();
+#define TCL_READABLE ...
+#define TCL_WRITABLE ...
+#define TCL_EXCEPTION ...
+#define TCL_ERROR ...
+#define TCL_OK ...
+
+#define TCL_LEAVE_ERR_MSG ...
+#define TCL_GLOBAL_ONLY ...
+#define TCL_EVAL_DIRECT ...
+#define TCL_EVAL_GLOBAL ...
+
+typedef unsigned short Tcl_UniChar;
+typedef ... Tcl_Interp;
+typedef ...* Tcl_ThreadId;
+typedef ...* Tcl_Command;
+
+typedef struct Tcl_ObjType {
+    char *name;
+    ...;
+} Tcl_ObjType;
+typedef struct Tcl_Obj {
+    char *bytes;
+    int length;
+    Tcl_ObjType *typePtr;
+    union {                     /* The internal representation: */
+        long longValue;         /*   - an long integer value. */
+        double doubleValue;     /*   - a double-precision floating value. */
+        struct {                /*   - internal rep as two pointers. */
+            void *ptr1;
+            void *ptr2;
+        } twoPtrValue;
+    } internalRep;
+    ...;
+} Tcl_Obj;
+
+Tcl_Interp *Tcl_CreateInterp();
+void Tcl_DeleteInterp(Tcl_Interp* interp);
+int Tcl_Init(Tcl_Interp* interp);
+int Tk_Init(Tcl_Interp* interp);
+
+void Tcl_Free(char* ptr);
+
+const char *Tcl_SetVar(Tcl_Interp* interp, const char* varName, const char* newValue, int flags);
+const char *Tcl_SetVar2(Tcl_Interp* interp, const char* name1, const char* name2, const char* newValue, int flags);
+const char *Tcl_GetVar(Tcl_Interp* interp, const char* varName, int flags);
+Tcl_Obj *Tcl_SetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, Tcl_Obj* newValuePtr, int flags);
+Tcl_Obj *Tcl_GetVar2Ex(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
+int Tcl_UnsetVar2(Tcl_Interp* interp, const char* name1, const char* name2, int flags);
+const Tcl_ObjType *Tcl_GetObjType(const char* typeName);
+
+Tcl_Obj *Tcl_NewStringObj(const char* bytes, int length);
+Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar* unicode, int numChars);
+Tcl_Obj *Tcl_NewLongObj(long longValue);
+Tcl_Obj *Tcl_NewBooleanObj(int boolValue);
+Tcl_Obj *Tcl_NewDoubleObj(double doubleValue);
+
+void Tcl_IncrRefCount(Tcl_Obj* objPtr);
+void Tcl_DecrRefCount(Tcl_Obj* objPtr);
+
+int Tcl_GetBoolean(Tcl_Interp* interp, const char* src, int* boolPtr);
+char *Tcl_GetString(Tcl_Obj* objPtr);
+char *Tcl_GetStringFromObj(Tcl_Obj* objPtr, int* lengthPtr);
+
+Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj* objPtr);
+int Tcl_GetCharLength(Tcl_Obj* objPtr);
+
+Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj* const objv[]);
+int Tcl_ListObjLength(Tcl_Interp* interp, Tcl_Obj* listPtr, int* intPtr);
+int Tcl_ListObjIndex(Tcl_Interp* interp, Tcl_Obj* listPtr, int index, Tcl_Obj** objPtrPtr);
+int Tcl_SplitList(Tcl_Interp* interp, char* list, int* argcPtr, const char*** argvPtr);
+
+int Tcl_Eval(Tcl_Interp* interp, const char* script);
+int Tcl_EvalFile(Tcl_Interp* interp, const char* filename);
+int Tcl_EvalObjv(Tcl_Interp* interp, int objc, Tcl_Obj** objv, int flags);
+Tcl_Obj *Tcl_GetObjResult(Tcl_Interp* interp);
+const char *Tcl_GetStringResult(Tcl_Interp* interp);
+void Tcl_SetObjResult(Tcl_Interp* interp, Tcl_Obj* objPtr);
+
+typedef void* ClientData;
+typedef int Tcl_CmdProc(
+        ClientData clientData,
+        Tcl_Interp *interp,
+        int argc,
+        const char *argv[]);
+typedef void Tcl_CmdDeleteProc(
+        ClientData clientData);
+Tcl_Command Tcl_CreateCommand(Tcl_Interp* interp, const char* cmdName, Tcl_CmdProc proc, ClientData clientData, Tcl_CmdDeleteProc deleteProc);
+int Tcl_DeleteCommand(Tcl_Interp* interp, const char* cmdName);
+
+Tcl_ThreadId Tcl_GetCurrentThread();
+int Tcl_DoOneEvent(int flags);
+
+int Tk_GetNumMainWindows();
+""")
+
+tklib = tkffi.verify("""
+#include <tcl.h>
+#include <tk.h>
+
+char *get_tk_version() { return TK_VERSION; }
+char *get_tcl_version() { return TCL_VERSION; }
+""",
+include_dirs=['/usr/include/tcl'],
+libraries=['tcl', 'tk'],
+)
diff --git a/lib_pypy/cffi.egg-info b/lib_pypy/cffi.egg-info
--- a/lib_pypy/cffi.egg-info
+++ b/lib_pypy/cffi.egg-info
@@ -1,6 +1,6 @@
 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
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -707,7 +707,7 @@
         class CTypesStructOrUnion(CTypesBaseStructOrUnion):
             __slots__ = ['_blob']
             _ctype = struct_or_union
-            _reftypename = '%s %s &' % (kind, name)
+            _reftypename = '%s &' % (name,)
             _kind = kind
         #
         CTypesStructOrUnion._fix_class()
@@ -934,7 +934,7 @@
         #
         class CTypesEnum(CTypesInt):
             __slots__ = []
-            _reftypename = 'enum %s &' % name
+            _reftypename = '%s &' % name
 
             def _get_own_repr(self):
                 value = self._value
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -244,6 +244,10 @@
         self.forcename = forcename
         self.build_c_name_with_marker()
 
+    def get_official_name(self):
+        assert self.c_name_with_marker.endswith('&')
+        return self.c_name_with_marker[:-1]
+
 
 class StructOrUnion(StructOrUnionOrEnum):
     fixedlayout = None
@@ -357,7 +361,9 @@
     def build_backend_type(self, ffi, finishlist):
         self.check_not_partial()
         finishlist.append(self)
-        return global_cache(self, ffi, 'new_struct_type', self.name, key=self)
+        
+        return global_cache(self, ffi, 'new_struct_type',
+                            self.get_official_name(), key=self)
 
 
 class UnionType(StructOrUnion):
@@ -365,7 +371,8 @@
 
     def build_backend_type(self, ffi, finishlist):
         finishlist.append(self)
-        return global_cache(self, ffi, 'new_union_type', self.name, key=self)
+        return global_cache(self, ffi, 'new_union_type',
+                            self.get_official_name(), key=self)
 
 
 class EnumType(StructOrUnionOrEnum):
@@ -388,7 +395,8 @@
     def build_backend_type(self, ffi, finishlist):
         self.check_not_partial()
         base_btype = self.build_baseinttype(ffi, finishlist)
-        return global_cache(self, ffi, 'new_enum_type', self.name,
+        return global_cache(self, ffi, 'new_enum_type',
+                            self.get_official_name(),
                             self.enumerators, self.enumvalues,
                             base_btype, key=self)
 
diff --git a/lib_pypy/ctypes_config_cache/syslog.ctc.py b/lib_pypy/ctypes_config_cache/syslog.ctc.py
deleted file mode 100644
--- a/lib_pypy/ctypes_config_cache/syslog.ctc.py
+++ /dev/null
@@ -1,75 +0,0 @@
-"""
-'ctypes_configure' source for syslog.py.
-Run this to rebuild _syslog_cache.py.
-"""
-
-from ctypes_configure.configure import (configure,
-    ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger)
-import dumpcache
-
-
-_CONSTANTS = (
-    'LOG_EMERG',
-    'LOG_ALERT',
-    'LOG_CRIT',
-    'LOG_ERR',
-    'LOG_WARNING',
-    'LOG_NOTICE',
-    'LOG_INFO',
-    'LOG_DEBUG',
-
-    'LOG_PID',
-    'LOG_CONS',
-    'LOG_NDELAY',
-
-    'LOG_KERN',
-    'LOG_USER',
-    'LOG_MAIL',
-    'LOG_DAEMON',
-    'LOG_AUTH',
-    'LOG_LPR',
-    'LOG_LOCAL0',
-    'LOG_LOCAL1',
-    'LOG_LOCAL2',
-    'LOG_LOCAL3',
-    'LOG_LOCAL4',
-    'LOG_LOCAL5',
-    'LOG_LOCAL6',
-    'LOG_LOCAL7',
-)
-_OPTIONAL_CONSTANTS = (
-    'LOG_NOWAIT',
-    'LOG_PERROR',
-
-    'LOG_SYSLOG',
-    'LOG_CRON',
-    'LOG_UUCP',
-    'LOG_NEWS',
-)
-
-# Constant aliases if there are not defined
-_ALIAS = (
-    ('LOG_SYSLOG', 'LOG_DAEMON'),
-    ('LOG_CRON', 'LOG_DAEMON'),
-    ('LOG_NEWS', 'LOG_MAIL'),
-    ('LOG_UUCP', 'LOG_MAIL'),
-)
-
-class SyslogConfigure:
-    _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h'])
-for key in _CONSTANTS:
-    setattr(SyslogConfigure, key, ConstantInteger(key))
-for key in _OPTIONAL_CONSTANTS:
-    setattr(SyslogConfigure, key, DefinedConstantInteger(key))
-
-config = configure(SyslogConfigure)
-for key in _OPTIONAL_CONSTANTS:
-    if config[key] is None:
-        del config[key]
-for alias, key in _ALIAS:
-    config.setdefault(alias, config[key])
-
-all_constants = config.keys()
-all_constants.sort()
-config['ALL_CONSTANTS'] = tuple(all_constants)
-dumpcache.dumpcache2('syslog', config)
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,3 +1,4 @@
+import sys
 import _continuation
 
 __version__ = "0.4.0"
@@ -5,7 +6,7 @@
 # ____________________________________________________________
 # Exceptions
 
-class GreenletExit(Exception):
+class GreenletExit(BaseException):
     """This special exception does not propagate to the parent greenlet; it
 can be used to kill a single greenlet."""
 
@@ -46,16 +47,16 @@
         if parent is not None:
             self.parent = parent
 
-    def switch(self, *args):
+    def switch(self, *args, **kwds):
         "Switch execution to this greenlet, optionally passing the values "
         "given as argument(s).  Returns the value passed when switching back."
-        return self.__switch('switch', args)
+        return self.__switch('switch', (args, kwds))
 
     def throw(self, typ=GreenletExit, val=None, tb=None):
         "raise exception in greenlet, return value passed when switching back"
         return self.__switch('throw', typ, val, tb)
 
-    def __switch(target, methodname, *args):
+    def __switch(target, methodname, *baseargs):
         current = getcurrent()
         #
         while not (target.__main or _continulet.is_pending(target)):
@@ -65,9 +66,9 @@
                     greenlet_func = _greenlet_start
                 else:
                     greenlet_func = _greenlet_throw
-                _continulet.__init__(target, greenlet_func, *args)
+                _continulet.__init__(target, greenlet_func, *baseargs)
                 methodname = 'switch'
-                args = ()
+                baseargs = ()
                 target.__started = True
                 break
             # already done, go to the parent instead
@@ -75,14 +76,27 @@
             # up the 'parent' explicitly.  Good enough, because a Ctrl-C
             # will show that the program is caught in this loop here.)
             target = target.parent
+            # convert a "raise GreenletExit" into "return GreenletExit"
+            if methodname == 'throw':
+                try:
+                    raise baseargs[0], baseargs[1]
+                except GreenletExit, e:
+                    methodname = 'switch'
+                    baseargs = (((e,), {}),)
+                except:
+                    baseargs = sys.exc_info()[:2] + baseargs[2:]
         #
         try:
             unbound_method = getattr(_continulet, methodname)
-            args = unbound_method(current, *args, to=target)
+            args, kwds = unbound_method(current, *baseargs, to=target)
         finally:
             _tls.current = current
         #
-        if len(args) == 1:
+        if kwds:
+            if args:
+                return args, kwds
+            return kwds
+        elif len(args) == 1:
             return args[0]
         else:
             return args
@@ -129,18 +143,22 @@
     _tls.current = gmain
 
 def _greenlet_start(greenlet, args):
+    args, kwds = args
     _tls.current = greenlet
     try:
-        res = greenlet.run(*args)
+        res = greenlet.run(*args, **kwds)
     except GreenletExit, e:
         res = e
     finally:
         _continuation.permute(greenlet, greenlet.parent)
-    return (res,)
+    return ((res,), None)
 
 def _greenlet_throw(greenlet, exc, value, tb):
     _tls.current = greenlet
     try:
         raise exc, value, tb
+    except GreenletExit, e:
+        res = e
     finally:
         _continuation.permute(greenlet, greenlet.parent)
+    return ((res,), None)
diff --git a/lib_pypy/grp.py b/lib_pypy/grp.py
--- a/lib_pypy/grp.py
+++ b/lib_pypy/grp.py
@@ -8,6 +8,7 @@
 
 from ctypes import Structure, c_char_p, c_int, POINTER
 from ctypes_support import standard_c_lib as libc
+import _structseq
 
 try: from __pypy__ import builtinify
 except ImportError: builtinify = lambda f: f
@@ -23,32 +24,13 @@
         ('gr_mem', POINTER(c_char_p)),
         )
 
-class Group(object):
-    def __init__(self, gr_name, gr_passwd, gr_gid, gr_mem):
-        self.gr_name = gr_name
-        self.gr_passwd = gr_passwd
-        self.gr_gid = gr_gid
-        self.gr_mem = gr_mem
+class struct_group:
+    __metaclass__ = _structseq.structseqtype
 
-    def __getitem__(self, item):
-        if item == 0:
-            return self.gr_name
-        elif item == 1:
-            return self.gr_passwd
-        elif item == 2:
-            return self.gr_gid
-        elif item == 3:
-            return self.gr_mem
-        else:
-            raise IndexError(item)
-
-    def __len__(self):
-        return 4
-
-    def __repr__(self):
-        return str((self.gr_name, self.gr_passwd, self.gr_gid, self.gr_mem))
-
-    # whatever else...
+    gr_name   = _structseq.structseqfield(0)
+    gr_passwd = _structseq.structseqfield(1)
+    gr_gid    = _structseq.structseqfield(2)
+    gr_mem    = _structseq.structseqfield(3)
 
 libc.getgrgid.argtypes = [gid_t]
 libc.getgrgid.restype = POINTER(GroupStruct)
@@ -71,8 +53,8 @@
     while res.contents.gr_mem[i]:
         mem.append(res.contents.gr_mem[i])
         i += 1
-    return Group(res.contents.gr_name, res.contents.gr_passwd,
-                 res.contents.gr_gid, mem)
+    return struct_group((res.contents.gr_name, res.contents.gr_passwd,
+                         res.contents.gr_gid, mem))
 
 @builtinify
 def getgrgid(gid):
diff --git a/lib_pypy/pyrepl/curses.py b/lib_pypy/pyrepl/curses.py
--- a/lib_pypy/pyrepl/curses.py
+++ b/lib_pypy/pyrepl/curses.py
@@ -19,11 +19,15 @@
 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
-# avoid importing the whole curses, if possible
-try:
+# If we are running on top of pypy, we import only _minimal_curses.
+# Don't try to fall back to _curses, because that's going to use cffi
+# and fall again more loudly.
+import sys
+if '__pypy__' in sys.builtin_module_names:
     # pypy case
     import _minimal_curses as _curses
-except ImportError:
+else:
+    # cpython case
     try:
         import _curses
     except ImportError:
diff --git a/lib_pypy/readline.egg-info b/lib_pypy/readline.egg-info
new file mode 100644
--- /dev/null
+++ b/lib_pypy/readline.egg-info


More information about the pypy-commit mailing list