Skip to content

Commit

Permalink
Use ruff formatter as pre-commit (#149)
Browse files Browse the repository at this point in the history
* Use ruff formatter as pre-commit

* Expand exceptions

* Update code

* Update docs

* Update code
  • Loading branch information
hagenw authored Jan 30, 2024
1 parent 41fff81 commit 41d5023
Show file tree
Hide file tree
Showing 20 changed files with 985 additions and 1,069 deletions.
10 changes: 0 additions & 10 deletions .flake8

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.8'
python-version: '3.10'

- name: Install pre-commit hooks
run: |
Expand Down
6 changes: 4 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#
#
default_language_version:
python: python3.8
python: python3.10

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.276
rev: v0.1.8
hooks:
- id: ruff
args: [ --fix ]
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Coding Convention
-----------------

We follow the PEP8_ convention for Python code
and check for correct syntax with ruff_.
and use ruff_ as a linter and code formatter.
In addition,
we check for common spelling errors with codespell_.
Both tools and possible exceptions
Expand All @@ -61,7 +61,8 @@ You can also install ruff_ and codespell_
and call it directly::

pip install ruff codespell # consider system wide installation
ruff check .
ruff check --fix . # lint all Python files, and fix any fixable errors
ruff format . # format code of all Python files
codespell

It can be restricted to specific folders::
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Code example for reading a file:
import audiofile
signal, sampling_rate = audiofile.read('signal.wav')
signal, sampling_rate = audiofile.read("signal.wav")
Under the hood it uses soundfile_ to read the audio files,
converting non-supported formats first to WAV files.
Expand Down
1 change: 1 addition & 0 deletions audiofile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# Dynamically get the version of the installed module
try:
import importlib.metadata

__version__ = importlib.metadata.version(__name__)
except Exception: # pragma: no cover
importlib = None # pragma: no cover
Expand Down
29 changes: 14 additions & 15 deletions audiofile/core/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,28 @@
np.random.seed(1)


@pytest.fixture(scope='session', autouse=True)
@pytest.fixture(scope="session", autouse=True)
def audio_file():
create_audio_files('.')
create_audio_files(".")

yield

# Clean up
for file in audeer.list_file_names('.', filetype='wav'):
for file in audeer.list_file_names(".", filetype="wav"):
if os.path.exists(file):
os.remove(file)
for file in audeer.list_file_names('.', filetype='flac'):
for file in audeer.list_file_names(".", filetype="flac"):
if os.path.exists(file):
os.remove(file)


def create_audio_files(
basedir,

basedir,
):
sampling_rate = 8000
mono_wav_file = audeer.path(basedir, 'mono.wav')
stereo_wav_file = audeer.path(basedir, 'stereo.wav')
stereo_flac_file = audeer.path(basedir, 'stereo.flac')
mono_wav_file = audeer.path(basedir, "mono.wav")
stereo_wav_file = audeer.path(basedir, "stereo.wav")
stereo_flac_file = audeer.path(basedir, "stereo.flac")
signal = am_fm_synth(1.5, 1, sampling_rate)
audiofile.write(mono_wav_file, signal, sampling_rate)
signal = am_fm_synth(1.5, 2, sampling_rate)
Expand All @@ -42,11 +41,11 @@ def create_audio_files(


def am_fm_synth(
duration: float,
num_channels: int = 1,
sampling_rate: int = 16000,
*,
dtype: type = np.float32,
duration: float,
num_channels: int = 1,
sampling_rate: int = 16000,
*,
dtype: type = np.float32,
) -> np.ndarray:
r"""Synthesise an AM/FM signal of given duration (sampled at given rate).
Expand Down Expand Up @@ -78,7 +77,7 @@ def am_fm_synth(
# No reinitialisation (to get true stereo)
for t in range(n_samples):
sig[ch_indx, t] = g * np.cos(ph_fm)
sig[ch_indx, t] *= ((1 - g_am) + g_am * np.square(np.cos(ph_am)))
sig[ch_indx, t] *= (1 - g_am) + g_am * np.square(np.cos(ph_am))
ph_am += omega_am / 2
ph_fm += omega0_car + omega_dev * np.cos(omega_mod * t)
return sig
10 changes: 5 additions & 5 deletions audiofile/core/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@


def convert(
infile: str,
outfile: str,
offset: float = 0,
duration: float = None,
infile: str,
outfile: str,
offset: float = 0,
duration: float = None,
):
"""Convert any audio/video file to WAV.
Expand All @@ -29,6 +29,6 @@ def convert(
# Convert to WAV file with ffmpeg
run_ffmpeg(infile, outfile, offset, duration)
except FileNotFoundError:
raise binary_missing_error('ffmpeg')
raise binary_missing_error("ffmpeg")
except subprocess.CalledProcessError:
raise broken_file_error(infile)
81 changes: 38 additions & 43 deletions audiofile/core/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,35 @@ def bit_depth(file: str) -> typing.Optional[int]:
broken or format is not supported
Examples:
>>> bit_depth('stereo.wav')
>>> bit_depth("stereo.wav")
16
"""
file = audeer.safe_path(file)
file_type = file_extension(file)
if file_type == 'wav':
if file_type == "wav":
precision_mapping = {
'PCM_16': 16,
'PCM_24': 24,
'PCM_32': 32,
'PCM_U8': 8,
'FLOAT': 32,
'DOUBLE': 64,
'ULAW': 8,
'ALAW': 8,
'IMA_ADPCM': 4,
'MS_ADPCM': 4,
'GSM610': 16, # not sure if this could be variable?
'G721_32': 4, # not sure if correct
"PCM_16": 16,
"PCM_24": 24,
"PCM_32": 32,
"PCM_U8": 8,
"FLOAT": 32,
"DOUBLE": 64,
"ULAW": 8,
"ALAW": 8,
"IMA_ADPCM": 4,
"MS_ADPCM": 4,
"GSM610": 16, # not sure if this could be variable?
"G721_32": 4, # not sure if correct
}
elif file_type == 'flac':
elif file_type == "flac":
precision_mapping = {
'PCM_16': 16,
'PCM_24': 24,
'PCM_32': 32,
'PCM_S8': 8,
"PCM_16": 16,
"PCM_24": 24,
"PCM_32": 32,
"PCM_S8": 8,
}
if file_extension(file) in ['wav', 'flac']:
if file_extension(file) in ["wav", "flac"]:
depth = precision_mapping[soundfile.info(file).subtype]
else:
depth = None
Expand All @@ -85,7 +85,7 @@ def channels(file: str) -> int:
broken or format is not supported
Examples:
>>> channels('stereo.wav')
>>> channels("stereo.wav")
2
"""
Expand All @@ -94,20 +94,16 @@ def channels(file: str) -> int:
return soundfile.info(file).channels
else:
try:
cmd = ['soxi', '-c', file]
cmd = ["soxi", "-c", file]
return int(run(cmd))
except (FileNotFoundError, subprocess.CalledProcessError):
# For MP4 stored and returned number of channels can be different
cmd1 = [
'mediainfo', '--Inform=Audio;%Channel(s)_Original%', file
]
cmd2 = [
'mediainfo', '--Inform=Audio;%Channel(s)%', file
]
cmd1 = ["mediainfo", "--Inform=Audio;%Channel(s)_Original%", file]
cmd2 = ["mediainfo", "--Inform=Audio;%Channel(s)%", file]
try:
return int(run(cmd1))
except FileNotFoundError:
raise binary_missing_error('mediainfo')
raise binary_missing_error("mediainfo")
except (ValueError, subprocess.CalledProcessError):
try:
return int(run(cmd2))
Expand Down Expand Up @@ -152,7 +148,7 @@ def duration(file: str, sloppy=False) -> float:
broken or format is not supported
Examples:
>>> duration('stereo.wav')
>>> duration("stereo.wav")
1.5
"""
Expand All @@ -162,17 +158,17 @@ def duration(file: str, sloppy=False) -> float:

if sloppy:
try:
cmd = ['soxi', '-D', file]
cmd = ["soxi", "-D", file]
duration = float(run(cmd))
except (FileNotFoundError, subprocess.CalledProcessError):
try:
cmd = ['mediainfo', '--Inform=Audio;%Duration%', file]
cmd = ["mediainfo", "--Inform=Audio;%Duration%", file]
duration = run(cmd)
if duration:
# Convert to seconds, as mediainfo returns milliseconds
duration = float(duration) / 1000
except FileNotFoundError:
raise binary_missing_error('mediainfo')
raise binary_missing_error("mediainfo")
# Behavior for broken files is different on Windows
# where no error is raised,
# but an empty duration is returned.
Expand Down Expand Up @@ -206,22 +202,21 @@ def samples(file: str) -> int:
broken or format is not supported
Examples:
>>> samples('stereo.wav')
>>> samples("stereo.wav")
12000
"""

def samples_as_int(file):
return int(
soundfile.info(file).duration * soundfile.info(file).samplerate
)
return int(soundfile.info(file).duration * soundfile.info(file).samplerate)

file = audeer.safe_path(file)
if file_extension(file) in SNDFORMATS:
return samples_as_int(file)
else:
# Always convert to WAV for non SNDFORMATS
with tempfile.TemporaryDirectory(prefix='audiofile') as tmpdir:
tmpfile = os.path.join(tmpdir, 'tmp.wav')
with tempfile.TemporaryDirectory(prefix="audiofile") as tmpdir:
tmpfile = os.path.join(tmpdir, "tmp.wav")
convert_to_wav(file, tmpfile)
return samples_as_int(tmpfile)

Expand All @@ -242,7 +237,7 @@ def sampling_rate(file: str) -> int:
broken or format is not supported
Examples:
>>> sampling_rate('stereo.wav')
>>> sampling_rate("stereo.wav")
8000
"""
Expand All @@ -251,11 +246,11 @@ def sampling_rate(file: str) -> int:
return soundfile.info(file).samplerate
else:
try:
cmd = ['soxi', '-r', file]
cmd = ["soxi", "-r", file]
return int(run(cmd))
except (FileNotFoundError, subprocess.CalledProcessError):
try:
cmd = ['mediainfo', '--Inform=Audio;%SamplingRate%', file]
cmd = ["mediainfo", "--Inform=Audio;%SamplingRate%", file]
sampling_rate = run(cmd)
if sampling_rate:
return int(sampling_rate)
Expand All @@ -264,6 +259,6 @@ def sampling_rate(file: str) -> int:
# to align coverage under Windows and Linux
raise subprocess.CalledProcessError(-2, cmd)
except FileNotFoundError:
raise binary_missing_error('mediainfo')
raise binary_missing_error("mediainfo")
except subprocess.CalledProcessError:
raise broken_file_error(file)
Loading

0 comments on commit 41d5023

Please sign in to comment.