Repository: pyfar/pyfar
Pull request #690 (2024-09-08 11:42:48)

Ruff: A, Avoid builtin function and type shadowing.
### Which issue(s) are closed by this pull request?

See #647

### Changes proposed in this pull request:

- apply for internal use
- how ro proceed with audio_subtypes and default_audio_subtype?


Patch:
diff --git a/pyfar/classes/filter.py b/pyfar/classes/filter.py
index 4583567d..86a491cf 100644
--- a/pyfar/classes/filter.py
+++ b/pyfar/classes/filter.py
@@ -84,8 +84,9 @@ def _repr_string(filter_type, order, n_channels, sampling_rate):
 
     if filter_type == "SOS":
         sec_str = 'section' if order == 1 else 'sections'
-        repr = (f"SOS filter with {order} {sec_str} and {n_channels} {ch_str} "
-                f"@ {sampling_rate} Hz sampling rate")
+        representation = (f"SOS filter with {order} {sec_str} and "
+                          f"{n_channels} {ch_str} "
+                          f"@ {sampling_rate} Hz sampling rate")
     else:
         if order % 10 == 1:
             order_string = 'st'
@@ -96,10 +97,12 @@ def _repr_string(filter_type, order, n_channels, sampling_rate):
         else:
             order_string = 'th'
 
-        repr = (f"{order}{order_string} order {filter_type} filter with "
-                f"{n_channels} {ch_str} @ {sampling_rate} Hz sampling rate")
+        representation = (f"{order}{order_string} order "
+                          f"{filter_type} filter with "
+                            f"{n_channels} {ch_str} @ {sampling_rate} "
+                            "Hz sampling rate")
 
-    return repr
+    return representation
 
 
 class Filter(object):
diff --git a/pyfar/dsp/interpolation.py b/pyfar/dsp/interpolation.py
index 7e24693a..d6ba0e29 100644
--- a/pyfar/dsp/interpolation.py
+++ b/pyfar/dsp/interpolation.py
@@ -10,12 +10,12 @@ from decimal import Decimal
 import warnings
 
 
-def _weighted_moving_average(input, output, weights):
+def _weighted_moving_average(input_data, output, weights):
     """Moving average filter of length N and arbitrary.
 
     Parameters
     ----------
-    input : numpy.ndarray
+    input_data : numpy.ndarray
         The input array
     output : numpy.ndarray
         The output buffer
@@ -35,8 +35,8 @@ def _weighted_moving_average(input, output, weights):
 
     """
     strided = np.lib.stride_tricks.as_strided(
-        input, strides=input.strides*2,
-        shape=(weights.size, input.size - (weights.size-1)))
+        input_data, strides=input_data.strides*2,
+        shape=(weights.size, input_data.size - (weights.size-1)))
     output[:] = np.average(strided, weights=weights, axis=0)
 
 
diff --git a/pyfar/io/io.py b/pyfar/io/io.py
index 3ed92ddb..5d23b4d1 100644
--- a/pyfar/io/io.py
+++ b/pyfar/io/io.py
@@ -457,13 +457,14 @@ def write_audio(signal, filename, subtype=None, overwrite=True, **kwargs):
     else:
         # Only the subtypes FLOAT, DOUBLE, VORBIS are not clipped,
         # see _clipped_audio_subtypes()
-        format = pathlib.Path(filename).suffix[1:]
+        format_type = pathlib.Path(filename).suffix[1:]
         if subtype is None:
