[pypy-commit] pypy stdlib-2.7.9: merge default into branch

mattip noreply at buildbot.pypy.org
Sat Feb 14 20:26:49 CET 2015


Author: mattip <matti.picus at gmail.com>
Branch: stdlib-2.7.9
Changeset: r75874:efdb6e5046b6
Date: 2015-02-14 21:23 +0200
http://bitbucket.org/pypy/pypy/changeset/efdb6e5046b6/

Log:	merge default into branch

diff too long, truncating to 2000 out of 3194 lines

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_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py
--- a/lib_pypy/_ctypes/array.py
+++ b/lib_pypy/_ctypes/array.py
@@ -9,7 +9,7 @@
     def __new__(self, name, cls, typedict):
         res = type.__new__(self, name, cls, typedict)
         if '_type_' in typedict:
-            ffiarray = _rawffi.Array(typedict['_type_']._ffishape)
+            ffiarray = _rawffi.Array(typedict['_type_']._ffishape_)
             res._ffiarray = ffiarray
             subletter = getattr(typedict['_type_'], '_type_', None)
             if subletter == 'c':
@@ -58,8 +58,8 @@
                 res.value = property(getvalue, setvalue)
                 
             if '_length_' in typedict:
-                res._ffishape = (ffiarray, typedict['_length_'])
-                res._fficompositesize = res._sizeofinstances()
+                res._ffishape_ = (ffiarray, typedict['_length_'])
+                res._fficompositesize_ = res._sizeofinstances()
         else:
             res._ffiarray = None
         return res
@@ -156,7 +156,7 @@
 
 class Array(_CData):
     __metaclass__ = ArrayMeta
-    _ffiargshape = 'P'
+    _ffiargshape_ = 'P'
 
     def __init__(self, *args):
         if not hasattr(self, '_buffer'):
@@ -191,13 +191,13 @@
         if ensure_objects(cobj) is not None:
             store_reference(self, index, cobj._objects)
         arg = cobj._get_buffer_value()
-        if self._type_._fficompositesize is None:
+        if self._type_._fficompositesize_ is None:
             self._buffer[index] = arg
             # something more sophisticated, cannot set field directly
         else:
             from ctypes import memmove
             dest = self._buffer.itemaddress(index)
-            memmove(dest, arg, self._type_._fficompositesize)
+            memmove(dest, arg, self._type_._fficompositesize_)
 
     def __getitem__(self, index):
         if isinstance(index, slice):
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
@@ -52,7 +52,7 @@
     def get_ffi_argtype(self):
         if self._ffiargtype:
             return self._ffiargtype
-        self._ffiargtype = _shape_to_ffi_type(self._ffiargshape)
+        self._ffiargtype = _shape_to_ffi_type(self._ffiargshape_)
         return self._ffiargtype
 
     def _CData_output(self, resbuffer, base=None, index=-1):
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -65,9 +65,9 @@
     _restype_ = None
     _errcheck_ = None
     _flags_ = 0
-    _ffiargshape = 'P'
-    _ffishape = 'P'
-    _fficompositesize = None
+    _ffiargshape_ = 'P'
+    _ffishape_ = 'P'
+    _fficompositesize_ = None
     _ffiarray = _rawffi.Array('P')
     _needs_free = False
     callable = None
@@ -98,7 +98,7 @@
     argtypes = property(_getargtypes, _setargtypes)
 
     def _check_argtypes_for_fastpath(self):
-        if all([hasattr(argtype, '_ffiargshape') for argtype in self._argtypes_]):
+        if all([hasattr(argtype, '_ffiargshape_') for argtype in self._argtypes_]):
             fastpath_cls = make_fastpath_subclass(self.__class__)
             fastpath_cls.enable_fastpath_maybe(self)
 
@@ -135,7 +135,7 @@
             _flag = flag & PARAMFLAG_COMBINED
             if _flag == PARAMFLAG_FOUT:
                 typ = self._argtypes_[idx]
-                if getattr(typ, '_ffiargshape', None) not in ('P', 'z', 'Z'):
+                if getattr(typ, '_ffiargshape_', None) not in ('P', 'z', 'Z'):
                     raise TypeError(
                         "'out' parameter %d must be a pointer type, not %s"
                         % (idx+1, type(typ).__name__)
@@ -182,11 +182,11 @@
     def _ffishapes(self, args, restype):
         if args is None:
             args = []
-        argtypes = [arg._ffiargshape for arg in args]
+        argtypes = [arg._ffiargshape_ for arg in args]
         if restype is not None:
             if not isinstance(restype, SimpleType):
                 raise TypeError("invalid result type for callback function")
-            restype = restype._ffiargshape
+            restype = restype._ffiargshape_
         else:
             restype = 'O' # void
         return argtypes, restype
@@ -599,7 +599,7 @@
         if self._is_primitive(restype) and not restype._is_pointer_like():
             return result
         #
-        shape = restype._ffishape
+        shape = restype._ffishape_
         if is_struct_shape(shape):
             buf = result
         else:
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -21,9 +21,9 @@
             size       = _rawffi.sizeof('P'),
             align      = _rawffi.alignment('P'),
             length     = 1,
-            _ffiargshape = 'P',
-            _ffishape  = 'P',
-            _fficompositesize = None,
+            _ffiargshape_ = 'P',
+            _ffishape_  = 'P',
+            _fficompositesize_ = None,
         )
         # XXX check if typedict['_type_'] is any sane
         # XXX remember about paramfunc
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -117,9 +117,9 @@
         default = TP_TO_DEFAULT[tp]
         ffiarray = _rawffi.Array(tp)
         result = type.__new__(self, name, bases, dct)
