[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