diff --git a/pysoundfile.py b/pysoundfile.py index 105f548..4286be6 100644 --- a/pysoundfile.py +++ b/pysoundfile.py @@ -329,12 +329,10 @@ def read(file, frames=-1, start=0, stop=None, dtype='float64', always_2d=True, return data, f.samplerate -def write(data, file, samplerate, - subtype=None, endian=None, format=None, closefd=True): +def write(data, file, samplerate, subtype=None, endian=None, format=None, + closefd=True, exclusive_creation=True): """Write data to a sound file. - .. note:: If `file` exists, it will be truncated and overwritten! - Parameters ---------- data : array_like @@ -357,6 +355,9 @@ def write(data, file, samplerate, Other Parameters ---------------- + exclusive_creation : bool + If ``True`` (the default), the file is opened with ``mode='x'``. + Otherwise, it is opened with ``mode='w'``. format, endian, closefd See :class:`SoundFile`. @@ -375,7 +376,8 @@ def write(data, file, samplerate, channels = 1 else: channels = data.shape[1] - with SoundFile(file, 'w', samplerate, channels, + mode = 'x' if exclusive_creation else 'w' + with SoundFile(file, mode, samplerate, channels, subtype, endian, format, closefd) as f: f.write(data) diff --git a/tests/test_argspec.py b/tests/test_argspec.py index 9aa987d..909b61d 100644 --- a/tests/test_argspec.py +++ b/tests/test_argspec.py @@ -30,7 +30,7 @@ def test_read_defaults(): meth_defaults = defaults(read_method) init_defaults = defaults(init) - del init_defaults['mode'] # Not meaningful in read() function: + del init_defaults['mode'] # mode is always 'r' del func_defaults['start'] del func_defaults['stop'] @@ -44,12 +44,13 @@ def test_read_defaults(): def test_write_defaults(): write_defaults = defaults(write_function) + del write_defaults['exclusive_creation'] init_defaults = defaults(init) # Same default values as SoundFile.__init__() init_defaults = remove_items(init_defaults, write_defaults) - del init_defaults['mode'] # mode is always 'w' + del init_defaults['mode'] # mode is always 'x' or 'w' del init_defaults['channels'] # Inferred from data del init_defaults['samplerate'] # Obligatory in write() assert not init_defaults # No more arguments should be left diff --git a/tests/test_pysoundfile.py b/tests/test_pysoundfile.py index 1fa6972..a612e60 100644 --- a/tests/test_pysoundfile.py +++ b/tests/test_pysoundfile.py @@ -194,6 +194,12 @@ def test_write_function(file_w): assert np.all(data == data_mono) +def test_write_with_exclusive_creation(): + with pytest.raises(OSError) as excinfo: + sf.write(data_mono, filename_mono, 44100) + assert "File exists" in str(excinfo.value) + + # ----------------------------------------------------------------------------- # Test blocks() function # -----------------------------------------------------------------------------