-        result._ffiargshape = tp
-        result._ffishape = tp
-        result._fficompositesize = None
+        result._ffiargshape_ = tp
+        result._ffishape_ = tp
+        result._fficompositesize_ = None
         result._ffiarray = ffiarray
         if tp == 'z':
             # c_char_p
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
@@ -36,9 +36,9 @@
     rawfields = []
     for f in all_fields:
         if len(f) > 2:
-            rawfields.append((f[0], f[1]._ffishape, f[2]))
+            rawfields.append((f[0], f[1]._ffishape_, f[2]))
         else:
-            rawfields.append((f[0], f[1]._ffishape))
+            rawfields.append((f[0], f[1]._ffishape_))
 
     _set_shape(self, rawfields, self._is_union)
 
@@ -48,8 +48,8 @@
         value = field[1]
         is_bitfield = (len(field) == 3)
         fields[name] = Field(name,
-                             self._ffistruct.fieldoffset(name),
-                             self._ffistruct.fieldsize(name),
+                             self._ffistruct_.fieldoffset(name),
+                             self._ffistruct_.fieldsize(name),
                              value, i, is_bitfield)
 
     if anonymous_fields:
@@ -58,9 +58,9 @@
             name = field[0]
             value = field[1]
             is_bitfield = (len(field) == 3)
-            startpos = self._ffistruct.fieldoffset(name)
+            startpos = self._ffistruct_.fieldoffset(name)
             if name in anonymous_fields:
-                for subname in value._names:
+                for subname in value._names_:
                     resnames.append(subname)
                     subfield = getattr(value, subname)
                     relpos = startpos + subfield.offset
@@ -71,7 +71,7 @@
             else:
                 resnames.append(name)
         names = resnames
-    self._names = names
+    self._names_ = names
     for name, field in fields.items():
         setattr(self, name, field)
 
@@ -114,19 +114,19 @@
         elif ensure_objects(cobj) is not None:
             store_reference(obj, key, cobj._objects)
         arg = cobj._get_buffer_value()
-        if fieldtype._fficompositesize is not None:
+        if fieldtype._fficompositesize_ is not None:
             from ctypes import memmove
             dest = obj._buffer.fieldaddress(self.name)
-            memmove(dest, arg, fieldtype._fficompositesize)
+            memmove(dest, arg, fieldtype._fficompositesize_)
         else:
             obj._buffer.__setattr__(self.name, arg)
 
 
 def _set_shape(tp, rawfields, is_union=False):
-    tp._ffistruct = _rawffi.Structure(rawfields, is_union,
+    tp._ffistruct_ = _rawffi.Structure(rawfields, is_union,
                                       getattr(tp, '_pack_', 0))
-    tp._ffiargshape = tp._ffishape = (tp._ffistruct, 1)
-    tp._fficompositesize = tp._ffistruct.size
+    tp._ffiargshape_ = tp._ffishape_ = (tp._ffistruct_, 1)
+    tp._fficompositesize_ = tp._ffistruct_.size
 
 
 def struct_setattr(self, name, value):
@@ -181,16 +181,16 @@
             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)
+        instance.__dict__['_buffer'] = self._ffistruct_.fromaddress(address)
         return instance
 
     def _sizeofinstances(self):
-        if not hasattr(self, '_ffistruct'):
+        if not hasattr(self, '_ffistruct_'):
             return 0
-        return self._ffistruct.size
+        return self._ffistruct_.size
 
     def _alignmentofinstances(self):
-        return self._ffistruct.alignment
+        return self._ffistruct_.alignment
 
     def from_param(self, value):
         if isinstance(value, tuple):
@@ -203,7 +203,7 @@
 
     def _CData_output(self, resarray, base=None, index=-1):
         res = StructOrUnion.__new__(self)
-        ffistruct = self._ffistruct.fromaddress(resarray.buffer)
+        ffistruct = self._ffistruct_.fromaddress(resarray.buffer)
         res.__dict__['_buffer'] = ffistruct
         res.__dict__['_base'] = base
         res.__dict__['_index'] = index
@@ -224,15 +224,15 @@
         self = super(_CData, cls).__new__(cls, *args, **kwds)
         if '_abstract_' in cls.__dict__:
             raise TypeError("abstract class")
-        if hasattr(cls, '_ffistruct'):
-            self.__dict__['_buffer'] = self._ffistruct(autofree=True)
+        if hasattr(cls, '_ffistruct_'):
+            self.__dict__['_buffer'] = self._ffistruct_(autofree=True)
         return self
 
     def __init__(self, *args, **kwds):
         type(self)._make_final()
-        if len(args) > len(self._names):
+        if len(args) > len(self._names_):
             raise TypeError("too many initializers")
-        for name, arg in zip(self._names, args):
+        for name, arg in zip(self._names_, args):
             if name in kwds:
                 raise TypeError("duplicate value for argument %r" % (
                     name,))
@@ -244,7 +244,7 @@
         """Return a _rawffi array of length 1 whose address is the same as
         the address of the field 'name' of self."""
         address = self._buffer.fieldaddress(name)
