[SCM] pysoundfile/master: New upstream version 0.9.0

umlaeute at users.alioth.debian.org umlaeute at users.alioth.debian.org
Mon Jun 19 11:07:13 UTC 2017


The following commit has been merged in the master branch:
commit 1d0906852a4cea708dfdb4940a4b8c645bb22fb9
Author: IOhannes m zmölnig <zmoelnig at umlautQ.umlaeute.mur.at>
Date:   Mon Jun 19 12:53:29 2017 +0200

    New upstream version 0.9.0

diff --git a/.travis.yml b/.travis.yml
index ac3132a..860fe77 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,17 +6,18 @@ python:
   - "3.3"
   - "3.4"
   - "3.5"
+  - "3.6"
   - "nightly"
-  - "pypy"
-  # TODO: Enable pypy3 once NumPy is working there:
+  - "pypy-5.3.1"
+  - "pypy-5.4.1"
+  # TODO: Enable pypy3 once NumPy is working there, see
+  # https://bitbucket.org/pypy/pypy/issues/1567/
   #- "pypy3"
 addons:
   apt:
     packages:
     - libsndfile1
 install:
-  # TODO: remove "@pypy-2.6.0" once
-  # https://github.com/travis-ci/travis-ci/issues/4756 is closed:
-  - "if [ $TRAVIS_PYTHON_VERSION = pypy -o $TRAVIS_PYTHON_VERSION = pypy3 ]; then pip install git+https://bitbucket.org/pypy/numpy.git@pypy-2.6.0 ; fi"
+  - "if [[ $TRAVIS_PYTHON_VERSION == pypy* ]]; then pip install git+https://bitbucket.org/pypy/numpy.git ; fi"
 script:
   - python setup.py test
diff --git a/LICENSE b/LICENSE
index 5def83f..74d836a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -11,7 +11,7 @@ met:
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
-  * Neither the name of the <ORGANIZATION> nor the names
+  * Neither the name of PySoundFile nor the names
     of its contributors may be used to endorse or promote products
     derived from this software without specific prior written
     permission.
@@ -26,4 +26,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.rst b/README.rst
index 8dbcaa4..2c1312e 100644
--- a/README.rst
+++ b/README.rst
@@ -31,6 +31,10 @@ In 0.8.0, we changed the default value of ``always_2d`` from ``True``
 to ``False``. Also, the order of arguments of the ``write`` function
 changed from ``write(data, file, ...)`` to ``write(file, data, ...)``.
 
+In 0.9.0, we changed the ``ctype`` arguments of the ``buffer_*``
+methods to ``dtype``, using the Numpy ``dtype`` notation. The old
+``ctype`` arguments still work, but are now officially deprecated.
+
 Installation
 ------------
 
@@ -229,3 +233,16 @@ News
       ``write(data, file, ...)`` to ``write(file, data, ...)``
 
     And many more minor bug fixes.
+
+2017-02-02 V0.9.0 Bastian Bechtold:
+    Thank you, Matthias Geier, Tomas Garcia, and Todd, for contributions
+    for this release.
+
+    - Adds support for ALAC files.
+    - Adds new member ``__libsndfile_version__``
+    - Adds number of frames to ``info`` class
+    - Adds ``dtype`` argument to ``buffer_*`` methods
+    - Deprecates ``ctype`` argument to ``buffer_*`` methods
+    - Adds official support for Python 3.6
+
+    And some minor bug fixes.
diff --git a/doc/fake_cffi.py b/doc/fake_cffi.py
index 66ed279..ea1cc30 100644
--- a/doc/fake_cffi.py
+++ b/doc/fake_cffi.py
@@ -2,10 +2,17 @@
 
 
 class FFI(object):
+
     def cdef(self, _):
         pass
 
     def dlopen(self, _):
         return self
 
+    def string(self, _):
+        return b'not implemented'
+
+    def sf_version_string(self):
+        return NotImplemented
+
     SFC_GET_FORMAT_INFO = NotImplemented