-            subtype = default_audio_subtype(format)
+            subtype = default_audio_subtype(format_type)
         if (np.any(data > 1.) and
                 subtype.upper() not in ['FLOAT', 'DOUBLE', 'VORBIS']):
             warnings.warn(
-                (f'{format}-files of subtype {subtype} are clipped to +/- 1. '
+                (f'{format_type}-files of subtype {subtype} '
+                 'are clipped to +/- 1. '
                  'Normalize your audio with pyfar.dsp.normalize to 1-LSB, with'
                  ' LSB being the least significant bit (e.g. 2**-15 for '
                  "16 bit) or use non-clipping subtypes 'FLOAT', 'DOUBLE', or "
@@ -501,12 +502,16 @@ def audio_formats():
     return soundfile.available_formats()
 
 
-def audio_subtypes(format=None):
+@pf._utils.rename_arg(
+        {"format" : "audio_format"},
+        "'format' will be deprecated in "
+        "pyfar 0.9.0 in favor of 'audio_format'")
+def audio_subtypes(audio_format=None):
     """Return a dictionary of available audio subtypes.
 
     Parameters
     ----------
-    format : str
+    audio_format : str
         If given, only compatible subtypes are returned.
 
     Notes
@@ -526,12 +531,21 @@ def audio_subtypes(format=None):
         warnings.warn(soundfile_warning)
         return
 
-    return soundfile.available_subtypes(format=format)
+    return soundfile.available_subtypes(format=audio_format)
 
 
-def default_audio_subtype(format):
+@pf._utils.rename_arg(
+        {"format" : "audio_format"},
+        "'format' will be deprecated in "
+        "pyfar 0.9.0 in favor of 'audio_format'")
+def default_audio_subtype(audio_format):
     """Return the default subtype for a given format.
 
+    Parameters
+    ----------
+    audio_format : str
+        If given, only compatible subtypes are returned.
+
     Notes
     -----
     This function is a wrapper of :py:func:`soundfile.default_subtype()`.
@@ -549,7 +563,7 @@ def default_audio_subtype(format):
         warnings.warn(soundfile_warning)
         return
 
-    return soundfile.default_subtype(format)
+    return soundfile.default_subtype(audio_format)
 
 
 def read_comsol(filename, expressions=None, parameters=None):
diff --git a/pyproject.toml b/pyproject.toml
index 983d2d59..ddc0ffa7 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,6 +10,7 @@ lint.select = [
     "E",
     "F",
     "W",
+    "A",
     "ERA",
     "NPY",
     "COM",


Test patch:
diff --git a/pyfar/testing/stub_utils.py b/pyfar/testing/stub_utils.py
index 658fbb5f..09555bc4 100644
--- a/pyfar/testing/stub_utils.py
+++ b/pyfar/testing/stub_utils.py
@@ -38,9 +38,9 @@ def signal_stub(time, freq, sampling_rate, fft_norm):
     # Use MagicMock and side_effect to mock __getitem__
     # See "Mocking a dictionary with MagicMock",
     # https://het.as.utexas.edu/HET/Software/mock/examples.html
-    def getitem(slice):
-        time = np.atleast_2d(signal.time[slice])
-        freq = np.atleast_2d(signal.freq[slice])
+    def getitem(slice_idx):
+        time = np.atleast_2d(signal.time[slice_idx])
+        freq = np.atleast_2d(signal.freq[slice_idx])
         item = signal_stub(
             time,
             freq,
@@ -55,10 +55,10 @@ def signal_stub(time, freq, sampling_rate, fft_norm):
         return samples
 
     def find_nearest_frequency(freqs):
-        bin = np.zeros(len(freqs), dtype=int)
+        bins = np.zeros(len(freqs), dtype=int)
         for idx, freq in enumerate(freqs):
-            bin[idx] = np.argmin(np.abs(signal.frequencies-freq))
-        return bin
+            bins[idx] = np.argmin(np.abs(signal.frequencies-freq))
+        return bins
 
     signal = mock.MagicMock(
         spec_set=Signal(time, sampling_rate, domain='time'))
@@ -100,8 +100,8 @@ def time_data_stub(time, times):
     # Use MagicMock and side_effect to mock __getitem__
     # See "Mocking a dictionary with MagicMock",
     # https://het.as.utexas.edu/HET/Software/mock/examples.html
-    def getitem(slice):
-        time = np.atleast_2d(time_data.time[slice])
+    def getitem(slice_idx):
+        time = np.atleast_2d(time_data.time[slice_idx])
         item = time_data_stub(time, time_data.times)
         return item
 
@@ -138,8 +138,8 @@ def frequency_data_stub(freq, frequencies):
     # Use MagicMock and side_effect to mock __getitem__
     # See "Mocking a dictionary with MagicMock",
     # https://het.as.utexas.edu/HET/Software/mock/examples.html
-    def getitem(slice):
-        freq = np.atleast_2d(frequency_data.freq[slice])
+    def getitem(slice_idx):
+        freq = np.atleast_2d(frequency_data.freq[slice_idx])
         item = frequency_data_stub(freq, frequency_data.frequencies)
         return item
 
diff --git a/tests/conftest.py b/tests/conftest.py
index 9706b4b3..82a404ff 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -604,7 +604,7 @@ def state():
 
 
 @pytest.fixture
-def filter(coeffs, state):
+def filterObject(coeffs, state):
     """ Filter object.
     """
     return fo.Filter(coefficients=coeffs, state=state)
diff --git a/tests/test_coordinates_new.py b/tests/test_coordinates_new.py
index 1c4ff503..00fa6e5e 100644
--- a/tests/test_coordinates_new.py
+++ b/tests/test_coordinates_new.py
@@ -329,43 +329,43 @@ def test_find_slice_error():
 
 
 @pytest.mark.parametrize(
-    'coordinate, min, max', [
+    'coordinate, minimum, maximum', [
         ('azimuth', 0, 2*np.pi),
         ('polar', -np.pi/2, 3*np.pi/2),
         ('frontal', 0, 2*np.pi),
     ])
-def test_angle_limits_cyclic(coordinate, min, max):
+def test_angle_limits_cyclic(coordinate, minimum, maximum):
     """Test different queries for find slice."""
     # spherical grid
     d = np.arange(-4*np.pi, 4*np.pi, np.pi/4)
     c = Coordinates(d, 0, 1)
     c.__setattr__(coordinate, d)
     attr = c.__getattribute__(coordinate)
-    desired = (d - min) % (max - min) + min
+    desired = (d - minimum) % (maximum - minimum) + minimum
     np.testing.assert_allclose(attr, desired, atol=2e-14)
 
 
 @pytest.mark.parametrize(
-    'coordinate, min, max', [
+    'coordinate, minimum, maximum', [
         ('azimuth', 0, 2*np.pi),
         ('polar', -np.pi/2, 3*np.pi/2),
         ('frontal', 0, 2*np.pi),
         ('radius', 0, np.inf),
         ('rho', 0, np.inf),
     ])
-def test_angle_cyclic_limits(coordinate, min, max):
+def test_angle_cyclic_limits(coordinate, minimum, maximum):
     """Test different queries for find slice."""
     # spherical grid
     d = np.arange(-4*np.pi, 4*np.pi, np.pi/4)
     c = Coordinates(d, 0, 1)
     c.__setattr__(coordinate, d)
     attr = c.__getattribute__(coordinate)
-    assert all(attr <= max)
-    assert all(attr >= min)
+    assert all(attr <= maximum)
+    assert all(attr >= minimum)
 
 
 @pytest.mark.parametrize(
-    'coordinate, min, max', [
+    'coordinate, minimum, maximum', [
         ('colatitude', 0, np.pi),
         ('upper', 0, np.pi),
         ('elevation', -np.pi/2, np.pi/2),
@@ -383,20 +383,21 @@ def test_angle_cyclic_limits(coordinate, min, max):
         (0),
         (np.finfo(float).eps),
     ])
-def test_angle_limits_rounded_by_2eps(coordinate, min, max, eps_min, eps_max):
+def test_angle_limits_rounded_by_2eps(
+        coordinate, minimum, maximum, eps_min, eps_max):
     """Test different queries for find slice."""
     # spherical grid
-    if max == np.inf:
-        d = np.arange(min, np.pi/4, 4*np.pi)
+    if maximum == np.inf:
+        d = np.arange(minimum, np.pi/4, 4*np.pi)
     else:
-        d = np.arange(min, np.pi/4, max)
+        d = np.arange(minimum, np.pi/4, maximum)
     d[0] -= eps_min
     d[-1] += eps_max
     c = Coordinates(d, 0, 1)
     c.__setattr__(coordinate, d)
     attr = c.__getattribute__(coordinate)
-    assert all(attr <= max)
-    assert all(attr >= min)
+    assert all(attr <= maximum)
+    assert all(attr >= minimum)
 
 
 def test__repr__dim():
diff --git a/tests/test_deprecations.py b/tests/test_deprecations.py
index 40c816b1..3216c342 100644
--- a/tests/test_deprecations.py
+++ b/tests/test_deprecations.py
@@ -372,3 +372,22 @@ def test_deprecations_shelf_function_results():
         pfilt.low_shelf_cascade(None, 250, "lower", -60, None, 4,
                                 sampling_rate=44100)[0].coefficients,
         rtol=0)
+
+
+def test_deprecations_audio_io():
+    with pytest.warns(
+        PyfarDeprecationWarning, match="'format' will be deprecated in "
+        "pyfar 0.9.0 in favor of 'audio_format'"):
+        pf.io.audio_subtypes(format='wav')
+    with pytest.warns(
+        PyfarDeprecationWarning, match="'format' will be deprecated in "
+        "pyfar 0.9.0 in favor of 'audio_format'"):
+        pf.io.default_audio_subtype(format='wav')
+
+    if version.parse(pf.__version__) >= version.parse('0.9.0'):
+        with pytest.raises(TypeError):
+            pf.io.default_audio_subtype(format='wav')
+
+    if version.parse(pf.__version__) >= version.parse('0.9.0'):
+        with pytest.raises(TypeError):
+            pf.io.audio_subtypes(format='wav')
diff --git a/tests/test_dsp.py b/tests/test_dsp.py
index d3b17822..95d2b0e2 100644
--- a/tests/test_dsp.py
+++ b/tests/test_dsp.py
@@ -575,10 +575,10 @@ def test_minimum_phase_against_reference():
     # tests are separated since their reliability depends on the type of
     # filters. The homomorphic method works best for filters with odd numbers
     # of taps. Hilbert_2 approximates the ideal minimum phase
-    input = [0, 0, 0, 0, 1, 0, 0, 0, 0]
+    input_data = [0, 0, 0, 0, 1, 0, 0, 0, 0]
     output = [1, 0, 0, 0, 0]
     min_phase = pyfar.dsp.minimum_phase(
-        pyfar.Signal(input, 44100))
+        pyfar.Signal(input_data, 44100))
 
     npt.assert_allclose(
         min_phase.time.flatten(), np.array(output, dtype=float),
diff --git a/tests/test_dsp_interpolation.py b/tests/test_dsp_interpolation.py
index b8e6a1fe..39acd6f6 100644
--- a/tests/test_dsp_interpolation.py
+++ b/tests/test_dsp_interpolation.py
@@ -34,13 +34,13 @@ def test_smooth_fractional_octave_mode(mode):
     """
 
     # load input data
-    input = np.loadtxt(os.path.join(
+    input_data = np.loadtxt(os.path.join(
             os.path.dirname(__file__), "references",
             "dsp.smooth_fractional_octave_input.csv"))
-    input = pf.Signal(input, 44100)
+    input_data = pf.Signal(input_data, 44100)
 
     # smooth
-    output, _ = smooth_fractional_octave(input, 1, mode)
+    output, _ = smooth_fractional_octave(input_data, 1, mode)
 
     # compare to reference
     reference = np.loadtxt(os.path.join(
diff --git a/tests/test_filter_classes.py b/tests/test_filter_classes.py
index 4d8880dd..cf169c76 100644
--- a/tests/test_filter_classes.py
+++ b/tests/test_filter_classes.py
@@ -361,21 +361,21 @@ def test_blockwise_processing(Filter):
 
 def test_blockwise_processing_with_coefficients_exchange():
     # input signal
-    input = pf.Signal([1, 2, 3, 4, 0], 44100)
+    input_data = pf.Signal([1, 2, 3, 4, 0], 44100)
 
     coefficients_1 = [2, -2]
     coefficients_2 = [2, -1.9]
 
     # time variant filtering using Filter object
     # initialize filter and state
-    filter = pf.FilterFIR([coefficients_1], 44100)
-    filter.init_state(input.cshape, state='zeros')
+    filterObj = pf.FilterFIR([coefficients_1], 44100)
+    filterObj.init_state(input_data.cshape, state='zeros')
     # process first block
-    filter_1 = filter.process(pf.Signal(input.time[..., :2], 44100))
+    filter_1 = filterObj.process(pf.Signal(input_data.time[..., :2], 44100))
     # update filter coefficients
-    filter.coefficients = [coefficients_2]
+    filterObj.coefficients = [coefficients_2]
     # process second block
-    filter_2 = filter.process(pf.Signal(input.time[..., 2:], 44100))
+    filter_2 = filterObj.process(pf.Signal(input_data.time[..., 2:], 44100))
 
     # overlap and add time variant filtering
     # first block
@@ -433,19 +433,19 @@ def test_extend_sos_coefficients():
     npt.assert_allclose(imp_filt, imp)
 
 
-def test___eq___equal(filter):
-    actual = filter.copy()
-    assert filter == actual
+def test___eq___equal(filterObject):
+    actual = filterObject.copy()
+    assert filterObject == actual
 
 
-def test___eq___notEqual(filter, coeffs, state):
+def test___eq___notEqual(filterObject, coeffs, state):
     actual = fo.Filter(coefficients=2 * coeffs, state=state)
-    assert not filter == actual
+    assert not filterObject == actual
     actual = fo.Filter(coefficients=coeffs, state=2 * state)
-    assert not filter == actual
-    actual = filter.copy()
+    assert not filterObject == actual
+    actual = filterObject.copy()
     actual.comment = f'{actual.comment} A completely different thing'
-    assert not filter == actual
+    assert not filterObject == actual
 
 
 def test_repr(capfd):
diff --git a/tests/test_filter_gammatone.py b/tests/test_filter_gammatone.py
index 14587afd..dc0e04b5 100644
--- a/tests/test_filter_gammatone.py
+++ b/tests/test_filter_gammatone.py
@@ -2,7 +2,6 @@ import pytest
 import numpy as np
 import numpy.testing as npt
 import pyfar as pf
-import pyfar.dsp.filter as filter
 
 
 def test_gammatone_bands_init_and_getter():
@@ -12,7 +11,7 @@ def test_gammatone_bands_init_and_getter():
     """
 
     # initialize filter bank
-    GFB = filter.GammatoneBands([0, 22050], resolution=.5)
+    GFB = pf.dsp.filter.GammatoneBands([0, 22050], resolution=.5)
 
     # test the getter
     npt.assert_array_equal(GFB.frequency_range, [0, 22050])
@@ -82,7 +81,7 @@ def test_gammatone_bands_roundtrip(amplitudes, shape_filtered, sampling_rate):
     """
 
     # initialize filter bank
-    GFB = filter.GammatoneBands(
+    GFB = pf.dsp.filter.GammatoneBands(
         [0, 22050], resolution=.5, sampling_rate=sampling_rate)
 
     # filter and sum an impulse signal
@@ -111,7 +110,7 @@ def test_gammatone_bands_roundtrip(amplitudes, shape_filtered, sampling_rate):
 
 def test_gammatone_bands_reset_state():
 
-    GFB = filter.GammatoneBands([0, 22050])
+    GFB = pf.dsp.filter.GammatoneBands([0, 22050])
 
     # filter in one block
     real, imag = GFB.process(pf.signals.impulse(2**12))
@@ -134,20 +133,20 @@ def test_gammatone_bands_assertions():
 
     # wrong values in freq_range
     with pytest.raises(ValueError, match="Values in frequency_range must be"):
-        filter.GammatoneBands([-1, 22050])
+        pf.dsp.filter.GammatoneBands([-1, 22050])
     with pytest.raises(ValueError, match="Values in frequency_range must be"):
-        filter.GammatoneBands([0, 24e3])
+        pf.dsp.filter.GammatoneBands([0, 24e3])
 
     # wrong value for delay
     with pytest.raises(ValueError, match="The delay must be larger than zero"):
-        filter.GammatoneBands([0, 22050], delay=0)
+        pf.dsp.filter.GammatoneBands([0, 22050], delay=0)
 
     # wrong value for resolution
     with pytest.raises(ValueError, match="The resolution must be larger than"):
-        filter.GammatoneBands([0, 22050], resolution=0)
+        pf.dsp.filter.GammatoneBands([0, 22050], resolution=0)
 
     # mismatching type for filter
-    GFB = filter.GammatoneBands([0, 22050])
+    GFB = pf.dsp.filter.GammatoneBands([0, 22050])
     with pytest.raises(TypeError, match="signal must be"):
         GFB.process([1, 0, 0])
 
@@ -159,7 +158,7 @@ def test_gammatone_bands_assertions():
 def test_gammatone_bands_repr():
     """Test string representation"""
 
-    GFB = filter.GammatoneBands([0, 22050])
+    GFB = pf.dsp.filter.GammatoneBands([0, 22050])
     assert str(GFB) == ("Reconstructing Gammatone filter bank with 42 bands "
                         "between 0 and 22050 Hz spaced by 1 ERB units "
                         "@ 44100 Hz sampling rate")
@@ -169,7 +168,7 @@ def test_gammatone_bands_repr():
 def test_gammatone_bands_shape(shape):
     """Test the shape of GammatoneBands-filtered signals"""
     impulse = pf.signals.impulse(2048, 0, np.ones(shape))
-    GFB = filter.GammatoneBands([0, 22050])
+    GFB = pf.dsp.filter.GammatoneBands([0, 22050])
 
     real, imag = GFB.process(impulse)
 
@@ -180,7 +179,7 @@ def test_gammatone_bands_shape(shape):
 def test_erb_frequencies():
     """Test erb_frequencies against reference from the AMT toolbox"""
 
-    frequencies = filter.erb_frequencies([0, 22050], .5)
+    frequencies = pf.dsp.filter.erb_frequencies([0, 22050], .5)
 
     # assert type and length
     assert isinstance(frequencies, np.ndarray)
@@ -198,12 +197,12 @@ def test_erb_frequencies_assertions():
 
     # freq_range must be an array of length 2
     with pytest.raises(ValueError, match="frequency_range must be an array"):
-        filter.erb_frequencies(1)
+        pf.dsp.filter.erb_frequencies(1)
     with pytest.raises(ValueError, match="frequency_range must be an array"):
-        filter.erb_frequencies([1])
+        pf.dsp.filter.erb_frequencies([1])
     # values freq_range must be increasing
     with pytest.raises(ValueError, match="The first value of frequency_range"):
-        filter.erb_frequencies([1, 0])
+        pf.dsp.filter.erb_frequencies([1, 0])
     # resolution must be > 0
     with pytest.raises(ValueError, match="Resolution must be larger"):
-        filter.erb_frequencies([0, 1], 0)
+        pf.dsp.filter.erb_frequencies([0, 1], 0)
diff --git a/tests/test_io.py b/tests/test_io.py
index 8be336a0..d945498b 100644
--- a/tests/test_io.py
+++ b/tests/test_io.py
@@ -273,15 +273,15 @@ def test_write_read_sphericalvoronoi(sphericalvoronoi, tmpdir):
     assert actual == sphericalvoronoi
 
 
-def test_write_read_filter(filter, tmpdir):
+def test_write_read_filter(filterObject, tmpdir):
     """ Filter
     Make sure `read` understands the bits written by `write`
     """
     filename = os.path.join(tmpdir, 'filter.far')
-    io.write(filename, filter=filter)
+    io.write(filename, filter=filterObject)
     actual = io.read(filename)['filter']
     assert isinstance(actual, fo.Filter)
-    assert actual == filter
+    assert actual == filterObject
 
 
 def test_write_filterFIR(filterFIR, tmpdir):
@@ -394,7 +394,7 @@ def test_write_read_builtins(dict_of_builtins, tmpdir):
 
 
 def test_write_read_multiplePyfarObjects(
-        filter,
+        filterObject,
         filterFIR,
         filterIIR,
         filterSOS,
@@ -413,7 +413,7 @@ def test_write_read_multiplePyfarObjects(
     matrix_2d_int = np.arange(0, 24, dtype=int).reshape((4, 6))
     io.write(
         filename,
-        filter=filter,
+        filter=filterObject,
         filterFIR=filterFIR,
         filterIIR=filterIIR,
         filterSOS=filterSOS,
@@ -427,7 +427,7 @@ def test_write_read_multiplePyfarObjects(
         **dict_of_builtins)
     actual = io.read(filename)
     assert isinstance(actual['filter'], fo.Filter)
-    assert actual['filter'] == filter
+    assert actual['filter'] == filterObject
     assert isinstance(actual['filterFIR'], fo.FilterFIR)
     assert actual['filterFIR'] == filterFIR
     assert isinstance(actual['filterIIR'], fo.FilterIIR)
@@ -452,7 +452,7 @@ def test_write_read_multiplePyfarObjects(
 
 
 def test_write_read_multiplePyfarObjectsWithCompression(
-        filter,
+        filterObject,
         filterFIR,
         filterIIR,
         filterSOS,
@@ -472,7 +472,7 @@ def test_write_read_multiplePyfarObjectsWithCompression(
     io.write(
         filename,
         compress=True,
-        filter=filter,
+        filter=filterObject,
         filterFIR=filterFIR,
         filterIIR=filterIIR,
         filterSOS=filterSOS,
@@ -486,7 +486,7 @@ def test_write_read_multiplePyfarObjectsWithCompression(
         **dict_of_builtins)
     actual = io.read(filename)
     assert isinstance(actual['filter'], fo.Filter)
-    assert actual['filter'] == filter
+    assert actual['filter'] == filterObject
     assert isinstance(actual['filterFIR'], fo.FilterFIR)
     assert actual['filterFIR'] == filterFIR
     assert isinstance(actual['filterIIR'], fo.FilterIIR)
diff --git a/tests/test_io_comsol.py b/tests/test_io_comsol.py
index 63b12716..0dfe2c1f 100644
--- a/tests/test_io_comsol.py
+++ b/tests/test_io_comsol.py
@@ -23,11 +23,11 @@ def test_read_comsol_wrong_file_type():
         io.read_comsol(filename)
 
 
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_warning_for_db_values(type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_warning_for_db_values(suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', 'level_only')
     with pytest.warns(Warning, match='dB'):
-        io.read_comsol(path + type)
+        io.read_comsol(path + suffix)
 
 
 def test_read_comsol_error_wrong_domain():
@@ -47,10 +47,10 @@ def test_read_comsol_error_wrong_domain():
     ('intensity_product', ['pabe.p_t*pabe.v_inst*2/sqrt(2)']),
     ('character_collection', ['1e-3[m/s]*(1e3)']),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_header_expressions(filename, expressions, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_header_expressions(filename, expressions, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    actual_expressions, _, _, _, _ = io.read_comsol_header(path + type)
+    actual_expressions, _, _, _, _ = io.read_comsol_header(path + suffix)
     assert len(actual_expressions) == len(expressions)
     for i, exp in enumerate(expressions):
         assert actual_expressions[i] == expressions[i]
@@ -66,10 +66,11 @@ def test_read_comsol_header_expressions(filename, expressions, type):
     ('intensity_product', ['Pa*m/s']),
     ('character_collection', ['m/s']),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_header_expressions_unit(filename, expressions_unit, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_header_expressions_unit(
+        filename, expressions_unit, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, actual_units, _, _, _ = io.read_comsol_header(path + type)
+    _, actual_units, _, _, _ = io.read_comsol_header(path + suffix)
     assert len(actual_units) == len(expressions_unit)
     for i, exp in enumerate(expressions_unit):
         assert actual_units[i] == expressions_unit[i]
@@ -90,10 +91,10 @@ def test_read_comsol_header_expressions_unit(filename, expressions_unit, type):
      {'theta': [0.0, 0.7854, 1.5708, 2.3562, 3.1416],
       'phi': [0., 1.5708, 3.1416, 4.7124]}),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_header_parameters(filename, parameters, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_header_parameters(filename, parameters, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, _, actual_parameters, _, _ = io.read_comsol_header(path + type)
+    _, _, actual_parameters, _, _ = io.read_comsol_header(path + suffix)
     assert parameters == actual_parameters
 
 
@@ -107,10 +108,10 @@ def test_read_comsol_header_parameters(filename, parameters, type):
     ('intensity_product', 'freq'),
     ('character_collection', 'freq'),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_header_domain(filename, domain, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_header_domain(filename, domain, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, _, _, actual_domain, _ = io.read_comsol_header(path + type)
+    _, _, _, actual_domain, _ = io.read_comsol_header(path + suffix)
     assert domain == actual_domain
 
 
@@ -125,10 +126,10 @@ def test_read_comsol_header_domain(filename, domain, type):
     ('intensity_product', [100, 500]),
     ('intensity_product', [100, 500]),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_header_domain_data(filename, domain_data, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_header_domain_data(filename, domain_data, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, _, _, _, actual_domain_data = io.read_comsol_header(path + type)
+    _, _, _, _, actual_domain_data = io.read_comsol_header(path + suffix)
     assert domain_data == actual_domain_data
 
 
@@ -142,11 +143,11 @@ def test_read_comsol_header_domain_data(filename, domain_data, type):
     'intensity_product',
     'character_collection',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_data_domain(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_data_domain(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, _, _, domain, domain_data = io.read_comsol_header(path + type)
-    data = io.read_comsol(path + type)
+    _, _, _, domain, domain_data = io.read_comsol_header(path + suffix)
+    data = io.read_comsol(path + suffix)
     data = data[0] if isinstance(data, tuple) else data
     assert domain == data.domain
     if domain == 'freq':
@@ -164,11 +165,11 @@ def test_read_comsol_data_domain(filename, type):
     ('pressure_parametric', 8),
     ('intensity_product', 8),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_data_shapes(filename, nodes, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_data_shapes(filename, nodes, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    expressions, _, parameters, _, _ = io.read_comsol_header(path + type)
-    data = io.read_comsol(path + type)
+    expressions, _, parameters, _, _ = io.read_comsol_header(path + suffix)
+    data = io.read_comsol(path + suffix)
     coordinates = data[1] if isinstance(data, tuple) else None
     data = data[0] if isinstance(data, tuple) else data
     if coordinates is not None:
@@ -186,10 +187,10 @@ def test_read_comsol_data_shapes(filename, nodes, type):
     'pressure_parametric',
     'intensity_product',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_coordinates(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_coordinates(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, coordinates = io.read_comsol(path + type)
+    _, coordinates = io.read_comsol(path + suffix)
     xyz = coordinates.cartesian
     assert all(xyz[0] == [-.5, -.5, -.5])
     assert all(xyz[1] == [0.5, -0.5, -0.5])
@@ -235,11 +236,11 @@ def test_read_comsol_first_value_data(filename, p1, suffix):
     ('pressure_parametric',
      complex(-1.6519703918208651E-4, -0.003880099599610891)),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_another_value_data(filename, p1, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_another_value_data(filename, p1, suffix):
     """Test freq=500; theta=0.7854; phi=3.1416"""
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    data, _ = io.read_comsol(path + type)
+    data, _ = io.read_comsol(path + suffix)
     point = 0
     exp = 0
     freq = 1
@@ -254,16 +255,16 @@ def test_read_comsol_another_value_data(filename, p1, type):
     ('pressure_parametric',
      complex(-1.6519703918208651E-4, -0.003880099599610891)),
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_parameters_another_value_data(filename, p1, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_parameters_another_value_data(filename, p1, suffix):
     """Test freq=500; theta=0.7854; phi=3.1416"""
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    _, _, parameters, _, _ = io.read_comsol_header(path + type)
+    _, _, parameters, _, _ = io.read_comsol_header(path + suffix)
     theta = 1
     phi = 2
     parameters['theta'] = [parameters['theta'][theta]]
     parameters['phi'] = [parameters['phi'][phi]]
-    data, _ = io.read_comsol(path + type, parameters=parameters)
+    data, _ = io.read_comsol(path + suffix, parameters=parameters)
     point = 0
     exp = 0
     freq = 1
@@ -280,11 +281,11 @@ def test_read_comsol_parameters_another_value_data(filename, p1, type):
     'intensity_product',
     'character_collection',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_expressions(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_expressions(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    expressions, _, _, _, _ = io.read_comsol_header(path + type)
-    data = io.read_comsol(path + type, expressions=[expressions[0]])
+    expressions, _, _, _, _ = io.read_comsol_header(path + suffix)
+    data = io.read_comsol(path + suffix, expressions=[expressions[0]])
     data = data[0] if isinstance(data, tuple) else data
     assert data.cshape[1] == 1
 
@@ -292,13 +293,13 @@ def test_read_comsol_expressions(filename, type):
 @pytest.mark.parametrize("filename",  [
     'pressure_parametric_incomplete',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_check_incomplete(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_check_incomplete(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    expressions, _, _, _, _ = io.read_comsol_header(path + type)
+    expressions, _, _, _, _ = io.read_comsol_header(path + suffix)
     with pytest.warns(Warning, match='Specific'):
         data, _ = io.read_comsol(
-            path + type, expressions=[expressions[0]])
+            path + suffix, expressions=[expressions[0]])
     assert all(np.isnan(data.freq[:, 0, -1, -1, 1]).flatten())
     data.freq[:, 0, -1, -1, 1] = 0
     assert any(~np.isnan(data.freq.flatten()))
@@ -308,14 +309,14 @@ def test_read_comsol_check_incomplete(filename, type):
     'intensity_parametric',
     'intensity_average',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_parameters_shape(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_parameters_shape(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
     expressions, expressions_unit, parameters, domain, domain_data \
-        = io.read_comsol_header(path + type)
+        = io.read_comsol_header(path + suffix)
     parameters['theta'] = parameters['theta'][:1]
     parameters['phi'] = parameters['phi'][:2]
-    data = io.read_comsol(path + type, parameters=parameters)
+    data = io.read_comsol(path + suffix, parameters=parameters)
     data = data[0] if isinstance(data, tuple) else data
     assert data.cshape[1] == len(expressions)
     assert data.cshape[2] == len(parameters['theta'][:1])
@@ -327,15 +328,15 @@ def test_read_comsol_parameters_shape(filename, type):
     'intensity_parametric',
     'intensity_average',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_expressions_value(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_expressions_value(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
     expressions, expressions_unit, parameters, domain, domain_data \
-        = io.read_comsol_header(path + type)
+        = io.read_comsol_header(path + suffix)
     data_exp = io.read_comsol(
-        path + type, expressions=[expressions[0], expressions[2]])
+        path + suffix, expressions=[expressions[0], expressions[2]])
     data_exp = data_exp[0] if isinstance(data_exp, tuple) else data_exp
-    data = io.read_comsol(path + type)
+    data = io.read_comsol(path + suffix)
     data = data[0] if isinstance(data, tuple) else data
     assert data_exp.freq[0, 0, 1, 1, 1] == data.freq[0, 0, 1, 1, 1]
     assert data_exp.freq[0, 1, 1, 1, 1] == data.freq[0, 2, 1, 1, 1]
@@ -348,12 +349,12 @@ def test_read_comsol_expressions_value(filename, type):
     'intensity_parametric_specific',
     'pressure_parametric_specific',
     ])
-@pytest.mark.parametrize("type",  ['.txt', '.dat', '.csv'])
-def test_read_comsol_check_specific_combination(filename, type):
+@pytest.mark.parametrize("suffix",  ['.txt', '.dat', '.csv'])
+def test_read_comsol_check_specific_combination(filename, suffix):
     path = os.path.join(os.getcwd(), 'tests', 'test_io_data', filename)
-    expressions, _, _, _, _ = io.read_comsol_header(path + type)
+    expressions, _, _, _, _ = io.read_comsol_header(path + suffix)
     with pytest.warns(Warning, match='Specific'):
-        data = io.read_comsol(path + type, expressions=[expressions[0]])
+        data = io.read_comsol(path + suffix, expressions=[expressions[0]])
     data = data[0] if isinstance(data, tuple) else data
     # For specific combinations shape of parameters need to be same
     assert data.cshape[2] == data.cshape[3]