-        A = _rawffi.Array(fieldtype._ffishape)
+        A = _rawffi.Array(fieldtype._ffishape_)
         return A.fromaddress(address, 1)
 
     def _get_buffer_for_param(self):
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("""
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,19 +363,9 @@
 
     sample_count = _sample_count(cp, size)
 
-    result = create_string_buffer(len(cp) * 2)
-    clip = _get_clipfn(size)
-
-    for i in range(sample_count):
-        sample = _get_sample(cp, size, i)
-
-        l_sample = clip(sample * fac1)
-        r_sample = clip(sample * fac2)
-
-        _put_sample(result, size, i * 2, l_sample)
-        _put_sample(result, size, i * 2 + 1, r_sample)
-
-    return result.raw
+    rv = ffi.new("unsigned char[]", len(cp) * 2)
+    lib.tostereo(rv, cp, len(cp), size, fac1, fac2)
+    return ffi.buffer(rv)[:]
 
 
 def add(cp1, cp2, size):
@@ -383,42 +374,34 @@
     if len(cp1) != len(cp2):
         raise error("Lengths should be the same")
 
-    clip = _get_clipfn(size)
-    sample_count = _sample_count(cp1, size)
-    result = create_string_buffer(len(cp1))
-
-    for i in range(sample_count):
-        sample1 = getsample(cp1, size, i)
-        sample2 = getsample(cp2, size, i)
-
-        sample = clip(sample1 + sample2)
-
-        _put_sample(result, size, i, sample)
-
-    return result.raw
+    rv = ffi.new("unsigned char[]", len(cp1))
+    lib.add(rv, cp1, cp2, len(cp1), size)
+    return ffi.buffer(rv)[:]
 
 
 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 +412,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 +428,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):
@@ -471,11 +455,10 @@
     inrate //= d
     outrate //= d
 
-    prev_i = [0] * nchannels
-    cur_i = [0] * nchannels
-
     if state is None:
         d = -outrate
+        prev_i = ffi.new('int[]', nchannels)
+        cur_i = ffi.new('int[]', nchannels)
     else:
         d, samps = state
 
@@ -483,70 +466,709 @@
             raise error("illegal state argument")
 
         prev_i, cur_i = zip(*samps)
-        prev_i, cur_i = list(prev_i), list(cur_i)
+        prev_i = ffi.new('int[]', prev_i)
+        cur_i = ffi.new('int[]', cur_i)
+    state_d = ffi.new('int[]', (d,))
 
     q = frame_count // inrate
     ceiling = (q + 1) * outrate
     nbytes = ceiling * bytes_per_frame
 
-    result = create_string_buffer(nbytes)
+    rv = ffi.new("unsigned char[]", nbytes)
+    trim_index = lib.ratecv(rv, cp, frame_count, size,
+                            nchannels, inrate, outrate,
+                            state_d, prev_i, cur_i,
+                            weightA, weightB)
+    result = ffi.buffer(rv)[:trim_index]
+    samps = zip(prev_i, cur_i)
+    return (result, (d, tuple(samps)))
 
-    samples = _get_samples(cp, size)
-    out_i = 0
-    while True:
-        while d < 0:
-            if frame_count == 0:
-                samps = zip(prev_i, cur_i)
-                retval = result.raw
 
-                # slice off extra bytes
-                trim_index = (out_i * bytes_per_frame) - len(retval)
-                retval = retval[:trim_index]
+ffi = FFI()
+ffi.cdef("""
+typedef short PyInt16;
 
-                return (retval, (d, tuple(samps)))
+int ratecv(char* rv, char* cp, size_t len, int size,
+           int nchannels, int inrate, int outrate,
+           int* state_d, int* prev_i, int* cur_i,
+           int weightA, int weightB);
 
-            for chan in range(nchannels):
-                prev_i[chan] = cur_i[chan]
-                cur_i[chan] = next(samples)
+void tostereo(char* rv, char* cp, size_t len, int size,
+              double fac1, double fac2);
+void add(char* rv, char* cp1, char* cp2, size_t len1, int size);
 
-                cur_i[chan] = (
-                    (weightA * cur_i[chan] + weightB * prev_i[chan])
-                    // (weightA + weightB)
-                )
+/* 2's complement (14-bit range) */
+unsigned char
+st_14linear2ulaw(PyInt16 pcm_val);
+PyInt16 st_ulaw2linear16(unsigned char);
 
-            frame_count -= 1
-            d += outrate
+/* 2's complement (13-bit range) */
+unsigned char
+st_linear2alaw(PyInt16 pcm_val);
+PyInt16 st_alaw2linear16(unsigned char);
 
-        while d >= 0:
-            for chan in range(nchannels):
-                cur_o = (
-                    (prev_i[chan] * d + cur_i[chan] * (outrate - d))
-                    // outrate
-                )
-                _put_sample(result, size, out_i, _overflow(cur_o, size))
-                out_i += 1
-                d -= inrate
 
+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 + r"""
+#include <math.h>
+
+static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF};
+/* -1 trick is needed on Windows to support -0x80000000 without a warning */
+static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1};
+
+static int
+fbound(double val, double minval, double maxval)
+{
+    if (val > maxval)
+        val = maxval;
+    else if (val < minval + 1)
+        val = minval;
+    return val;
+}
+
+static int
+gcd(int a, int b)
+{
+    while (b > 0) {
+        int tmp = a % b;
+        a = b;
+        b = tmp;
+    }
+    return a;
+}
+
+int ratecv(char* rv, char* cp, size_t len, int size,
+           int nchannels, int inrate, int outrate,
+           int* state_d, int* prev_i, int* cur_i,
+           int weightA, int weightB)
+{
+    char *ncp = rv;
+    int d, chan;
+
+    /* divide inrate and outrate by their greatest common divisor */
+    d = gcd(inrate, outrate);
+    inrate /= d;
+    outrate /= d;
+    /* divide weightA and weightB by their greatest common divisor */
+    d = gcd(weightA, weightB);
+    weightA /= d;
+    weightA /= d;
+
+    d = *state_d;
+
+    for (;;) {
+        while (d < 0) {
+            if (len == 0) {
+                *state_d = d;
+                return ncp - rv;
+            }
+            for (chan = 0; chan < nchannels; chan++) {
+                prev_i[chan] = cur_i[chan];
+                if (size == 1)
+                    cur_i[chan] = ((int)*CHARP(cp, 0)) << 24;
+                else if (size == 2)
+                    cur_i[chan] = ((int)*SHORTP(cp, 0)) << 16;
+                else if (size == 4)
+                    cur_i[chan] = (int)*LONGP(cp, 0);
+                cp += size;
+                /* implements a simple digital filter */
+                cur_i[chan] = (int)(
+                    ((double)weightA * (double)cur_i[chan] +
+                     (double)weightB * (double)prev_i[chan]) /
+                    ((double)weightA + (double)weightB));
+            }
+            len--;
+            d += outrate;
+        }
+        while (d >= 0) {
+            for (chan = 0; chan < nchannels; chan++) {
+                int cur_o;
+                cur_o = (int)(((double)prev_i[chan] * (double)d +
+                         (double)cur_i[chan] * (double)(outrate - d)) /
+                    (double)outrate);
+                if (size == 1)
+                    *CHARP(ncp, 0) = (signed char)(cur_o >> 24);
+                else if (size == 2)
+                    *SHORTP(ncp, 0) = (short)(cur_o >> 16);
+                else if (size == 4)
+                    *LONGP(ncp, 0) = (Py_Int32)(cur_o);
+                ncp += size;
+            }
+            d -= inrate;
+        }
+    }
+}
+
+void tostereo(char* rv, char* cp, size_t len, int size,
+              double fac1, double fac2)
+{
+    int val1, val2, val = 0;
+    double fval, maxval, minval;
+    char *ncp = rv;
+    int i;
+
+    maxval = (double) maxvals[size];
+    minval = (double) minvals[size];
+
+    for ( i=0; i < len; i += size ) {
+        if ( size == 1 )      val = (int)*CHARP(cp, i);
+        else if ( size == 2 ) val = (int)*SHORTP(cp, i);
+        else if ( size == 4 ) val = (int)*LONGP(cp, i);
+
+        fval = (double)val*fac1;
+        val1 = (int)floor(fbound(fval, minval, maxval));
+
+        fval = (double)val*fac2;
+        val2 = (int)floor(fbound(fval, minval, maxval));
+
+        if ( size == 1 )      *CHARP(ncp, i*2) = (signed char)val1;
+        else if ( size == 2 ) *SHORTP(ncp, i*2) = (short)val1;
+        else if ( size == 4 ) *LONGP(ncp, i*2) = (Py_Int32)val1;
+
+        if ( size == 1 )      *CHARP(ncp, i*2+1) = (signed char)val2;
+        else if ( size == 2 ) *SHORTP(ncp, i*2+2) = (short)val2;
+        else if ( size == 4 ) *LONGP(ncp, i*2+4) = (Py_Int32)val2;
+    }
+}
+
+void add(char* rv, char* cp1, char* cp2, size_t len1, int size)
+{
+    int i;
+    int val1 = 0, val2 = 0, minval, maxval, newval;
+    char* ncp = rv;
+
+    maxval = maxvals[size];
+    minval = minvals[size];
+
+    for ( i=0; i < len1; i += size ) {
+        if ( size == 1 )      val1 = (int)*CHARP(cp1, i);
+        else if ( size == 2 ) val1 = (int)*SHORTP(cp1, i);
+        else if ( size == 4 ) val1 = (int)*LONGP(cp1, i);
+
+        if ( size == 1 )      val2 = (int)*CHARP(cp2, i);
+        else if ( size == 2 ) val2 = (int)*SHORTP(cp2, i);
+        else if ( size == 4 ) val2 = (int)*LONGP(cp2, i);
+
+        if (size < 4) {
+            newval = val1 + val2;
+            /* truncate in case of overflow */
+            if (newval > maxval)
+                newval = maxval;
+            else if (newval < minval)
+                newval = minval;
+        }
+        else {
+            double fval = (double)val1 + (double)val2;
+            /* truncate in case of overflow */
+            newval = (int)floor(fbound(fval, minval, maxval));
+        }
+
+        if ( size == 1 )      *CHARP(ncp, i) = (signed char)newval;
+        else if ( size == 2 ) *SHORTP(ncp, i) = (short)newval;
+        else if ( size == 4 ) *LONGP(ncp, i) = (Py_Int32)newval;
+    }
+}
+
+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
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "0.8.6"
-__version_info__ = (0, 8, 6)
+__version__ = "0.8.6+"
+__version_info__ = (0, 8, 6, "plus")
 
 # 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__
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
@@ -55,7 +55,8 @@
             # _cffi_backend.so compiled.
             import _cffi_backend as backend
             from . import __version__
-            assert backend.__version__ == __version__
+            assert backend.__version__ == __version__, \
+               "version mismatch, %s != %s" % (backend.__version__, __version__)
             # (If you insist you can also try to pass the option
             # 'backend=backend_ctypes.CTypesBackend()', but don't
             # rely on it!  It's probably not going to work well.)
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
@@ -2,11 +2,10 @@
 from . import model
 
 if sys.version_info < (3,):
-    integer_types = (int, long)
     bytechr = chr
 else:
     unicode = str
-    integer_types = int
+    long = int
     xrange = range
     bytechr = lambda num: bytes([num])
 
@@ -181,7 +180,7 @@
             address = 0
         elif isinstance(source, CTypesData):
             address = source._cast_to_integer()
-        elif isinstance(source, integer_types):
+        elif isinstance(source, (int, long)):
             address = source
         else:
             raise TypeError("bad type for cast to %r: %r" %
@@ -358,7 +357,7 @@
             is_signed = (ctype(-1).value == -1)
         #
         def _cast_source_to_int(source):
-            if isinstance(source, (integer_types, float)):
+            if isinstance(source, (int, long, float)):
                 source = int(source)
             elif isinstance(source, CTypesData):
                 source = source._cast_to_integer()
@@ -399,7 +398,7 @@
             if kind == 'bool':
                 @classmethod
                 def _cast_from(cls, source):
-                    if not isinstance(source, (integer_types, float)):
+                    if not isinstance(source, (int, long, float)):
                         source = _cast_source_to_int(source)
                     return cls(bool(source))
                 def __int__(self):
@@ -438,7 +437,7 @@
             if kind == 'int' or kind == 'byte' or kind == 'bool':
                 @staticmethod
                 def _to_ctypes(x):
-                    if not isinstance(x, integer_types):
+                    if not isinstance(x, (int, long)):
                         if isinstance(x, CTypesData):
                             x = int(x)
                         else:
@@ -465,7 +464,7 @@
             if kind == 'float':
                 @staticmethod
                 def _to_ctypes(x):
-                    if not isinstance(x, (integer_types, float, CTypesData)):
+                    if not isinstance(x, (int, long, float, CTypesData)):
                         raise TypeError("float expected, got %s" %
                                         type(x).__name__)
                     return ctype(x).value
@@ -529,14 +528,14 @@
                 self._own = True
 
             def __add__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return self._new_pointer_at(self._address +
                                                 other * self._bitem_size)
                 else:
                     return NotImplemented
 
             def __sub__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return self._new_pointer_at(self._address -
                                                 other * self._bitem_size)
                 elif type(self) is type(other):
@@ -611,7 +610,7 @@
 
             def __init__(self, init):
                 if length is None:
-                    if isinstance(init, integer_types):
+                    if isinstance(init, (int, long)):
                         len1 = init
                         init = None
                     elif kind == 'char' and isinstance(init, bytes):
@@ -686,7 +685,7 @@
                 return CTypesPtr._arg_to_ctypes(value)
 
             def __add__(self, other):
-                if isinstance(other, integer_types):
+                if isinstance(other, (int, long)):
                     return CTypesPtr._new_pointer_at(
                         ctypes.addressof(self._blob) +
                         other * ctypes.sizeof(BItem._ctype))
diff --git a/lib_pypy/cffi/verifier.py b/lib_pypy/cffi/verifier.py
--- a/lib_pypy/cffi/verifier.py
+++ b/lib_pypy/cffi/verifier.py
@@ -1,4 +1,4 @@
-import sys, os, binascii, shutil
+import sys, os, binascii, shutil, io
 from . import __version_verifier_modules__
 from . import ffiplatform
 
@@ -13,6 +13,16 @@
                 if type == imp.C_EXTENSION]
 
 
+if sys.version_info >= (3,):
+    NativeIO = io.StringIO
+else:
+    class NativeIO(io.BytesIO):
+        def write(self, s):
+            if isinstance(s, unicode):
+                s = s.encode('ascii')
+            super(NativeIO, self).write(s)
+
+
 class Verifier(object):
 
     def __init__(self, ffi, preamble, tmpdir=None, modulename=None,
@@ -144,19 +154,36 @@
         self._vengine.collect_types()
         self._has_module = True
 
-    def _write_source(self, file=None):
-        must_close = (file is None)
-        if must_close:
-            _ensure_dir(self.sourcefilename)
-            file = open(self.sourcefilename, 'w')
+    def _write_source_to(self, file):
         self._vengine._f = file
         try:
             self._vengine.write_source_to_f()
         finally:
             del self._vengine._f
-            if must_close:
-                file.close()
-        if must_close:
+
+    def _write_source(self, file=None):
+        if file is not None:
+            self._write_source_to(file)
+        else:
+            # Write our source file to an in memory file.
+            f = NativeIO()
+            self._write_source_to(f)
+            source_data = f.getvalue()
+
+            # Determine if this matches the current file
+            if os.path.exists(self.sourcefilename):
+                with open(self.sourcefilename, "r") as fp:
+                    needs_written = not (fp.read() == source_data)
+            else:
+                needs_written = True
+
+            # Actually write the file out if it doesn't match
+            if needs_written:
+                _ensure_dir(self.sourcefilename)
+                with open(self.sourcefilename, "w") as fp:
+                    fp.write(source_data)
+
+            # Set this flag
             self._has_source = True
 
     def _compile_module(self):
diff --git a/lib_pypy/gdbm.py b/lib_pypy/gdbm.py
--- a/lib_pypy/gdbm.py
+++ b/lib_pypy/gdbm.py
@@ -1,4 +1,4 @@
-import cffi, os
+import cffi, os, sys
 
 ffi = cffi.FFI()
 ffi.cdef('''
@@ -37,9 +37,19 @@
 ''')
 
 try:
-    lib = ffi.verify('''
-    #include "gdbm.h"
-    ''', libraries=['gdbm'])
+    if sys.platform.startswith('freebsd'):
+        import os.path
+        _localbase = os.environ.get('LOCALBASE', '/usr/local')
+        lib = ffi.verify('''
+        #include "gdbm.h"
+        ''', libraries=['gdbm'],
+             include_dirs=[os.path.join(_localbase, 'include')],
+             library_dirs=[os.path.join(_localbase, 'lib')]
+        )
+    else:
+        lib = ffi.verify('''
+        #include "gdbm.h"
+        ''', libraries=['gdbm'])
 except cffi.VerificationError as e:
     # distutils does not preserve the actual message,
     # but the verification is simple enough that the
diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py
--- a/lib_pypy/pyrepl/readline.py
+++ b/lib_pypy/pyrepl/readline.py
@@ -73,6 +73,7 @@
     assume_immutable_completions = False
     use_brackets = False
     sort_in_column = True
+    tab_insert_spaces_if_stem_is_empty = False
 
     def error(self, msg="none"):
         pass    # don't show error messages by default
@@ -86,6 +87,13 @@
         return ''.join(b[p+1:self.pos])
 
     def get_completions(self, stem):
+        if len(stem) == 0 and self.tab_insert_spaces_if_stem_is_empty:
+            b = self.buffer
+            p = self.pos
+            while p > 0 and b[p - 1] != '\n':
+                p -= 1
+            num_spaces = 4 - ((self.pos - p) % 4)
+            return [' ' * num_spaces]
         result = []
         function = self.config.readline_completer
         if function is not None:
@@ -204,14 +212,15 @@
         boolean value is true.
         """
         reader = self.get_reader()
-        saved = reader.more_lines
+        saved = reader.more_lines, reader.tab_insert_spaces_if_stem_is_empty
         try:
             reader.more_lines = more_lines
             reader.ps1 = reader.ps2 = ps1
             reader.ps3 = reader.ps4 = ps2
+            reader.tab_insert_spaces_if_stem_is_empty = True
             return reader.readline(returns_unicode=returns_unicode)
         finally:
-            reader.more_lines = saved
+            reader.more_lines, reader.tab_insert_spaces_if_stem_is_empty = saved
 
     def parse_and_bind(self, string):
         pass  # XXX we don't support parsing GNU-readline-style init files
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -48,9 +48,13 @@
 Install build-time dependencies
 -------------------------------
 (**Note**: for some hints on how to translate the Python interpreter under
-Windows, see the `windows document`_)
+Windows, see the `windows document`_ . For hints on how to cross-compile in
+a chroot using scratchbox2, see the `arm document`_ in the 
+`RPython documentation`_)
 
 .. _`windows document`: windows.html
