[pypy-commit] pypy framestate: hg merge default
rlamy
noreply at buildbot.pypy.org
Thu Feb 12 20:27:50 CET 2015
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r75842:2a0e866552f1
Date: 2015-02-12 19:25 +0000
http://bitbucket.org/pypy/pypy/changeset/2a0e866552f1/
Log: hg merge default
diff too long, truncating to 2000 out of 40693 lines
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -7,10 +7,7 @@
9b623bc48b5950cf07184462a0e48f2c4df0d720 pypy-2.1-beta1-arm
ab0dd631c22015ed88e583d9fdd4c43eebf0be21 pypy-2.1-beta1-arm
20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0
-20e51c4389ed4469b66bb9d6289ce0ecfc82c4b9 release-2.3.0
-0000000000000000000000000000000000000000 release-2.3.0
394146e9bb673514c61f0150ab2013ccf78e8de7 release-2.3
32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1
-32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.2=3.1
-0000000000000000000000000000000000000000 release-2.2=3.1
+10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -28,7 +28,7 @@
DEALINGS IN THE SOFTWARE.
-PyPy Copyright holders 2003-2014
+PyPy Copyright holders 2003-2015
-----------------------------------
Except when otherwise stated (look for LICENSE files or information at
@@ -42,19 +42,19 @@
Amaury Forgeot d'Arc
Samuele Pedroni
Alex Gaynor
+ Brian Kearns
+ Matti Picus
+ Philip Jenvey
Michael Hudson
David Schneider
- Matti Picus
- Brian Kearns
- Philip Jenvey
Holger Krekel
Christian Tismer
Hakan Ardo
Benjamin Peterson
Manuel Jacob
+ Ronan Lamy
Anders Chrigstrom
Eric van Riet Paap
- Ronan Lamy
Wim Lavrijsen
Richard Emslie
Alexander Schremmer
@@ -68,9 +68,9 @@
Camillo Bruni
Laura Creighton
Toon Verwaest
+ Romain Guillebert
Leonardo Santagada
Seo Sanghyeon
- Romain Guillebert
Justin Peel
Ronny Pfannschmidt
David Edelsohn
@@ -91,15 +91,16 @@
Michal Bendowski
Jan de Mooij
stian
+ Tyler Wade
Michael Foord
Stephan Diehl
- Tyler Wade
Stefan Schwarzer
Valentino Volonghi
Tomek Meka
Patrick Maupin
Bob Ippolito
Bruno Gola
+ David Malcolm
Jean-Paul Calderone
Timo Paulssen
Squeaky
@@ -108,18 +109,19 @@
Marius Gedminas
Martin Matusiak
Konstantin Lopuhin
+ Wenzhu Man
John Witulski
- Wenzhu Man
+ Laurence Tratt
+ Ivan Sichmann Freitas
Greg Price
Dario Bertini
Mark Pearse
Simon Cross
- Ivan Sichmann Freitas
Andreas Stührk
+ Stefano Rivera
Jean-Philippe St. Pierre
Guido van Rossum
Pavel Vinogradov
- Stefano Rivera
Paweł Piotr Przeradowski
Paul deGrandis
Ilya Osadchiy
@@ -129,7 +131,6 @@
tav
Taavi Burns
Georg Brandl
- Laurence Tratt
Bert Freudenberg
Stian Andreassen
Wanja Saatkamp
@@ -141,13 +142,12 @@
Jeremy Thurgood
Rami Chowdhury
Tobias Pape
- David Malcolm
Eugene Oden
Henry Mason
Vasily Kuznetsov
Preston Timmons
+ David Ripton
Jeff Terrace
- David Ripton
Dusty Phillips
Lukas Renggli
Guenter Jantzen
@@ -166,13 +166,16 @@
Gintautas Miliauskas
Michael Twomey
Lucian Branescu Mihaila
+ Yichao Yu
Gabriel Lavoie
Olivier Dormond
Jared Grubb
Karl Bartel
+ Wouter van Heyst
Brian Dorsey
Victor Stinner
Andrews Medina
+ anatoly techtonik
Stuart Williams
Jasper Schulz
Christian Hudon
@@ -182,12 +185,11 @@
Michael Cheng
Justas Sadzevicius
Gasper Zejn
- anatoly techtonik
Neil Shepperd
+ Stanislaw Halik
Mikael Schönenberg
Elmo M?ntynen
Jonathan David Riehl
- Stanislaw Halik
Anders Qvist
Corbin Simpson
Chirag Jadwani
@@ -196,10 +198,13 @@
Vincent Legoll
Alan McIntyre
Alexander Sedov
+ Attila Gobi
Christopher Pope
Christian Tismer
Marc Abramowitz
Dan Stromberg
+ Arjun Naik
+ Valentina Mukhamedzhanova
Stefano Parmesan
Alexis Daboville
Jens-Uwe Mager
@@ -213,8 +218,6 @@
Sylvain Thenault
Nathan Taylor
Vladimir Kryachko
- Arjun Naik
- Attila Gobi
Jacek Generowicz
Alejandro J. Cura
Jacob Oscarson
@@ -222,22 +225,23 @@
Ryan Gonzalez
Ian Foote
Kristjan Valur Jonsson
+ David Lievens
Neil Blakey-Milner
Lutz Paelike
Lucio Torre
Lars Wassermann
- Valentina Mukhamedzhanova
Henrik Vendelbo
Dan Buch
Miguel de Val Borro
Artur Lisiecki
Sergey Kishchenko
- Yichao Yu
Ignas Mikalajunas
Christoph Gerum
Martin Blais
Lene Wagner
Tomo Cocoa
+ Toni Mattis
+ Lucas Stadler
roberto at goyle
Yury V. Zaytsev
Anna Katrina Dominguez
@@ -265,23 +269,30 @@
Stephan Busemann
Rafał Gałczyński
Christian Muirhead
+ Berker Peksag
James Lan
shoma hosaka
- Daniel Neuh?user
- Matthew Miller
+ Daniel Neuhäuser
+ Ben Mather
+ halgari
+ Boglarka Vezer
+ Chris Pressey
Buck Golemon
Konrad Delong
Dinu Gherman
Chris Lambacher
coolbutuseless at gmail.com
+ Jim Baker
Rodrigo Araújo
- Jim Baker
+ Nikolaos-Digenis Karagiannis
James Robert
Armin Ronacher
Brett Cannon
+ Donald Stufft
yrttyr
aliceinwire
OlivierBlanvillain
+ Dan Sanders
Zooko Wilcox-O Hearn
Tomer Chachamu
Christopher Groskopf
@@ -295,6 +306,7 @@
Markus Unterwaditzer
Even Wiik Thomassen
jbs
+ squeaky
soareschen
Kurt Griffiths
Mike Bayer
@@ -306,6 +318,7 @@
Anna Ravencroft
Dan Crosta
Julien Phalip
+ Roman Podoliaka
Dan Loewenherz
Heinrich-Heine University, Germany
diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py
--- a/lib-python/2.7/collections.py
+++ b/lib-python/2.7/collections.py
@@ -17,6 +17,10 @@
except ImportError:
assert '__pypy__' not in _sys.builtin_module_names
newdict = lambda _ : {}
+try:
+ from __pypy__ import reversed_dict
+except ImportError:
+ reversed_dict = lambda d: reversed(d.keys())
try:
from thread import get_ident as _get_ident
@@ -29,142 +33,35 @@
################################################################################
class OrderedDict(dict):
- 'Dictionary that remembers insertion order'
- # An inherited dict maps keys to values.
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
- # The remaining methods are order-aware.
- # Big-O running times for all methods are the same as regular dictionaries.
+ '''Dictionary that remembers insertion order.
- # The internal self.__map dict maps keys to links in a doubly linked list.
- # The circular doubly linked list starts and ends with a sentinel element.
- # The sentinel element never gets deleted (this simplifies the algorithm).
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
+ In PyPy all dicts are ordered anyway. This is mostly useful as a
+ placeholder to mean "this dict must be ordered even on CPython".
- def __init__(self, *args, **kwds):
- '''Initialize an ordered dictionary. The signature is the same as
- regular dictionaries, but keyword arguments are not recommended because
- their insertion order is arbitrary.
-
- '''
- if len(args) > 1:
- raise TypeError('expected at most 1 arguments, got %d' % len(args))
- try:
- self.__root
- except AttributeError:
- self.__root = root = [] # sentinel node
- root[:] = [root, root, None]
- self.__map = {}
- self.__update(*args, **kwds)
-
- def __setitem__(self, key, value, dict_setitem=dict.__setitem__):
- 'od.__setitem__(i, y) <==> od[i]=y'
- # Setting a new item creates a new link at the end of the linked list,
- # and the inherited dictionary is updated with the new key/value pair.
- if key not in self:
- root = self.__root
- last = root[0]
- last[1] = root[0] = self.__map[key] = [last, root, key]
- return dict_setitem(self, key, value)
-
- def __delitem__(self, key, dict_delitem=dict.__delitem__):
- 'od.__delitem__(y) <==> del od[y]'
- # Deleting an existing item uses self.__map to find the link which gets
- # removed by updating the links in the predecessor and successor nodes.
- dict_delitem(self, key)
- link_prev, link_next, _ = self.__map.pop(key)
- link_prev[1] = link_next # update link_prev[NEXT]
- link_next[0] = link_prev # update link_next[PREV]
-
- def __iter__(self):
- 'od.__iter__() <==> iter(od)'
- # Traverse the linked list in order.
- root = self.__root
- curr = root[1] # start at the first node
- while curr is not root:
- yield curr[2] # yield the curr[KEY]
- curr = curr[1] # move to next node
+ Known difference: iterating over an OrderedDict which is being
+ concurrently modified raises RuntimeError in PyPy. In CPython
+ instead we get some behavior that appears reasonable in some
+ cases but is nonsensical in other cases. This is officially
+ forbidden by the CPython docs, so we forbid it explicitly for now.
+ '''
def __reversed__(self):
- 'od.__reversed__() <==> reversed(od)'
- # Traverse the linked list in reverse order.
- root = self.__root
- curr = root[0] # start at the last node
- while curr is not root:
- yield curr[2] # yield the curr[KEY]
- curr = curr[0] # move to previous node
-
- def clear(self):
- 'od.clear() -> None. Remove all items from od.'
- root = self.__root
- root[:] = [root, root, None]
- self.__map.clear()
- dict.clear(self)
-
- # -- the following methods do not depend on the internal structure --
-
- def keys(self):
- 'od.keys() -> list of keys in od'
- return list(self)
-
- def values(self):
- 'od.values() -> list of values in od'
- return [self[key] for key in self]
-
- def items(self):
- 'od.items() -> list of (key, value) pairs in od'
- return [(key, self[key]) for key in self]
-
- def iterkeys(self):
- 'od.iterkeys() -> an iterator over the keys in od'
- return iter(self)
-
- def itervalues(self):
- 'od.itervalues -> an iterator over the values in od'
- for k in self:
- yield self[k]
-
- def iteritems(self):
- 'od.iteritems -> an iterator over the (key, value) pairs in od'
- for k in self:
- yield (k, self[k])
-
- update = MutableMapping.update
-
- __update = update # let subclasses override update without breaking __init__
-
- __marker = object()
-
- def pop(self, key, default=__marker):
- '''od.pop(k[,d]) -> v, remove specified key and return the corresponding
- value. If key is not found, d is returned if given, otherwise KeyError
- is raised.
-
- '''
- if key in self:
- result = self[key]
- del self[key]
- return result
- if default is self.__marker:
- raise KeyError(key)
- return default
-
- def setdefault(self, key, default=None):
- 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od'
- if key in self:
- return self[key]
- self[key] = default
- return default
+ return reversed_dict(self)
def popitem(self, last=True):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
'''
- if not self:
- raise KeyError('dictionary is empty')
- key = next(reversed(self) if last else iter(self))
- value = self.pop(key)
- return key, value
+ if last:
+ return dict.popitem(self)
+ else:
+ it = dict.__iter__(self)
+ try:
+ k = it.next()
+ except StopIteration:
+ raise KeyError('dictionary is empty')
+ return (k, self.pop(k))
def __repr__(self, _repr_running={}):
'od.__repr__() <==> repr(od)'
@@ -183,8 +80,6 @@
'Return state information for pickling'
items = [[k, self[k]] for k in self]
inst_dict = vars(self).copy()
- for k in vars(OrderedDict()):
- inst_dict.pop(k, None)
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
@@ -193,17 +88,6 @@
'od.copy() -> a shallow copy of od'
return self.__class__(self)
- @classmethod
- def fromkeys(cls, iterable, value=None):
- '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.
- If not specified, the value defaults to None.
-
- '''
- self = cls()
- for key in iterable:
- self[key] = value
- return self
-
def __eq__(self, other):
'''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive
while comparison to a regular mapping is order-insensitive.
diff --git a/lib-python/2.7/ctypes/test/test_frombuffer.py b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -2,7 +2,6 @@
import array
import gc
import unittest
-from ctypes.test import xfail
class X(Structure):
_fields_ = [("c_int", c_int)]
@@ -11,7 +10,6 @@
self._init_called = True
class Test(unittest.TestCase):
- @xfail
def test_fom_buffer(self):
a = array.array("i", range(16))
x = (c_int * 16).from_buffer(a)
@@ -34,10 +32,9 @@
del a; gc.collect(); gc.collect(); gc.collect()
self.assertEqual(x[:], expected)
- self.assertRaises(TypeError,
+ self.assertRaises((TypeError, ValueError),
(c_char * 16).from_buffer, "a" * 16)
- @xfail
def test_fom_buffer_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer(a, sizeof(c_int))
@@ -46,7 +43,6 @@
self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int)))
self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int)))
- @xfail
def test_from_buffer_copy(self):
a = array.array("i", range(16))
x = (c_int * 16).from_buffer_copy(a)
@@ -71,7 +67,6 @@
x = (c_char * 16).from_buffer_copy("a" * 16)
self.assertEqual(x[:], "a" * 16)
- @xfail
def test_fom_buffer_copy_with_offset(self):
a = array.array("i", range(16))
x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
diff --git a/lib-python/2.7/distutils/unixccompiler.py b/lib-python/2.7/distutils/unixccompiler.py
--- a/lib-python/2.7/distutils/unixccompiler.py
+++ b/lib-python/2.7/distutils/unixccompiler.py
@@ -58,7 +58,7 @@
executables = {'preprocessor' : None,
'compiler' : ["cc"],
'compiler_so' : ["cc"],
- 'compiler_cxx' : ["cc"],
+ 'compiler_cxx' : ["c++"], # pypy: changed, 'cc' is bogus
'linker_so' : ["cc", "-shared"],
'linker_exe' : ["cc"],
'archiver' : ["ar", "-cr"],
diff --git a/lib-python/2.7/sqlite3/test/dbapi.py b/lib-python/2.7/sqlite3/test/dbapi.py
--- a/lib-python/2.7/sqlite3/test/dbapi.py
+++ b/lib-python/2.7/sqlite3/test/dbapi.py
@@ -478,6 +478,29 @@
except TypeError:
pass
+ def CheckCurDescription(self):
+ self.cu.execute("select * from test")
+
+ actual = self.cu.description
+ expected = [
+ ('id', None, None, None, None, None, None),
+ ('name', None, None, None, None, None, None),
+ ('income', None, None, None, None, None, None),
+ ]
+ self.assertEqual(expected, actual)
+
+ def CheckCurDescriptionVoidStatement(self):
+ self.cu.execute("insert into test(name) values (?)", ("foo",))
+ self.assertIsNone(self.cu.description)
+
+ def CheckCurDescriptionWithoutStatement(self):
+ cu = self.cx.cursor()
+ try:
+ self.assertIsNone(cu.description)
+ finally:
+ cu.close()
+
+
@unittest.skipUnless(threading, 'This test requires threading.')
class ThreadTests(unittest.TestCase):
def setUp(self):
diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py
--- a/lib-python/2.7/subprocess.py
+++ b/lib-python/2.7/subprocess.py
@@ -1589,7 +1589,7 @@
'copyfile' in caller.f_globals):
dest_dir = sys.pypy_resolvedirof(target_executable)
src_dir = sys.pypy_resolvedirof(sys.executable)
- for libname in ['libpypy-c.so']:
+ for libname in ['libpypy-c.so', 'libpypy-c.dylib']:
dest_library = os.path.join(dest_dir, libname)
src_library = os.path.join(src_dir, libname)
if os.path.exists(src_library):
diff --git a/lib-python/2.7/test/test_audioop.py b/lib-python/2.7/test/test_audioop.py
--- a/lib-python/2.7/test/test_audioop.py
+++ b/lib-python/2.7/test/test_audioop.py
@@ -2,7 +2,7 @@
import sys
import unittest
import struct
-from test.test_support import run_unittest, impl_detail
+from test.test_support import run_unittest
formats = {
@@ -183,7 +183,6 @@
self.assertEqual(audioop.lin2lin(datas[4], 4, 2),
packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1))
- @impl_detail(pypy=False)
def test_adpcm2lin(self):
self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 1, None),
(b'\x00\x00\x00\xff\x00\xff', (-179, 40)))
@@ -198,7 +197,6 @@
self.assertEqual(audioop.adpcm2lin(b'\0' * 5, w, None),
(b'\0' * w * 10, (0, 0)))
- @impl_detail(pypy=False)
def test_lin2adpcm(self):
self.assertEqual(audioop.lin2adpcm(datas[1], 1, None),
(b'\x07\x7f\x7f', (-221, 39)))
@@ -212,7 +210,6 @@
self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None),
(b'\0' * 5, (0, 0)))
- @impl_detail(pypy=False)
def test_lin2alaw(self):
self.assertEqual(audioop.lin2alaw(datas[1], 1),
b'\xd5\x87\xa4\x24\xaa\x2a\x5a')
@@ -221,7 +218,6 @@
self.assertEqual(audioop.lin2alaw(datas[4], 4),
b'\xd5\x87\xa4\x24\xaa\x2a\x55')
- @impl_detail(pypy=False)
def test_alaw2lin(self):
encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\
b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff'
@@ -236,7 +232,6 @@
decoded = audioop.alaw2lin(encoded, w)
self.assertEqual(audioop.lin2alaw(decoded, w), encoded)
- @impl_detail(pypy=False)
def test_lin2ulaw(self):
self.assertEqual(audioop.lin2ulaw(datas[1], 1),
b'\xff\xad\x8e\x0e\x80\x00\x67')
@@ -245,7 +240,6 @@
self.assertEqual(audioop.lin2ulaw(datas[4], 4),
b'\xff\xad\x8e\x0e\x80\x00\x7e')
- @impl_detail(pypy=False)
def test_ulaw2lin(self):
encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\
b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff'
@@ -360,7 +354,6 @@
self.assertRaises(audioop.error,
audioop.findmax, ''.join( chr(x) for x in xrange(256)), -2392392)
- @impl_detail(pypy=False)
def test_issue7673(self):
state = None
for data, size in INVALID_DATA:
@@ -385,7 +378,6 @@
self.assertRaises(audioop.error, audioop.lin2alaw, data, size)
self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state)
- @impl_detail(pypy=False)
def test_wrongsize(self):
data = b'abcdefgh'
state = None
diff --git a/lib-python/2.7/test/test_collections.py b/lib-python/2.7/test/test_collections.py
--- a/lib-python/2.7/test/test_collections.py
+++ b/lib-python/2.7/test/test_collections.py
@@ -578,7 +578,12 @@
def __repr__(self):
return "MySet(%s)" % repr(list(self))
s = MySet([5,43,2,1])
- self.assertEqual(s.pop(), 1)
+ # changed from CPython 2.7: it was "s.pop() == 1" but I see
+ # nothing that guarantees a particular order here. In the
+ # 'all_ordered_dicts' branch of PyPy (or with OrderedDict
+ # instead of sets), it consistently returns 5, but this test
+ # should not rely on this or any other order.
+ self.assert_(s.pop() in [5,43,2,1])
def test_issue8750(self):
empty = WithSet()
@@ -1010,8 +1015,9 @@
c=3, e=5).items()), pairs) # mixed input
# make sure no positional args conflict with possible kwdargs
- self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
- ['self'])
+ if '__init__' in OrderedDict.__dict__: # absent in PyPy
+ self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
+ ['self'])
# Make sure that direct calls to __init__ do not clear previous contents
d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
@@ -1108,6 +1114,16 @@
od.popitem()
self.assertEqual(len(od), 0)
+ def test_popitem_first(self):
+ pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
+ shuffle(pairs)
+ od = OrderedDict(pairs)
+ while pairs:
+ self.assertEqual(od.popitem(last=False), pairs.pop(0))
+ with self.assertRaises(KeyError):
+ od.popitem(last=False)
+ self.assertEqual(len(od), 0)
+
def test_pop(self):
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
shuffle(pairs)
@@ -1179,7 +1195,11 @@
od = OrderedDict(pairs)
# yaml.dump(od) -->
# '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n'
- self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1]))
+
+ # PyPy bug fix: added [0] at the end of this line, because the
+ # test is really about the 2-tuples that need to be 2-lists
+ # inside the list of 6 of them
+ self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1][0]))
def test_reduce_not_too_fat(self):
# do not save instance dictionary if not needed
@@ -1189,6 +1209,16 @@
od.x = 10
self.assertEqual(len(od.__reduce__()), 3)
+ def test_reduce_exact_output(self):
+ # PyPy: test that __reduce__() produces the exact same answer as
+ # CPython does, even though in the 'all_ordered_dicts' branch we
+ # have to emulate it.
+ pairs = [['c', 1], ['b', 2], ['d', 4]]
+ od = OrderedDict(pairs)
+ self.assertEqual(od.__reduce__(), (OrderedDict, (pairs,)))
+ od.x = 10
+ self.assertEqual(od.__reduce__(), (OrderedDict, (pairs,), {'x': 10}))
+
def test_repr(self):
od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])
self.assertEqual(repr(od),
diff --git a/lib-python/2.7/test/test_xml_etree.py b/lib-python/2.7/test/test_xml_etree.py
--- a/lib-python/2.7/test/test_xml_etree.py
+++ b/lib-python/2.7/test/test_xml_etree.py
@@ -225,9 +225,9 @@
>>> element.remove(subelement)
>>> serialize(element) # 5
'<tag key="value" />'
- >>> element.remove(subelement)
+ >>> element.remove(subelement) # doctest: +ELLIPSIS
Traceback (most recent call last):
- ValueError: list.remove(x): x not in list
+ ValueError: list.remove(...
>>> serialize(element) # 6
'<tag key="value" />'
>>> element[0:0] = [subelement, subelement, subelement]
diff --git a/lib-python/stdlib-upgrade.txt b/lib-python/stdlib-upgrade.txt
--- a/lib-python/stdlib-upgrade.txt
+++ b/lib-python/stdlib-upgrade.txt
@@ -7,7 +7,7 @@
1. check out the branch vendor/stdlib
2. upgrade the files there
-3. update stdlib-versions.txt with the output of hg -id from the cpython repo
+3. update stdlib-version.txt with the output of hg -id from the cpython repo
4. commit
5. update to default/py3k
6. create a integration branch for the new stdlib
diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py
--- a/lib_pypy/_ctypes/basics.py
+++ b/lib_pypy/_ctypes/basics.py
@@ -83,6 +83,37 @@
def in_dll(self, dll, name):
return self.from_address(dll._handle.getaddressindll(name))
+ def from_buffer(self, obj, offset=0):
+ size = self._sizeofinstances()
+ buf = buffer(obj, offset, size)
+ if len(buf) < size:
+ raise ValueError(
+ "Buffer size too small (%d instead of at least %d bytes)"
+ % (len(buf) + offset, size + offset))
+ raw_addr = buf._pypy_raw_address()
+ result = self.from_address(raw_addr)
+ result._ensure_objects()['ffffffff'] = obj
+ return result
+
+ def from_buffer_copy(self, obj, offset=0):
+ size = self._sizeofinstances()
+ buf = buffer(obj, offset, size)
+ if len(buf) < size:
+ raise ValueError(
+ "Buffer size too small (%d instead of at least %d bytes)"
+ % (len(buf) + offset, size + offset))
+ result = self()
+ dest = result._buffer.buffer
+ try:
+ raw_addr = buf._pypy_raw_address()
+ except ValueError:
+ _rawffi.rawstring2charp(dest, buf)
+ else:
+ from ctypes import memmove
+ memmove(dest, raw_addr, size)
+ return result
+
+
class CArgObject(object):
""" simple wrapper around buffer, just for the case of freeing
it afterwards
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
@@ -1,3 +1,4 @@
+import sys
import _rawffi
from _ctypes.basics import _CData, _CDataMeta, keepalive_key,\
store_reference, ensure_objects, CArgObject
@@ -178,6 +179,8 @@
instance = StructOrUnion.__new__(self)
if isinstance(address, _rawffi.StructureInstance):
address = address.buffer
+ # fix the address: turn it into as unsigned, in case it is negative
+ address = address & (sys.maxint * 2 + 1)
instance.__dict__['_buffer'] = self._ffistruct.fromaddress(address)
return instance
diff --git a/lib_pypy/_functools.py b/lib_pypy/_functools.py
--- a/lib_pypy/_functools.py
+++ b/lib_pypy/_functools.py
@@ -9,7 +9,10 @@
of the given arguments and keywords.
"""
- def __init__(self, func, *args, **keywords):
+ def __init__(self, *args, **keywords):
+ if not args:
+ raise TypeError('__init__() takes at least 2 arguments (1 given)')
+ func, args = args[0], args[1:]
if not callable(func):
raise TypeError("the first argument must be callable")
self._func = func
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -270,11 +270,14 @@
_ffi.cdef("int sqlite3_enable_load_extension(sqlite3 *db, int onoff);")
if sys.platform.startswith('freebsd'):
+ import os
+ import os.path
+ _localbase = os.environ.get('LOCALBASE', '/usr/local')
_lib = _ffi.verify("""
#include <sqlite3.h>
""", libraries=['sqlite3'],
- include_dirs=['/usr/local/include'],
- library_dirs=['/usr/local/lib']
+ include_dirs=[os.path.join(_localbase, 'include')],
+ library_dirs=[os.path.join(_localbase, 'lib')]
)
else:
_lib = _ffi.verify("""
@@ -1175,8 +1178,9 @@
try:
return self.__description
except AttributeError:
- self.__description = self.__statement._get_description()
- return self.__description
+ if self.__statement:
+ self.__description = self.__statement._get_description()
+ return self.__description
description = property(__get_description)
def __get_lastrowid(self):
diff --git a/lib_pypy/audioop.py b/lib_pypy/audioop.py
--- a/lib_pypy/audioop.py
+++ b/lib_pypy/audioop.py
@@ -1,12 +1,11 @@
-from __future__ import division
import __builtin__ as builtins
import math
import struct
from fractions import gcd
-from ctypes import create_string_buffer
+from cffi import FFI
-_buffer = buffer
+_buffer = memoryview
class error(Exception):
@@ -149,7 +148,7 @@
def _sum2(cp1, cp2, length):
size = 2
return sum(getsample(cp1, size, i) * getsample(cp2, size, i)
- for i in range(length))
+ for i in range(length)) + 0.0
def findfit(cp1, cp2):
@@ -328,13 +327,14 @@
_check_params(len(cp), size)
clip = _get_clipfn(size)
- result = create_string_buffer(len(cp))
+ rv = ffi.new("unsigned char[]", len(cp))
+ result = ffi.buffer(rv)
for i, sample in enumerate(_get_samples(cp, size)):
sample = clip(int(sample * factor))
_put_sample(result, size, i, sample)
- return result.raw
+ return result[:]
def tomono(cp, size, fac1, fac2):
@@ -343,7 +343,8 @@
sample_count = _sample_count(cp, size)
- result = create_string_buffer(len(cp) // 2)
+ rv = ffi.new("unsigned char[]", len(cp) // 2)
+ result = ffi.buffer(rv)
for i in range(0, sample_count, 2):
l_sample = getsample(cp, size, i)
@@ -354,7 +355,7 @@
_put_sample(result, size, i // 2, sample)
- return result.raw
+ return result[:]
def tostereo(cp, size, fac1, fac2):
@@ -362,7 +363,8 @@
sample_count = _sample_count(cp, size)
- result = create_string_buffer(len(cp) * 2)
+ rv = ffi.new("unsigned char[]", len(cp) * 2)
+ result = ffi.buffer(rv)
clip = _get_clipfn(size)
for i in range(sample_count):
@@ -374,7 +376,7 @@
_put_sample(result, size, i * 2, l_sample)
_put_sample(result, size, i * 2 + 1, r_sample)
- return result.raw
+ return result[:]
def add(cp1, cp2, size):
@@ -385,7 +387,8 @@
clip = _get_clipfn(size)
sample_count = _sample_count(cp1, size)
- result = create_string_buffer(len(cp1))
+ rv = ffi.new("unsigned char[]", len(cp1))
+ result = ffi.buffer(rv)
for i in range(sample_count):
sample1 = getsample(cp1, size, i)
@@ -395,30 +398,32 @@
_put_sample(result, size, i, sample)
- return result.raw
+ return result[:]
def bias(cp, size, bias):
_check_params(len(cp), size)
- result = create_string_buffer(len(cp))
+ rv = ffi.new("unsigned char[]", len(cp))
+ result = ffi.buffer(rv)
for i, sample in enumerate(_get_samples(cp, size)):
sample = _overflow(sample + bias, size)
_put_sample(result, size, i, sample)
- return result.raw
+ return result[:]
def reverse(cp, size):
_check_params(len(cp), size)
sample_count = _sample_count(cp, size)
- result = create_string_buffer(len(cp))
+ rv = ffi.new("unsigned char[]", len(cp))
+ result = ffi.buffer(rv)
for i, sample in enumerate(_get_samples(cp, size)):
_put_sample(result, size, sample_count - i - 1, sample)
- return result.raw
+ return result[:]
def lin2lin(cp, size, size2):
@@ -429,7 +434,8 @@
return cp
new_len = (len(cp) // size) * size2
- result = create_string_buffer(new_len)
+ rv = ffi.new("unsigned char[]", new_len)
+ result = ffi.buffer(rv)
for i in range(_sample_count(cp, size)):
sample = _get_sample(cp, size, i)
@@ -444,7 +450,7 @@
sample = _overflow(sample, size2)
_put_sample(result, size2, i, sample)
- return result.raw
+ return result[:]
def ratecv(cp, size, nchannels, inrate, outrate, state, weightA=1, weightB=0):
@@ -489,7 +495,8 @@
ceiling = (q + 1) * outrate
nbytes = ceiling * bytes_per_frame
- result = create_string_buffer(nbytes)
+ rv = ffi.new("unsigned char[]", nbytes)
+ result = ffi.buffer(rv)
samples = _get_samples(cp, size)
out_i = 0
@@ -497,7 +504,7 @@
while d < 0:
if frame_count == 0:
samps = zip(prev_i, cur_i)
- retval = result.raw
+ retval = result[:]
# slice off extra bytes
trim_index = (out_i * bytes_per_frame) - len(retval)
@@ -528,25 +535,523 @@
d -= inrate
+ffi = FFI()
+ffi.cdef("""
+typedef short PyInt16;
+
+/* 2's complement (14-bit range) */
+unsigned char
+st_14linear2ulaw(PyInt16 pcm_val);
+PyInt16 st_ulaw2linear16(unsigned char);
+
+/* 2's complement (13-bit range) */
+unsigned char
+st_linear2alaw(PyInt16 pcm_val);
+PyInt16 st_alaw2linear16(unsigned char);
+
+
+void lin2adcpm(unsigned char* rv, unsigned char* cp, size_t len,
+ size_t size, int* state);
+void adcpm2lin(unsigned char* rv, unsigned char* cp, size_t len,
+ size_t size, int* state);
+""")
+
+# This code is directly copied from CPython file: Modules/audioop.c
+_AUDIOOP_C_MODULE = """
+typedef short PyInt16;
+typedef int Py_Int32;
+
+/* Code shamelessly stolen from sox, 12.17.7, g711.c
+** (c) Craig Reese, Joe Campbell and Jeff Poskanzer 1989 */
+
+/* From g711.c:
+ *
+ * December 30, 1994:
+ * Functions linear2alaw, linear2ulaw have been updated to correctly
+ * convert unquantized 16 bit values.
+ * Tables for direct u- to A-law and A- to u-law conversions have been
+ * corrected.
+ * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
+ * bli at cpk.auc.dk
+ *
+ */
+#define BIAS 0x84 /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
+#define QUANT_MASK (0xf) /* Quantization field mask. */
+#define SEG_SHIFT (4) /* Left shift for segment number. */
+#define SEG_MASK (0x70) /* Segment field mask. */
+
+static PyInt16 seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
+ 0x1FF, 0x3FF, 0x7FF, 0xFFF};
+static PyInt16 seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
+ 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
+
+static PyInt16
+search(PyInt16 val, PyInt16 *table, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (val <= *table++)
+ return (i);
+ }
+ return (size);
+}
+#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc])
+#define st_alaw2linear16(uc) (_st_alaw2linear16[uc])
+
+static PyInt16 _st_ulaw2linear16[256] = {
+ -32124, -31100, -30076, -29052, -28028, -27004, -25980,
+ -24956, -23932, -22908, -21884, -20860, -19836, -18812,
+ -17788, -16764, -15996, -15484, -14972, -14460, -13948,
+ -13436, -12924, -12412, -11900, -11388, -10876, -10364,
+ -9852, -9340, -8828, -8316, -7932, -7676, -7420,
+ -7164, -6908, -6652, -6396, -6140, -5884, -5628,
+ -5372, -5116, -4860, -4604, -4348, -4092, -3900,
+ -3772, -3644, -3516, -3388, -3260, -3132, -3004,
+ -2876, -2748, -2620, -2492, -2364, -2236, -2108,
+ -1980, -1884, -1820, -1756, -1692, -1628, -1564,
+ -1500, -1436, -1372, -1308, -1244, -1180, -1116,
+ -1052, -988, -924, -876, -844, -812, -780,
+ -748, -716, -684, -652, -620, -588, -556,
+ -524, -492, -460, -428, -396, -372, -356,
+ -340, -324, -308, -292, -276, -260, -244,
+ -228, -212, -196, -180, -164, -148, -132,
+ -120, -112, -104, -96, -88, -80, -72,
+ -64, -56, -48, -40, -32, -24, -16,
+ -8, 0, 32124, 31100, 30076, 29052, 28028,
+ 27004, 25980, 24956, 23932, 22908, 21884, 20860,
+ 19836, 18812, 17788, 16764, 15996, 15484, 14972,
+ 14460, 13948, 13436, 12924, 12412, 11900, 11388,
+ 10876, 10364, 9852, 9340, 8828, 8316, 7932,
+ 7676, 7420, 7164, 6908, 6652, 6396, 6140,
+ 5884, 5628, 5372, 5116, 4860, 4604, 4348,
+ 4092, 3900, 3772, 3644, 3516, 3388, 3260,
+ 3132, 3004, 2876, 2748, 2620, 2492, 2364,
+ 2236, 2108, 1980, 1884, 1820, 1756, 1692,
+ 1628, 1564, 1500, 1436, 1372, 1308, 1244,
+ 1180, 1116, 1052, 988, 924, 876, 844,
+ 812, 780, 748, 716, 684, 652, 620,
+ 588, 556, 524, 492, 460, 428, 396,
+ 372, 356, 340, 324, 308, 292, 276,
+ 260, 244, 228, 212, 196, 180, 164,
+ 148, 132, 120, 112, 104, 96, 88,
+ 80, 72, 64, 56, 48, 40, 32,
+ 24, 16, 8, 0
+};
+
+/*
+ * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
+ * stored in a unsigned char. This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 14-bits.
+ *
+ * In order to simplify the encoding process, the original linear magnitude
+ * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ * (33 - 8191). The result can be seen in the following encoding table:
+ *
+ * Biased Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 00000001wxyza 000wxyz
+ * 0000001wxyzab 001wxyz
+ * 000001wxyzabc 010wxyz
+ * 00001wxyzabcd 011wxyz
+ * 0001wxyzabcde 100wxyz
+ * 001wxyzabcdef 101wxyz
+ * 01wxyzabcdefg 110wxyz
+ * 1wxyzabcdefgh 111wxyz
+ *
+ * Each biased linear code has a leading 1 which identifies the segment
+ * number. The value of the segment number is equal to 7 minus the number
+ * of leading 0's. The quantization interval is directly available as the
+ * four bits wxyz. * The trailing bits (a - h) are ignored.
+ *
+ * Ordinarily the complement of the resulting code word is used for
+ * transmission, and so the code word is complemented before it is returned.
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_14linear2ulaw(PyInt16 pcm_val) /* 2's complement (14-bit range) */
+{
+ PyInt16 mask;
+ PyInt16 seg;
+ unsigned char uval;
+
+ /* The original sox code does this in the calling function, not here */
+ pcm_val = pcm_val >> 2;
+
+ /* u-law inverts all bits */
+ /* Get the sign and the magnitude of the value. */
+ if (pcm_val < 0) {
+ pcm_val = -pcm_val;
+ mask = 0x7F;
+ } else {
+ mask = 0xFF;
+ }
+ if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
+ pcm_val += (BIAS >> 2);
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_uend, 8);
+
+ /*
+ * Combine the sign, segment, quantization bits;
+ * and complement the code word.
+ */
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (unsigned char) (0x7F ^ mask);
+ else {
+ uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
+ return (uval ^ mask);
+ }
+
+}
+
+static PyInt16 _st_alaw2linear16[256] = {
+ -5504, -5248, -6016, -5760, -4480, -4224, -4992,
+ -4736, -7552, -7296, -8064, -7808, -6528, -6272,
+ -7040, -6784, -2752, -2624, -3008, -2880, -2240,
+ -2112, -2496, -2368, -3776, -3648, -4032, -3904,
+ -3264, -3136, -3520, -3392, -22016, -20992, -24064,
+ -23040, -17920, -16896, -19968, -18944, -30208, -29184,
+ -32256, -31232, -26112, -25088, -28160, -27136, -11008,
+ -10496, -12032, -11520, -8960, -8448, -9984, -9472,
+ -15104, -14592, -16128, -15616, -13056, -12544, -14080,
+ -13568, -344, -328, -376, -360, -280, -264,
+ -312, -296, -472, -456, -504, -488, -408,
+ -392, -440, -424, -88, -72, -120, -104,
+ -24, -8, -56, -40, -216, -200, -248,
+ -232, -152, -136, -184, -168, -1376, -1312,
+ -1504, -1440, -1120, -1056, -1248, -1184, -1888,
+ -1824, -2016, -1952, -1632, -1568, -1760, -1696,
+ -688, -656, -752, -720, -560, -528, -624,
+ -592, -944, -912, -1008, -976, -816, -784,
+ -880, -848, 5504, 5248, 6016, 5760, 4480,
+ 4224, 4992, 4736, 7552, 7296, 8064, 7808,
+ 6528, 6272, 7040, 6784, 2752, 2624, 3008,
+ 2880, 2240, 2112, 2496, 2368, 3776, 3648,
+ 4032, 3904, 3264, 3136, 3520, 3392, 22016,
+ 20992, 24064, 23040, 17920, 16896, 19968, 18944,
+ 30208, 29184, 32256, 31232, 26112, 25088, 28160,
+ 27136, 11008, 10496, 12032, 11520, 8960, 8448,
+ 9984, 9472, 15104, 14592, 16128, 15616, 13056,
+ 12544, 14080, 13568, 344, 328, 376, 360,
+ 280, 264, 312, 296, 472, 456, 504,
+ 488, 408, 392, 440, 424, 88, 72,
+ 120, 104, 24, 8, 56, 40, 216,
+ 200, 248, 232, 152, 136, 184, 168,
+ 1376, 1312, 1504, 1440, 1120, 1056, 1248,
+ 1184, 1888, 1824, 2016, 1952, 1632, 1568,
+ 1760, 1696, 688, 656, 752, 720, 560,
+ 528, 624, 592, 944, 912, 1008, 976,
+ 816, 784, 880, 848
+};
+
+/*
+ * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
+ * stored in a unsigned char. This function should only be called with
+ * the data shifted such that it only contains information in the lower
+ * 13-bits.
+ *
+ * Linear Input Code Compressed Code
+ * ------------------------ ---------------
+ * 0000000wxyza 000wxyz
+ * 0000001wxyza 001wxyz
+ * 000001wxyzab 010wxyz
+ * 00001wxyzabc 011wxyz
+ * 0001wxyzabcd 100wxyz
+ * 001wxyzabcde 101wxyz
+ * 01wxyzabcdef 110wxyz
+ * 1wxyzabcdefg 111wxyz
+ *
+ * For further information see John C. Bellamy's Digital Telephony, 1982,
+ * John Wiley & Sons, pps 98-111 and 472-476.
+ */
+static unsigned char
+st_linear2alaw(PyInt16 pcm_val) /* 2's complement (13-bit range) */
+{
+ PyInt16 mask;
+ short seg;
+ unsigned char aval;
+
+ /* The original sox code does this in the calling function, not here */
+ pcm_val = pcm_val >> 3;
+
+ /* A-law using even bit inversion */
+ if (pcm_val >= 0) {
+ mask = 0xD5; /* sign (7th) bit = 1 */
+ } else {
+ mask = 0x55; /* sign bit = 0 */
+ pcm_val = -pcm_val - 1;
+ }
+
+ /* Convert the scaled magnitude to segment number. */
+ seg = search(pcm_val, seg_aend, 8);
+
+ /* Combine the sign, segment, and quantization bits. */
+
+ if (seg >= 8) /* out of range, return maximum value. */
+ return (unsigned char) (0x7F ^ mask);
+ else {
+ aval = (unsigned char) seg << SEG_SHIFT;
+ if (seg < 2)
+ aval |= (pcm_val >> 1) & QUANT_MASK;
+ else
+ aval |= (pcm_val >> seg) & QUANT_MASK;
+ return (aval ^ mask);
+ }
+}
+/* End of code taken from sox */
+
+/* Intel ADPCM step variation table */
+static int indexTable[16] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+static int stepsizeTable[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+#define CHARP(cp, i) ((signed char *)(cp+i))
+#define SHORTP(cp, i) ((short *)(cp+i))
+#define LONGP(cp, i) ((Py_Int32 *)(cp+i))
+"""
+
+lib = ffi.verify(_AUDIOOP_C_MODULE + """
+void lin2adcpm(unsigned char* ncp, unsigned char* cp, size_t len,
+ size_t size, int* state)
+{
+ int step, outputbuffer = 0, bufferstep;
+ int val = 0;
+ int diff, vpdiff, sign, delta;
+ size_t i;
+ int valpred = state[0];
+ int index = state[1];
+
+ step = stepsizeTable[index];
+ bufferstep = 1;
+
+ for ( i=0; i < len; i += size ) {
+ if ( size == 1 ) val = ((int)*CHARP(cp, i)) << 8;
+ else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+ else if ( size == 4 ) val = ((int)*LONGP(cp, i)) >> 16;
+
+ /* Step 1 - compute difference with previous value */
+ diff = val - valpred;
+ sign = (diff < 0) ? 8 : 0;
+ if ( sign ) diff = (-diff);
+
+ /* Step 2 - Divide and clamp */
+ /* Note:
+ ** This code *approximately* computes:
+ ** delta = diff*4/step;
+ ** vpdiff = (delta+0.5)*step/4;
+ ** but in shift step bits are dropped. The net result of this
+ ** is that even if you have fast mul/div hardware you cannot
+ ** put it to good use since the fixup would be too expensive.
+ */
+ delta = 0;
+ vpdiff = (step >> 3);
+
+ if ( diff >= step ) {
+ delta = 4;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step ) {
+ delta |= 2;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step ) {
+ delta |= 1;
+ vpdiff += step;
+ }
+
+ /* Step 3 - Update previous value */
+ if ( sign )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ /* Step 4 - Clamp previous value to 16 bits */
+ if ( valpred > 32767 )
+ valpred = 32767;
+ else if ( valpred < -32768 )
+ valpred = -32768;
+
+ /* Step 5 - Assemble value, update index and step values */
+ delta |= sign;
+
+ index += indexTable[delta];
+ if ( index < 0 ) index = 0;
+ if ( index > 88 ) index = 88;
+ step = stepsizeTable[index];
+
+ /* Step 6 - Output value */
+ if ( bufferstep ) {
+ outputbuffer = (delta << 4) & 0xf0;
+ } else {
+ *ncp++ = (delta & 0x0f) | outputbuffer;
+ }
+ bufferstep = !bufferstep;
+ }
+ state[0] = valpred;
+ state[1] = index;
+}
+
+
+void adcpm2lin(unsigned char* ncp, unsigned char* cp, size_t len,
+ size_t size, int* state)
+{
+ int step, inputbuffer = 0, bufferstep;
+ int val = 0;
+ int diff, vpdiff, sign, delta;
+ size_t i;
+ int valpred = state[0];
+ int index = state[1];
+
+ step = stepsizeTable[index];
+ bufferstep = 0;
+
+ for ( i=0; i < len*size*2; i += size ) {
+ /* Step 1 - get the delta value and compute next index */
+ if ( bufferstep ) {
+ delta = inputbuffer & 0xf;
+ } else {
+ inputbuffer = *cp++;
+ delta = (inputbuffer >> 4) & 0xf;
+ }
+
+ bufferstep = !bufferstep;
+
+ /* Step 2 - Find new index value (for later) */
+ index += indexTable[delta];
+ if ( index < 0 ) index = 0;
+ if ( index > 88 ) index = 88;
+
+ /* Step 3 - Separate sign and magnitude */
+ sign = delta & 8;
+ delta = delta & 7;
+
+ /* Step 4 - Compute difference and new predicted value */
+ /*
+ ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment
+ ** in adpcm_coder.
+ */
+ vpdiff = step >> 3;
+ if ( delta & 4 ) vpdiff += step;
+ if ( delta & 2 ) vpdiff += step>>1;
+ if ( delta & 1 ) vpdiff += step>>2;
+
+ if ( sign )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ /* Step 5 - clamp output value */
+ if ( valpred > 32767 )
+ valpred = 32767;
+ else if ( valpred < -32768 )
+ valpred = -32768;
+
+ /* Step 6 - Update step value */
+ step = stepsizeTable[index];
+
+ /* Step 6 - Output value */
+ if ( size == 1 ) *CHARP(ncp, i) = (signed char)(valpred >> 8);
+ else if ( size == 2 ) *SHORTP(ncp, i) = (short)(valpred);
+ else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)(valpred<<16);
+ }
+ state[0] = valpred;
+ state[1] = index;
+}
+""")
+
+def _get_lin_samples(cp, size):
+ for sample in _get_samples(cp, size):
+ if size == 1:
+ yield sample << 8
+ elif size == 2:
+ yield sample
+ elif size == 4:
+ yield sample >> 16
+
+def _put_lin_sample(result, size, i, sample):
+ if size == 1:
+ sample >>= 8
+ elif size == 2:
+ pass
+ elif size == 4:
+ sample <<= 16
+ _put_sample(result, size, i, sample)
+
def lin2ulaw(cp, size):
- raise NotImplementedError()
+ _check_params(len(cp), size)
+ rv = ffi.new("unsigned char[]", _sample_count(cp, size))
+ for i, sample in enumerate(_get_lin_samples(cp, size)):
+ rv[i] = lib.st_14linear2ulaw(sample)
+ return ffi.buffer(rv)[:]
def ulaw2lin(cp, size):
- raise NotImplementedError()
+ _check_size(size)
+ rv = ffi.new("unsigned char[]", len(cp) * size)
+ result = ffi.buffer(rv)
+ for i, value in enumerate(cp):
+ sample = lib.st_ulaw2linear16(ord(value))
+ _put_lin_sample(result, size, i, sample)
+ return result[:]
def lin2alaw(cp, size):
- raise NotImplementedError()
+ _check_params(len(cp), size)
+ rv = ffi.new("unsigned char[]", _sample_count(cp, size))
+ for i, sample in enumerate(_get_lin_samples(cp, size)):
+ rv[i] = lib.st_linear2alaw(sample)
+ return ffi.buffer(rv)[:]
def alaw2lin(cp, size):
- raise NotImplementedError()
+ _check_size(size)
+ rv = ffi.new("unsigned char[]", len(cp) * size)
+ result = ffi.buffer(rv)
+ for i, value in enumerate(cp):
+ sample = lib.st_alaw2linear16(ord(value))
+ _put_lin_sample(result, size, i, sample)
+ return result[:]
def lin2adpcm(cp, size, state):
- raise NotImplementedError()
+ _check_params(len(cp), size)
+ if state is None:
+ state = (0, 0)
+ rv = ffi.new("unsigned char[]", len(cp) // size // 2)
+ state_ptr = ffi.new("int[]", state)
+ lib.lin2adcpm(rv, cp, len(cp), size, state_ptr)
+ return ffi.buffer(rv)[:], tuple(state_ptr)
def adpcm2lin(cp, size, state):
- raise NotImplementedError()
+ _check_size(size)
+ if state is None:
+ state = (0, 0)
+ rv = ffi.new("unsigned char[]", len(cp) * size * 2)
+ state_ptr = ffi.new("int[]", state)
+ lib.adcpm2lin(rv, cp, len(cp), size, state_ptr)
+ return ffi.buffer(rv)[:], tuple(state_ptr)
+
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -6,3 +6,8 @@
__version__ = "0.8.6"
__version_info__ = (0, 8, 6)
+
+# The verifier module file names are based on the CRC32 of a string that
+# contains the following version number. It may be older than __version__
+# if nothing is clearly incompatible.
+__version_verifier_modules__ = "0.8.6"
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -69,6 +69,7 @@
self._function_caches = []
self._libraries = []
self._cdefsources = []
+ self._windows_unicode = None
if hasattr(backend, 'set_ffi'):
backend.set_ffi(self)
for name in backend.__dict__:
@@ -77,6 +78,7 @@
#
with self._lock:
self.BVoidP = self._get_cached_btype(model.voidp_type)
+ self.BCharA = self._get_cached_btype(model.char_array_type)
if isinstance(backend, types.ModuleType):
# _cffi_backend: attach these constants to the class
if not hasattr(FFI, 'NULL'):
@@ -189,13 +191,16 @@
cdecl = self._typeof(cdecl)
return self._backend.alignof(cdecl)
- def offsetof(self, cdecl, fieldname):
+ def offsetof(self, cdecl, *fields_or_indexes):
"""Return the offset of the named field inside the given
- structure, which must be given as a C type name.
+ structure or array, which must be given as a C type name.
+ You can give several field names in case of nested structures.
+ You can also give numeric values which correspond to array
+ items, in case of an array type.
"""
if isinstance(cdecl, basestring):
cdecl = self._typeof(cdecl)
- return self._backend.typeoffsetof(cdecl, fieldname)[1]
+ return self._typeoffsetof(cdecl, *fields_or_indexes)[1]
def new(self, cdecl, init=None):
"""Allocate an instance according to the specified C type and
@@ -264,6 +269,16 @@
"""
return self._backend.buffer(cdata, size)
+ def from_buffer(self, python_buffer):
+ """Return a <cdata 'char[]'> that points to the data of the
+ given Python object, which must support the buffer interface.
+ Note that this is not meant to be used on the built-in types str,
+ unicode, or bytearray (you can build 'char[]' arrays explicitly)
+ but only on objects containing large quantities of raw data
+ in some other format, like 'array.array' or numpy arrays.
+ """
+ return self._backend.from_buffer(self.BCharA, python_buffer)
+
def callback(self, cdecl, python_callable=None, error=None):
"""Return a callback object or a decorator making such a
callback object. 'cdecl' must name a C function pointer type.
@@ -335,9 +350,23 @@
which requires binary compatibility in the signatures.
"""
from .verifier import Verifier, _caller_dir_pycache
+ #
+ # If set_unicode(True) was called, insert the UNICODE and
+ # _UNICODE macro declarations
+ if self._windows_unicode:
+ self._apply_windows_unicode(kwargs)
+ #
+ # Set the tmpdir here, and not in Verifier.__init__: it picks
+ # up the caller's directory, which we want to be the caller of
+ # ffi.verify(), as opposed to the caller of Veritier().
tmpdir = tmpdir or _caller_dir_pycache()
+ #
+ # Make a Verifier() and use it to load the library.
self.verifier = Verifier(self, source, tmpdir, **kwargs)
lib = self.verifier.load_library()
+ #
+ # Save the loaded library for keep-alive purposes, even
+ # if the caller doesn't keep it alive itself (it should).
self._libraries.append(lib)
return lib
@@ -356,15 +385,29 @@
with self._lock:
return model.pointer_cache(self, ctype)
- def addressof(self, cdata, field=None):
+ def addressof(self, cdata, *fields_or_indexes):
"""Return the address of a <cdata 'struct-or-union'>.
- If 'field' is specified, return the address of this field.
+ If 'fields_or_indexes' are given, returns the address of that
+ field or array item in the structure or array, recursively in
+ case of nested structures.
"""
ctype = self._backend.typeof(cdata)
- ctype, offset = self._backend.typeoffsetof(ctype, field)
+ if fields_or_indexes:
+ ctype, offset = self._typeoffsetof(ctype, *fields_or_indexes)
+ else:
+ if ctype.kind == "pointer":
+ raise TypeError("addressof(pointer)")
+ offset = 0
ctypeptr = self._pointer_to(ctype)
return self._backend.rawaddressof(ctypeptr, cdata, offset)
+ def _typeoffsetof(self, ctype, field_or_index, *fields_or_indexes):
+ ctype, offset = self._backend.typeoffsetof(ctype, field_or_index)
+ for field1 in fields_or_indexes:
+ ctype, offset1 = self._backend.typeoffsetof(ctype, field1, 1)
+ offset += offset1
+ return ctype, offset
+
def include(self, ffi_to_include):
"""Includes the typedefs, structs, unions and enums defined
in another FFI instance. Usage is similar to a #include in C,
@@ -387,6 +430,44 @@
def from_handle(self, x):
return self._backend.from_handle(x)
+ def set_unicode(self, enabled_flag):
+ """Windows: if 'enabled_flag' is True, enable the UNICODE and
+ _UNICODE defines in C, and declare the types like TCHAR and LPTCSTR
+ to be (pointers to) wchar_t. If 'enabled_flag' is False,
+ declare these types to be (pointers to) plain 8-bit characters.
+ This is mostly for backward compatibility; you usually want True.
+ """
+ if self._windows_unicode is not None:
+ raise ValueError("set_unicode() can only be called once")
+ enabled_flag = bool(enabled_flag)
+ if enabled_flag:
+ self.cdef("typedef wchar_t TBYTE;"
+ "typedef wchar_t TCHAR;"
+ "typedef const wchar_t *LPCTSTR;"
+ "typedef const wchar_t *PCTSTR;"
+ "typedef wchar_t *LPTSTR;"
+ "typedef wchar_t *PTSTR;"
+ "typedef TBYTE *PTBYTE;"
+ "typedef TCHAR *PTCHAR;")
+ else:
+ self.cdef("typedef char TBYTE;"
+ "typedef char TCHAR;"
+ "typedef const char *LPCTSTR;"
+ "typedef const char *PCTSTR;"
+ "typedef char *LPTSTR;"
+ "typedef char *PTSTR;"
+ "typedef TBYTE *PTBYTE;"
+ "typedef TCHAR *PTCHAR;")
+ self._windows_unicode = enabled_flag
+
+ def _apply_windows_unicode(self, kwds):
+ defmacros = kwds.get('define_macros', ())
+ if not isinstance(defmacros, (list, tuple)):
+ raise TypeError("'define_macros' must be a list or tuple")
+ defmacros = list(defmacros) + [('UNICODE', '1'),
+ ('_UNICODE', '1')]
+ kwds['define_macros'] = defmacros
+
def _load_backend_lib(backend, name, flags):
if name is None:
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
@@ -169,6 +169,7 @@
class CTypesGenericPtr(CTypesData):
__slots__ = ['_address', '_as_ctype_ptr']
_automatic_casts = False
+ kind = "pointer"
@classmethod
def _newp(cls, init):
@@ -370,10 +371,12 @@
(CTypesPrimitive, type(source).__name__))
return source
#
+ kind1 = kind
class CTypesPrimitive(CTypesGenericPrimitive):
__slots__ = ['_value']
_ctype = ctype
_reftypename = '%s &' % name
+ kind = kind1
def __init__(self, value):
self._value = value
@@ -703,12 +706,13 @@
class struct_or_union(base_ctypes_class):
pass
struct_or_union.__name__ = '%s_%s' % (kind, name)
+ kind1 = kind
#
class CTypesStructOrUnion(CTypesBaseStructOrUnion):
__slots__ = ['_blob']
_ctype = struct_or_union
_reftypename = '%s &' % (name,)
- _kind = kind
+ _kind = kind = kind1
#
CTypesStructOrUnion._fix_class()
return CTypesStructOrUnion
@@ -994,27 +998,42 @@
def getcname(self, BType, replace_with):
return BType._get_c_name(replace_with)
- def typeoffsetof(self, BType, fieldname):
- if fieldname is not None and issubclass(BType, CTypesGenericPtr):
- BType = BType._BItem
- if not issubclass(BType, CTypesBaseStructOrUnion):
- raise TypeError("expected a struct or union ctype")
- if fieldname is None:
- return (BType, 0)
- else:
+ def typeoffsetof(self, BType, fieldname, num=0):
+ if isinstance(fieldname, str):
+ if num == 0 and issubclass(BType, CTypesGenericPtr):
+ BType = BType._BItem
+ if not issubclass(BType, CTypesBaseStructOrUnion):
+ raise TypeError("expected a struct or union ctype")
BField = BType._bfield_types[fieldname]
if BField is Ellipsis:
raise TypeError("not supported for bitfields")
return (BField, BType._offsetof(fieldname))
+ elif isinstance(fieldname, (int, long)):
+ if issubclass(BType, CTypesGenericArray):
+ BType = BType._CTPtr
+ if not issubclass(BType, CTypesGenericPtr):
+ raise TypeError("expected an array or ptr ctype")
+ BItem = BType._BItem
+ offset = BItem._get_size() * fieldname
+ if offset > sys.maxsize:
+ raise OverflowError
+ return (BItem, offset)
+ else:
+ raise TypeError(type(fieldname))
- def rawaddressof(self, BTypePtr, cdata, offset):
+ def rawaddressof(self, BTypePtr, cdata, offset=None):
if isinstance(cdata, CTypesBaseStructOrUnion):
ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata))
elif isinstance(cdata, CTypesGenericPtr):
+ if offset is None or not issubclass(type(cdata)._BItem,
+ CTypesBaseStructOrUnion):
+ raise TypeError("unexpected cdata type")
+ ptr = type(cdata)._to_ctypes(cdata)
+ elif isinstance(cdata, CTypesGenericArray):
ptr = type(cdata)._to_ctypes(cdata)
else:
raise TypeError("expected a <cdata 'struct-or-union'>")
- if offset != 0:
+ if offset:
ptr = ctypes.cast(
ctypes.c_void_p(
ctypes.cast(ptr, ctypes.c_void_p).value + offset),
diff --git a/lib_pypy/cffi/commontypes.py b/lib_pypy/cffi/commontypes.py
--- a/lib_pypy/cffi/commontypes.py
+++ b/lib_pypy/cffi/commontypes.py
@@ -29,6 +29,9 @@
result = model.PointerType(resolve_common_type(result[:-2]))
elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
result = model.PrimitiveType(result)
+ elif result == 'set-unicode-needed':
+ raise api.FFIError("The Windows type %r is only available after "
+ "you call ffi.set_unicode()" % (commontype,))
else:
if commontype == result:
raise api.FFIError("Unsupported type: %r. Please file a bug "
@@ -86,8 +89,6 @@
"ULONGLONG": "unsigned long long",
"WCHAR": "wchar_t",
"SHORT": "short",
- "TBYTE": "WCHAR",
- "TCHAR": "WCHAR",
"UCHAR": "unsigned char",
"UINT": "unsigned int",
"UINT8": "unsigned char",
@@ -157,14 +158,12 @@
"LPCVOID": model.const_voidp_type,
"LPCWSTR": "const WCHAR *",
- "LPCTSTR": "LPCWSTR",
"LPDWORD": "DWORD *",
"LPHANDLE": "HANDLE *",
"LPINT": "int *",
"LPLONG": "long *",
"LPSTR": "CHAR *",
"LPWSTR": "WCHAR *",
- "LPTSTR": "LPWSTR",
"LPVOID": model.voidp_type,
"LPWORD": "WORD *",
"LRESULT": "LONG_PTR",
@@ -173,7 +172,6 @@
"PBYTE": "BYTE *",
"PCHAR": "CHAR *",
"PCSTR": "const CHAR *",
- "PCTSTR": "LPCWSTR",
"PCWSTR": "const WCHAR *",
"PDWORD": "DWORD *",
"PDWORDLONG": "DWORDLONG *",
@@ -200,9 +198,6 @@
"PSIZE_T": "SIZE_T *",
"PSSIZE_T": "SSIZE_T *",
"PSTR": "CHAR *",
- "PTBYTE": "TBYTE *",
- "PTCHAR": "TCHAR *",
- "PTSTR": "LPWSTR",
"PUCHAR": "UCHAR *",
"PUHALF_PTR": "UHALF_PTR *",
"PUINT": "UINT *",
@@ -240,6 +235,15 @@
"USN": "LONGLONG",
"VOID": model.void_type,
"WPARAM": "UINT_PTR",
+
+ "TBYTE": "set-unicode-needed",
+ "TCHAR": "set-unicode-needed",
+ "LPCTSTR": "set-unicode-needed",
+ "PCTSTR": "set-unicode-needed",
+ "LPTSTR": "set-unicode-needed",
+ "PTSTR": "set-unicode-needed",
+ "PTBYTE": "set-unicode-needed",
+ "PTCHAR": "set-unicode-needed",
})
return result
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -1,4 +1,3 @@
-
from . import api, model
from .commontypes import COMMON_TYPES, resolve_common_type
try:
@@ -209,6 +208,8 @@
def _add_constants(self, key, val):
if key in self._int_constants:
+ if self._int_constants[key] == val:
+ return # ignore identical double declarations
raise api.FFIError(
"multiple declarations of constant: %s" % (key,))
self._int_constants[key] = val
@@ -228,12 +229,18 @@
pyvalue = int(int_str, 0)
self._add_constants(key, pyvalue)
+ self._declare('macro ' + key, pyvalue)
elif value == '...':
self._declare('macro ' + key, value)
else:
- raise api.CDefError('only supports the syntax "#define '
- '%s ..." (literally) or "#define '
- '%s 0x1FF" for now' % (key, key))
+ raise api.CDefError(
+ 'only supports one of the following syntax:\n'
+ ' #define %s ... (literally dot-dot-dot)\n'
+ ' #define %s NUMBER (with NUMBER an integer'
+ ' constant, decimal/hex/octal)\n'
+ 'got:\n'
+ ' #define %s %s'
+ % (key, key, key, value))
def _parse_decl(self, decl):
node = decl.type
@@ -460,6 +467,8 @@
elif kind == 'union':
tp = model.UnionType(explicit_name, None, None, None)
elif kind == 'enum':
+ if explicit_name == '__dotdotdot__':
+ raise CDefError("Enums cannot be declared with ...")
tp = self._build_enum_type(explicit_name, type.values)
else:
raise AssertionError("kind = %r" % (kind,))
@@ -532,9 +541,24 @@
def _parse_constant(self, exprnode, partial_length_ok=False):
# for now, limited to expressions that are an immediate number
- # or negative number
+ # or positive/negative number
if isinstance(exprnode, pycparser.c_ast.Constant):
- return int(exprnode.value, 0)
+ s = exprnode.value
+ if s.startswith('0'):
+ if s.startswith('0x') or s.startswith('0X'):
+ return int(s, 16)
+ return int(s, 8)
+ elif '1' <= s[0] <= '9':
+ return int(s, 10)
+ elif s[0] == "'" and s[-1] == "'" and (
+ len(s) == 3 or (len(s) == 4 and s[1] == "\\")):
+ return ord(s[-2])
+ else:
+ raise api.CDefError("invalid constant %r" % (s,))
+ #
+ if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
+ exprnode.op == '+'):
+ return self._parse_constant(exprnode.expr)
#
if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
exprnode.op == '-'):
diff --git a/lib_pypy/cffi/ffiplatform.py b/lib_pypy/cffi/ffiplatform.py
--- a/lib_pypy/cffi/ffiplatform.py
+++ b/lib_pypy/cffi/ffiplatform.py
@@ -11,6 +11,9 @@
"""
+LIST_OF_FILE_NAMES = ['sources', 'include_dirs', 'library_dirs',
+ 'extra_objects', 'depends']
+
def get_extension(srcfilename, modname, sources=(), **kwds):
from distutils.core import Extension
allsources = [srcfilename]
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
@@ -235,6 +235,8 @@
BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist)
return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length)
+char_array_type = ArrayType(PrimitiveType('char'), None)
+
class StructOrUnionOrEnum(BaseTypeByIdentity):
_attrs_ = ('name',)
@@ -478,7 +480,7 @@
try:
res = getattr(ffi._backend, funcname)(*args)
except NotImplementedError as e:
- raise NotImplementedError("%r: %s" % (srctype, e))
+ raise NotImplementedError("%s: %r: %s" % (funcname, srctype, e))
# note that setdefault() on WeakValueDictionary is not atomic
# and contains a rare bug (http://bugs.python.org/issue19542);
# we have to use a lock and do it ourselves
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
+++ b/lib_pypy/cffi/vengine_cpy.py
@@ -65,7 +65,7 @@
# The following two 'chained_list_constants' items contains
# the head of these two chained lists, as a string that gives the
# call to do, if any.
- self._chained_list_constants = ['0', '0']
+ self._chained_list_constants = ['((void)lib,0)', '((void)lib,0)']
#
prnt = self._prnt
# first paste some standard set of lines that are mostly '#define'
@@ -138,15 +138,22 @@
More information about the pypy-commit
mailing list