diff --git a/setup.py b/setup.py
index e75b421..cfd57f1 100644
--- a/setup.py
+++ b/setup.py
@@ -7,9 +7,9 @@ import sys
 
 PYTHON_INTERPRETERS = '.'.join([
     'cp26', 'cp27',
-    'cp32', 'cp33', 'cp34', 'cp35',
+    'cp32', 'cp33', 'cp34', 'cp35', 'cp36',
     'pp27',
-    'pp32',
+    'pp32', 'pp33',
 ])
 MACOSX_VERSIONS = '.'.join([
     'macosx_10_5_x86_64',
@@ -29,15 +29,18 @@ elif platform == 'win32':
 else:
     libname = None
 
-if libname:
+if libname and os.path.isdir('_soundfile_data'):
     packages = ['_soundfile_data']
     package_data = {'_soundfile_data': [libname, 'COPYING']}
+    zip_safe = False
 else:
     packages = None
     package_data = None
+    zip_safe = True
 
 
 class PyTest(TestCommand):
+
     user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")]
 
     def initialize_options(self):
@@ -62,8 +65,10 @@ try:
 except ImportError:
     pass
 else:
+
     class bdist_wheel_half_pure(bdist_wheel):
         """Create OS-dependent, but Python-independent wheels."""
+
         def get_tag(self):
             pythons = 'py2.py3.' + PYTHON_INTERPRETERS
             if platform == 'darwin':
@@ -82,7 +87,7 @@ else:
 
 setup(
     name='SoundFile',
-    version='0.8.1',
+    version='0.9.0',
     description='An audio library based on libsndfile, CFFI and NumPy',
     author='Bastian Bechtold',
     author_email='basti at bastibe.de',
@@ -91,6 +96,7 @@ setup(
     py_modules=['soundfile'],
     packages=packages,
     package_data=package_data,
+    zip_safe=zip_safe,
     license='BSD 3-Clause License',
     install_requires=['cffi>=0.6'],
     extras_require={'numpy': ['numpy']},
diff --git a/soundfile.py b/soundfile.py
index e1d34e0..4e62296 100644
--- a/soundfile.py
+++ b/soundfile.py
@@ -8,7 +8,7 @@ Alternatively, sound files can be opened as :class:`SoundFile` objects.
 For further information, see http://pysoundfile.readthedocs.org/.
 
 """
-__version__ = "0.8.1"
+__version__ = "0.9.0"
 
 import os as _os
 import sys as _sys
@@ -31,6 +31,7 @@ enum
 
 enum
 {
+    SFC_GET_LIB_VERSION             = 0x1000,
     SFC_GET_LOG_INFO                = 0x1001,
     SFC_GET_FORMAT_INFO             = 0x1028,
 
@@ -92,10 +93,12 @@ sf_count_t  sf_read_int      (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
 sf_count_t  sf_read_float    (SNDFILE *sndfile, float *ptr, sf_count_t items) ;
 sf_count_t  sf_read_double   (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
 
-sf_count_t  sf_readf_short   (SNDFILE *sndfile, short *ptr, sf_count_t frames) ;
-sf_count_t  sf_readf_int     (SNDFILE *sndfile, int *ptr, sf_count_t frames) ;
-sf_count_t  sf_readf_float   (SNDFILE *sndfile, float *ptr, sf_count_t frames) ;
-sf_count_t  sf_readf_double  (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
+/* Note: Data ptr argument types are declared as void* here in order to
+         avoid an implicit cast warning. (gh183). */
+sf_count_t  sf_readf_short   (SNDFILE *sndfile, void *ptr, sf_count_t frames) ;
+sf_count_t  sf_readf_int     (SNDFILE *sndfile, void *ptr, sf_count_t frames) ;
+sf_count_t  sf_readf_float   (SNDFILE *sndfile, void *ptr, sf_count_t frames) ;
+sf_count_t  sf_readf_double  (SNDFILE *sndfile, void *ptr, sf_count_t frames) ;
 
 sf_count_t  sf_write_short   (SNDFILE *sndfile, short *ptr, sf_count_t items) ;
 sf_count_t  sf_write_int     (SNDFILE *sndfile, int *ptr, sf_count_t items) ;
@@ -114,6 +117,7 @@ sf_count_t  sf_write_raw     (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
 
 const char* sf_get_string    (SNDFILE *sndfile, int str_type) ;
 int         sf_set_string    (SNDFILE *sndfile, int str_type, const char* str) ;
+const char * sf_version_string (void) ;
 
 typedef sf_count_t  (*sf_vio_get_filelen) (void *user_data) ;
 typedef sf_count_t  (*sf_vio_seek)        (sf_count_t offset, int whence, void *user_data) ;
@@ -210,6 +214,10 @@ _subtypes = {
     'DPCM_8':    0x0050,  # 8 bit differential PCM (XI only)
     'DPCM_16':   0x0051,  # 16 bit differential PCM (XI only)
     'VORBIS':    0x0060,  # Xiph Vorbis encoding.
+    'ALAC_16':   0x0070,  # Apple Lossless Audio Codec (16 bit).
+    'ALAC_20':   0x0071,  # Apple Lossless Audio Codec (20 bit).
+    'ALAC_24':   0x0072,  # Apple Lossless Audio Codec (24 bit).
+    'ALAC_32':   0x0073,  # Apple Lossless Audio Codec (32 bit).
 }
 
 _endians = {
@@ -257,7 +265,7 @@ _ffi_types = {
 
 try:
     _snd = _ffi.dlopen('sndfile')
-except OSError as err:
+except OSError:
     if _sys.platform == 'darwin':
         _libname = 'libsndfile.dylib'
     elif _sys.platform == 'win32':
@@ -269,6 +277,10 @@ except OSError as err:
         _os.path.dirname(_os.path.abspath(__file__)),
         '_soundfile_data', _libname))
 
+__libsndfile_version__ = _ffi.string(_snd.sf_version_string()).decode('utf-8', 'replace')
+if __libsndfile_version__.startswith('libsndfile-'):
+    __libsndfile_version__ = __libsndfile_version__[len('libsndfile-'):]
+
 
 def read(file, frames=-1, start=0, stop=None, dtype='float64', always_2d=False,
          fill_value=None, out=None, samplerate=None, channels=None,
@@ -481,13 +493,15 @@ def blocks(file, blocksize=None, overlap=0, frames=-1, start=0, stop=None,
 
 class _SoundFileInfo(object):
     """Information about a SoundFile"""
+
     def __init__(self, file, verbose):
         self.verbose = verbose
         with SoundFile(file) as f:
             self.name = f.name
             self.samplerate = f.samplerate
             self.channels = f.channels
-            self.duration = len(f)/f.samplerate
+            self.frames = len(f)
+            self.duration = self.frames/f.samplerate
             self.format = f.format
             self.subtype = f.subtype
             self.endian = f.endian
@@ -520,6 +534,7 @@ class _SoundFileInfo(object):
             info += "\n".join(
                 ["\nendian: {0.endian}",
                  "sections: {0.sections}",
+                 "frames: {0.frames}",
                  'extra_info: """',
                  '    {1}"""'])
         indented_extra_info = ("\n"+" "*4).join(self.extra_info.split("\n"))
@@ -616,7 +631,6 @@ def default_subtype(format):
 
 
 class SoundFile(object):
-
     """A sound file.
 
     For more documentation see the __init__() docstring (which is also
@@ -768,7 +782,7 @@ class SoundFile(object):
         info = _ffi.new("char[]", 2**14)
         _snd.sf_command(self._file, _snd.SFC_GET_LOG_INFO,
                         info, _ffi.sizeof(info))
-        return _ffi.string(info).decode()
+        return _ffi.string(info).decode('utf-8', 'replace')
 
     # avoid confusion if something goes wrong before assigning self._file:
     _file = None
@@ -803,7 +817,7 @@ class SoundFile(object):
         if name in _str_types:
             self._check_if_closed()
             data = _snd.sf_get_string(self._file, _str_types[name])
-            return _ffi.string(data).decode() if data else ""
+            return _ffi.string(data).decode('utf-8', 'replace') if data else ""
         else:
             raise AttributeError(
                 "'SoundFile' object has no attribute {0!r}".format(name))
@@ -956,10 +970,10 @@ class SoundFile(object):
                 out[frames:] = fill_value
         return out
 
-    def buffer_read(self, frames=-1, ctype='double'):
+    def buffer_read(self, frames=-1, ctype=None, dtype=None):
         """Read from the file and return data as buffer object.
 
-        Reads the given number of frames in the given data format
+        Reads the given number of `frames` in the given data format
         starting at the current read/write position.  This advances the
         read/write position by the same number of frames.
         By default, all frames from the current read/write position to
@@ -971,8 +985,8 @@ class SoundFile(object):
         frames : int, optional
             The number of frames to read. If `frames < 0`, the whole
             rest of the file is read.
-        ctype : {'double', 'float', 'int', 'short'}, optional
-            Audio data will be converted to the given C data type.
+        dtype : {'float64', 'float32', 'int32', 'int16'}
+            Audio data will be converted to the given data type.
 
         Returns
         -------
@@ -985,30 +999,32 @@ class SoundFile(object):
 
         """
         frames = self._check_frames(frames, fill_value=None)
+        dtype = self._ctype_is_deprecated(ctype, dtype)
+        ctype = self._check_dtype(dtype)
         cdata = _ffi.new(ctype + '[]', frames * self.channels)
         read_frames = self._cdata_io('read', cdata, ctype, frames)
         assert read_frames == frames
         return _ffi.buffer(cdata)
 
-    def buffer_read_into(self, buffer, ctype='double'):
-        """Read from the file into a buffer object.
+    def buffer_read_into(self, buffer, ctype=None, dtype=None):
+        """Read from the file into a given buffer object.
 
-        Reads the given number of frames in the given data format
-        starting at the current read/write position.  This advances the
-        read/write position by the same number of frames.
-        By default, all frames from the current read/write position to
-        the end of the file are returned.
-        Use :meth:`.seek` to move the current read/write position.
+        Fills the given `buffer` with frames in the given data format
+        starting at the current read/write position (which can be
+        changed with :meth:`.seek`) until the buffer is full or the end
+        of the file is reached.  This advances the read/write position
+        by the number of frames that were read.
 
         Parameters
         ----------
-        out : writable buffer, optional
-            If specified, audio data from the file is written to this
-            buffer instead of a newly created buffer.
+        buffer : writable buffer
+            Audio frames from the file are written to this buffer.
+        dtype : {'float64', 'float32', 'int32', 'int16'}
+            The data type of `buffer`.
 
         Returns
         -------
-        num_read : int
+        int
             The number of frames that were read from the file.
             This can be less than the size of `buffer`.
             The rest of the buffer is not filled with meaningful data.
@@ -1018,6 +1034,8 @@ class SoundFile(object):
         buffer_read, .read
 
         """
+        dtype = self._ctype_is_deprecated(ctype, dtype)
+        ctype = self._check_dtype(dtype)
         cdata, frames = self._check_buffer(buffer, ctype)
         frames = self._cdata_io('read', cdata, ctype, frames)
         return frames
@@ -1075,26 +1093,29 @@ class SoundFile(object):
         assert written == len(data)
         self._update_len(written)
 
-    def buffer_write(self, data, ctype):
+    def buffer_write(self, data, ctype=None, dtype=None):
         """Write audio data from a buffer/bytes object to the file.
 
-        Writes a number of frames at the read/write position to the
-        file. This also advances the read/write position by the same
-        number of frames and enlarges the file if necessary.
+        Writes the contents of `data` to the file at the current
+        read/write position.
+        This also advances the read/write position by the number of
+        frames that were written and enlarges the file if necessary.
 
         Parameters
         ----------
         data : buffer or bytes
-            A buffer object or bytes containing the audio data to be
+            A buffer or bytes object containing the audio data to be
             written.
-        ctype : {'double', 'float', 'int', 'short'}, optional
-            The data type of the audio data stored in `buffer`.
+        dtype : {'float64', 'float32', 'int32', 'int16'}
+            The data type of the audio data stored in `data`.
 
         See Also
         --------
         .write, buffer_read
 
         """
+        dtype = self._ctype_is_deprecated(ctype, dtype)
+        ctype = self._check_dtype(dtype)
         cdata, frames = self._check_buffer(data, ctype)
         written = self._cdata_io('write', cdata, ctype, frames)
         assert written == frames
@@ -1332,6 +1353,7 @@ class SoundFile(object):
 
     def _check_buffer(self, data, ctype):
         """Convert buffer to cdata and check for valid size."""
+        assert ctype in _ffi_types.values()
         if not isinstance(data, bytes):
             data = _ffi.from_buffer(data)
         frames, remainder = divmod(len(data),
@@ -1349,6 +1371,31 @@ class SoundFile(object):
             shape = frames,
         return np.empty(shape, dtype, order='C')
 
+    def _check_dtype(self, dtype):
+        """Check if dtype string is valid and return ctype string."""
+        try:
+            return _ffi_types[dtype]
+        except KeyError:
+            raise ValueError("dtype must be one of {0!r}".format(
+                sorted(_ffi_types.keys())))
+
+    def _ctype_is_deprecated(self, ctype, dtype):
+        """Show warning if ctype is used instead of dtype.
+
+        At some point, ctype arguments shall be removed and the
+        corresponding dtype arguments shall lose their default value.
+
+        """
+        if ctype is not None:
+            from warnings import warn
+            warn('ctype is deprecated; use dtype instead', Warning)
+            if dtype is not None:
+                raise TypeError('Use dtype instead of ctype')
+            for k, v in _ffi_types.items():
+                if v == ctype:
+                    return k
+        return dtype
+
     def _array_io(self, action, array, frames):
         """Check array and call low-level IO function."""
         if (array.ndim not in (1, 2) or
@@ -1357,19 +1404,14 @@ class SoundFile(object):
             raise ValueError("Invalid shape: {0!r}".format(array.shape))
         if not array.flags.c_contiguous:
             raise ValueError("Data must be C-contiguous")
-        try:
-            ctype = _ffi_types[array.dtype.name]
-        except KeyError:
-            raise TypeError("dtype must be one of {0!r}".format(
-                sorted(_ffi_types.keys())))
+        ctype = self._check_dtype(array.dtype.name)
         assert array.dtype.itemsize == _ffi.sizeof(ctype)
         cdata = _ffi.cast(ctype + '*', array.__array_interface__['data'][0])
         return self._cdata_io(action, cdata, ctype, frames)
 
     def _cdata_io(self, action, data, ctype, frames):
         """Call one of libsndfile's read/write functions."""
-        if ctype not in _ffi_types.values():
-            raise ValueError("Unsupported data type: {0!r}".format(ctype))
+        assert ctype in _ffi_types.values()
         self._check_if_closed()
         if self.seekable():
             curr = self.tell()
@@ -1410,7 +1452,7 @@ def _error_check(err, prefix=""):
     """Pretty-print a numerical error code if there is an error."""
     if err != 0:
         err_str = _snd.sf_error_number(err)
-        raise RuntimeError(prefix + _ffi.string(err_str).decode())
+        raise RuntimeError(prefix + _ffi.string(err_str).decode('utf-8', 'replace'))
 
 
 def _format_int(format, subtype, endian):
@@ -1506,7 +1548,7 @@ def _get_format_from_filename(file, mode):
         # This raises an exception if file is not a (Unicode/byte) string:
         format = _os.path.splitext(file)[-1][1:]
         # Convert bytes to unicode (raises AttributeError on Python 3 str):
-        format = format.decode()
+        format = format.decode('utf-8', 'replace')
     except Exception:
         pass
     if format.upper() not in _formats and 'r' not in mode:
@@ -1521,6 +1563,8 @@ def _format_str(format_int):
         for k, v in dictionary.items():
             if v == format_int:
                 return k
+    else:
+        return 'n/a'
 
 
 def _format_info(format_int, format_flag=_snd.SFC_GET_FORMAT_INFO):
@@ -1531,7 +1575,7 @@ def _format_info(format_int, format_flag=_snd.SFC_GET_FORMAT_INFO):
                     _ffi.sizeof("SF_FORMAT_INFO"))
     name = format_info.name
     return (_format_str(format_info.format),
-            _ffi.string(name).decode() if name else "")
+            _ffi.string(name).decode('utf-8', 'replace') if name else "")
 
 
 def _available_formats_helper(count_flag, format_flag):
diff --git a/tests/test_pysoundfile.py b/tests/test_pysoundfile.py
index fad54f0..ca10325 100644
--- a/tests/test_pysoundfile.py
+++ b/tests/test_pysoundfile.py
@@ -193,7 +193,7 @@ def test_read_into_non_contiguous_out(file_stereo_r):
 
 def test_read_into_out_with_invalid_dtype(file_stereo_r):
     out = np.empty((3, 2), dtype='int64')
-    with pytest.raises(TypeError) as excinfo:
+    with pytest.raises(ValueError) as excinfo:
         sf.read(file_stereo_r, out=out)
     assert "dtype must be one of" in str(excinfo.value)
 
@@ -522,6 +522,7 @@ def test_if_open_with_mode_w_truncates(file_stereo_rplus, mode):
 
 
 class LimitedFile(object):
+
     def __init__(self, file, attrs):
         for attr in attrs:
             setattr(self, attr, getattr(file, attr))
@@ -730,33 +731,33 @@ def test_read_into_out_over_end_with_fill_should_return_full_data_and_write_into
 
 
 def test_buffer_read(sf_stereo_r):
-    buf = sf_stereo_r.buffer_read(2)
+    buf = sf_stereo_r.buffer_read(2, dtype='float64')
     assert len(buf) == 2 * 2 * 8
     assert sf_stereo_r.seek(0, sf.SEEK_CUR) == 2
     data = np.frombuffer(buf, dtype='float64').reshape(-1, 2)
     assert np.all(data == data_stereo[:2])
-    buf = sf_stereo_r.buffer_read(ctype='float')
+    buf = sf_stereo_r.buffer_read(dtype='float32')
     assert len(buf) == 2 * 2 * 4
     assert sf_stereo_r.seek(0, sf.SEEK_CUR) == 4
     data = np.frombuffer(buf, dtype='float32').reshape(-1, 2)
     assert np.all(data == data_stereo[2:])
-    buf = sf_stereo_r.buffer_read()
+    buf = sf_stereo_r.buffer_read(dtype='float32')
     assert len(buf) == 0
-    buf = sf_stereo_r.buffer_read(666)
+    buf = sf_stereo_r.buffer_read(666, dtype='float32')
     assert len(buf) == 0
     with pytest.raises(ValueError) as excinfo:
-        sf_stereo_r.buffer_read(ctype='char')
-    assert "Unsupported data type" in str(excinfo.value)
+        sf_stereo_r.buffer_read(dtype='int8')
+    assert "dtype must be one of" in str(excinfo.value)
 
 
 @xfail_from_buffer
 def test_buffer_read_into(sf_stereo_r):
     out = np.ones((3, 2))
-    frames = sf_stereo_r.buffer_read_into(out)
+    frames = sf_stereo_r.buffer_read_into(out, dtype='float64')
     assert frames == 3
     assert np.all(out == data_stereo[:3])
     assert sf_stereo_r.seek(0, sf.SEEK_CUR) == 3
-    frames = sf_stereo_r.buffer_read_into(out)
+    frames = sf_stereo_r.buffer_read_into(out, dtype='float64')
     assert frames == 1
     assert np.all(out[:1] == data_stereo[3:])
     assert sf_stereo_r.seek(0, sf.SEEK_CUR) == 4
@@ -814,7 +815,7 @@ def test_rplus_append_data(sf_stereo_rplus):
 @xfail_from_buffer
 def test_buffer_write(sf_stereo_w):
     buf = np.array([[1, 2], [-1, -2]], dtype='int16')
-    sf_stereo_w.buffer_write(buf, 'short')
+    sf_stereo_w.buffer_write(buf, dtype='int16')
     sf_stereo_w.close()
     data, fs = sf.read(filename_new, dtype='int16')
     assert np.all(data == buf)
@@ -823,7 +824,7 @@ def test_buffer_write(sf_stereo_w):
 
 def test_buffer_write_with_bytes(sf_stereo_w):
     b = b"\x01\x00\xFF\xFF\xFF\x00\x00\xFF"
-    sf_stereo_w.buffer_write(b, 'short')
+    sf_stereo_w.buffer_write(b, dtype='int16')
     sf_stereo_w.close()
     data, fs = sf.read(filename_new, dtype='int16')
     assert np.all(data == [[1, -1], [255, -256]])
@@ -834,7 +835,7 @@ def test_buffer_write_with_bytes(sf_stereo_w):
 def test_buffer_write_with_wrong_size(sf_stereo_w):
     buf = np.array([1, 2, 3], dtype='int16')
     with pytest.raises(ValueError) as excinfo:
-        sf_stereo_w.buffer_write(buf, 'short')
+        sf_stereo_w.buffer_write(buf, dtype='int16')
     assert "multiple of frame size" in str(excinfo.value)
 
 
@@ -910,6 +911,10 @@ def test_read_int_data_from_float_file(file_inmemory):
     assert fs == 44100
 
 
+def test_libsndfile_version():
+    assert '.' in sf.__libsndfile_version__
+
+
 # -----------------------------------------------------------------------------
 # RAW tests
 # -----------------------------------------------------------------------------

-- 
pysoundfile packaging



More information about the pkg-multimedia-commits mailing list