+.. _`arm document`: http://rpython.readthedocs.org/en/latest/arm.html
+.. _`RPython documentation`: http://rpython.readthedocs.org
 
 
 To build PyPy on Unix using the C translation backend, you need at least a C
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -300,6 +300,18 @@
 Notably missing from the list above are ``str`` and ``unicode``.  If your
 code relies on comparing strings with ``is``, then it might break in PyPy.
 
+Note that for floats there "``is``" only one object per "bit pattern"
+of the float.  So ``float('nan') is float('nan')`` is true on PyPy,
+but not on CPython because they are two objects; but ``0.0 is -0.0``
+is always False, as the bit patterns are different.  As usual,
+``float('nan') == float('nan')`` is always False.  When used in
+containers (as list items or in sets for example), the exact rule of
+equality used is "``if x is y or x == y``" (on both CPython and PyPy);
+as a consequence, because all ``nans`` are identical in PyPy, you
+cannot have several of them in a set, unlike in CPython.  (Issue `#1974`__)
+
+.. __: https://bitbucket.org/pypy/pypy/issue/1974/different-behaviour-for-collections-of
+
 
 Miscellaneous
 -------------
diff --git a/pypy/doc/interpreter-optimizations.rst b/pypy/doc/interpreter-optimizations.rst
--- a/pypy/doc/interpreter-optimizations.rst
+++ b/pypy/doc/interpreter-optimizations.rst
@@ -165,7 +165,7 @@
 We improved this by keeping method lookup separated from method call, unlike
 some other approaches, but using the value stack as a cache instead of building
 a temporary object.  We extended the bytecode compiler to (optionally) generate
-the following code for ``obj.meth(x)``::
+the following code for ``obj.meth(x, y)``::
 
     LOAD_GLOBAL     obj
     LOOKUP_METHOD   meth
@@ -181,7 +181,7 @@
 the attribute actually refers to a function object from the class; when this is
 not the case, ``LOOKUP_METHOD`` still pushes two values, but one *(im_func)* is
 simply the regular result that ``LOAD_ATTR`` would have returned, and the other
-*(im_self)* is a None placeholder.
+*(im_self)* is an interpreter-level None placeholder.
 
 After pushing the arguments, the layout of the stack in the above
 example is as follows (the stack grows upwards):
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -712,7 +712,7 @@
         return self.wrap(not self.is_true(w_obj))
 
     def eq_w(self, w_obj1, w_obj2):
-        """shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
+        """Implements equality with the double check 'x is y or x == y'."""
         return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
 
     def is_(self, w_one, w_two):
diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py
--- a/pypy/interpreter/unicodehelper.py
+++ b/pypy/interpreter/unicodehelper.py
@@ -16,17 +16,20 @@
                                              space.wrap(msg)]))
     return raise_unicode_exception_decode
 
+class RUnicodeEncodeError(Exception):
+    def __init__(self, encoding, object, start, end, reason):
+        self.encoding = encoding
+        self.object = object
+        self.start = start
+        self.end = end
+        self.reason = reason
+
 @specialize.memo()
 def encode_error_handler(space):
     # Fast version of the "strict" errors handler.
     def raise_unicode_exception_encode(errors, encoding, msg, u,
                                        startingpos, endingpos):
-        raise OperationError(space.w_UnicodeEncodeError,
-                             space.newtuple([space.wrap(encoding),
-                                             space.wrap(u),
-                                             space.wrap(startingpos),
-                                             space.wrap(endingpos),
-                                             space.wrap(msg)]))
+        raise RUnicodeEncodeError(encoding, u, startingpos, endingpos, msg)
     return raise_unicode_exception_encode
 
 # ____________________________________________________________
diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -8,7 +8,7 @@
     appleveldefs = {
         }
     interpleveldefs = {
-        '__version__': 'space.wrap("0.8.6")',
+        '__version__': 'space.wrap("0.8.6+")',
 
         'load_library': 'libraryobj.load_library',
 
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -3241,4 +3241,4 @@
 
 def test_version():
     # this test is here mostly for PyPy
-    assert __version__ == "0.8.6"
+    assert __version__ == "0.8.6+"
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -1153,6 +1153,11 @@
         assert buffer(s)._pypy_raw_address() == addr
         assert buffer(s, 10)._pypy_raw_address() == addr + 10
 
+        addr = memoryview(s)._pypy_raw_address()
+        assert type(addr) is int
+        assert memoryview(s)._pypy_raw_address() == addr
+        assert memoryview(s)[10:]._pypy_raw_address() == addr + 10
+
     def test_union(self):
         import _rawffi
         longsize = _rawffi.sizeof('l')
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -81,7 +81,10 @@
                 return w_object.descr_copy(space, w_order)
             elif not copy and (subok or type(w_object) is W_NDimArray):
                 return w_object
-        # we have a ndarray, but need to copy or change dtype or create W_NDimArray
+        if subok and not type(w_object) is W_NDimArray:
+            raise oefmt(space.w_NotImplementedError, 
+                "array(..., subok=True) only partially implemented")
+        # we have a ndarray, but need to copy or change dtype 
         if dtype is None:
             dtype = w_object.get_dtype()
         if dtype != w_object.get_dtype():
@@ -89,13 +92,12 @@
             copy = True
         if copy:
             shape = w_object.get_shape()
-            _elems_w = w_object.reshape(space, space.wrap(-1))
             elems_w = [None] * w_object.get_size()
-            for i in range(len(elems_w)):
-                elems_w[i] = _elems_w.descr_getitem(space, space.wrap(i))
-        elif subok:
-            raise oefmt(space.w_NotImplementedError, 
-                "array(...copy=False, subok=True) not implemented yet")
+            elsize = w_object.get_dtype().elsize
+            # TODO - use w_object.implementation without copying to a list
+            # unfortunately that causes a union error in translation
+            for i in range(w_object.get_size()):
+                elems_w[i] = w_object.implementation.getitem(i * elsize)
         else:
             sz = support.product(w_object.get_shape()) * dtype.elsize
             return W_NDimArray.from_shape_and_storage(space,
@@ -113,7 +115,7 @@
             dtype = descriptor.variable_dtype(space, dtype.char + '1')
 
     w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
-    if len(elems_w) == 1:
+    if support.product(shape) == 1:
         w_arr.set_scalar_value(dtype.coerce(space, elems_w[0]))
     else:
         loop.assign(space, w_arr, elems_w)
diff --git a/pypy/module/micronumpy/flatiter.py b/pypy/module/micronumpy/flatiter.py
--- a/pypy/module/micronumpy/flatiter.py
+++ b/pypy/module/micronumpy/flatiter.py
@@ -15,6 +15,7 @@
         self._base = base
         self.dtype = base.get_dtype()
         self.shape = [base.get_size()]
+        self.storage = self._base.implementation.storage
 
     def base(self):
         return self._base
diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -2852,6 +2852,13 @@
         c.flat = ['defgh', 'ijklmnop']
         assert (c.flatten() == ['def', 'ijk']*5).all()
 
+    def test_flatiter_subtype(self):
+        from numpy import array
+        x = array([[1, 2], [3, 4]]).T
+        y = array(x.flat)
+        assert (x == [[1, 3], [2, 4]]).all()
+
+
     def test_slice_copy(self):
         from numpy import zeros
         a = zeros((10, 10))
diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py
--- a/pypy/module/micronumpy/test/test_subtype.py
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -26,6 +26,12 @@
                     self.called_finalize = True
             return SubType ''')
 
+    def test_subtype_ndarray(self):
+        from numpy import arange, array
+        a = arange(24, dtype='int32').reshape((6,4))
+        b = array(a, dtype='float64', subok=True)
+        assert (a == b).all()
+
     def test_subtype_base(self):
         from numpy import ndarray, dtype
         class C(ndarray):
@@ -272,40 +278,103 @@
         import numpy as N
         # numpy's matrix class caused an infinite loop
         class matrix(N.ndarray):
-            getcnt = 0
             def __new__(subtype, data, dtype=None, copy=True):
+                print('matrix __new__')
+                if isinstance(data, matrix):
+                    dtype2 = data.dtype
+                    if (dtype is None):
+                        dtype = dtype2
+                    if (dtype2 == dtype) and (not copy):
+                        return data
+                    return data.astype(dtype)
+
+                if isinstance(data, N.ndarray):
+                    if dtype is None:
+                        intype = data.dtype
+                    else:
+                        intype = N.dtype(dtype)
+                    new = data.view(subtype)
+                    if intype != data.dtype:
+                        return new.astype(intype)
+                    if copy: return new.copy()
+                    else: return new
+
+                if isinstance(data, str):
+                    data = _convert_from_string(data)
+
+                # now convert data to an array
                 arr = N.array(data, dtype=dtype, copy=copy)
+                ndim = arr.ndim
                 shape = arr.shape
+                if (ndim > 2):
+                    raise ValueError("matrix must be 2-dimensional")
+                elif ndim == 0:
+                    shape = (1, 1)
+                elif ndim == 1:
+                    shape = (1, shape[0])
+
+                order = False
+                if (ndim == 2) and arr.flags.fortran:
+                    order = True
+
+                if not (order or arr.flags.contiguous):
+                    arr = arr.copy()
 
                 ret = N.ndarray.__new__(subtype, shape, arr.dtype,
                                         buffer=arr,
-                                        order=True)
+                                        order=order)
                 return ret
 
+            def __array_finalize__(self, obj):
+                print('matrix __array_finalize__')
+                self._getitem = False
+                if (isinstance(obj, matrix) and obj._getitem): return
+                ndim = self.ndim
+                if (ndim == 2):
+                    return
+                if (ndim > 2):
+                    newshape = tuple([x for x in self.shape if x > 1])
+                    ndim = len(newshape)
+                    if ndim == 2:
+                        self.shape = newshape
+                        return
+                    elif (ndim > 2):
+                        raise ValueError("shape too large to be a matrix.")
+                else:
+                    newshape = self.shape
+                if ndim == 0:
+                    self.shape = (1, 1)
+                elif ndim == 1:
+                    self.shape = (1, newshape[0])
+                return
+
             def __getitem__(self, index):
-                matrix.getcnt += 1
-                if matrix.getcnt > 10:
-                    # XXX strides.find_shape_and_elems is sensitive
-                    # to shape modification
-                    xxx
-                out = N.ndarray.__getitem__(self, index)
+                print('matrix __getitem__')
+                self._getitem = True
+
+                try:
+                    out = N.ndarray.__getitem__(self, index)
+                finally:
+                    self._getitem = False
 
                 if not isinstance(out, N.ndarray):
                     return out
+
+                if out.ndim == 0:
+                    return out[()]
+                if out.ndim == 1:
+                    sh = out.shape[0]
                     # Determine when we should have a column array
-                old_shape = out.shape
-                if out.ndim < 2:
-                    sh = out.shape[0]
                     try:
                         n = len(index)
                     except:
                         n = 0
-                    if n > 1:
+                    if n > 1 and isscalar(index[1]):
                         out.shape = (sh, 1)
                     else:
                         out.shape = (1, sh)
-                #print 'out, shape was',old_shape,'now',out.shape,'out',out
                 return out
+
         a = matrix([[1., 2.], [3., 4.]])
         b = N.array([a])
         assert (b == a).all()
@@ -318,6 +387,17 @@
         assert len(b.shape) == 2
         assert (b == a).all()
 
+        b = N.array(a, copy=True, dtype=int)
+        assert len(b.shape) == 2
+        assert (b == a).all()
+
+        c = matrix(a, copy=False)
+        assert c.base is not None
+        c[0, 0] = 100
+        assert a[0, 0] == 100
+        b = N.array(c, copy=True)
+        assert (b == a).all()
+
     def test_setstate_no_version(self):
         # Some subclasses of ndarray, like MaskedArray, do not use
         # version in __setstare__
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
@@ -27,7 +27,7 @@
         log = self.run(main, [libm_name])
         pow_addr, res = log.result
         assert res == 8.0 * 300
-        py.test.xfail()     # XXX re-optimize _ffi for the JIT?
+        py.test.skip("XXX re-optimize _ffi for the JIT?")
         loop, = log.loops_by_filename(self.filepath)
         if 'ConstClass(pow)' in repr(loop):   # e.g. OS/X
             pow_addr = 'ConstClass(pow)'
@@ -134,7 +134,7 @@
         ops = loop.allops()
         opnames = log.opnames(ops)
         assert opnames.count('new_with_vtable') == 1 # only the virtualref
-        py.test.xfail()     # XXX re-optimize _ffi for the JIT?
+        py.test.skip("XXX re-optimize _ffi for the JIT?")
         assert opnames.count('call_release_gil') == 1
         idx = opnames.index('call_release_gil')
         call = ops[idx]
@@ -159,7 +159,7 @@
             return struct.getfield('x')
         #
         log = self.run(main, [])
-        py.test.xfail()     # XXX re-optimize _ffi for the JIT?
+        py.test.skip("XXX re-optimize _ffi for the JIT?")
         loop, = log.loops_by_filename(self.filepath)
         assert loop.match_by_id('getfield', """
             guard_not_invalidated(descr=...)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py b/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_ownlib.py
@@ -8,34 +8,137 @@
 SOURCE = """\
 #include <errno.h>
 
-int test_getting_errno(void) {
+#ifdef _WIN32
+#define EXPORT __declspec(dllexport)
+#else
+#define EXPORT
+#endif
+
+EXPORT int test_getting_errno(void) {
     errno = 123;
     return -1;
 }
 
-int test_setting_errno(void) {
+EXPORT int test_setting_errno(void) {
     return errno;
+};
+
+typedef struct {
+    long x;
+    long y;
+} POINT;
+
+typedef struct {
+    long left;
+    long top;
+    long right;
+    long bottom;
+} RECT;
+
+
+EXPORT int PointInRect(RECT *prc, POINT pt)
+{
+    if (pt.x < prc->left)
+        return 0;
+    if (pt.x > prc->right)
+        return 0;
+    if (pt.y < prc->top)
+        return 0;
+    if (pt.y > prc->bottom)


More information about the pypy-commit mailing list