Skip to content

Commit 962f9bb

Browse files
committed
refactor(espeak_wrapper): fix ruff lint suggestions
1 parent 7b2289a commit 962f9bb

File tree

2 files changed

+44
-41
lines changed

2 files changed

+44
-41
lines changed

TTS/tts/utils/text/phonemizers/espeak_wrapper.py

+43-41
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
"""Wrapper to call the espeak/espeak-ng phonemizer."""
2+
13
import logging
24
import re
35
import subprocess
4-
from typing import Dict, List
6+
from typing import Optional
57

68
from packaging.version import Version
79

@@ -11,7 +13,7 @@
1113
logger = logging.getLogger(__name__)
1214

1315

14-
def is_tool(name):
16+
def _is_tool(name) -> bool:
1517
from shutil import which
1618

1719
return which(name) is not None
@@ -22,31 +24,33 @@ def is_tool(name):
2224
espeak_version_pattern = re.compile(r"text-to-speech:\s(?P<version>\d+\.\d+(\.\d+)?)")
2325

2426

25-
def get_espeak_version():
27+
def get_espeak_version() -> str:
28+
"""Return version of the `espeak` binary."""
2629
output = subprocess.getoutput("espeak --version")
2730
match = espeak_version_pattern.search(output)
2831

2932
return match.group("version")
3033

3134

32-
def get_espeakng_version():
35+
def get_espeakng_version() -> str:
36+
"""Return version of the `espeak-ng` binary."""
3337
output = subprocess.getoutput("espeak-ng --version")
3438
return output.split()[3]
3539

3640

3741
# priority: espeakng > espeak
38-
if is_tool("espeak-ng"):
42+
if _is_tool("espeak-ng"):
3943
_DEF_ESPEAK_LIB = "espeak-ng"
4044
_DEF_ESPEAK_VER = get_espeakng_version()
41-
elif is_tool("espeak"):
45+
elif _is_tool("espeak"):
4246
_DEF_ESPEAK_LIB = "espeak"
4347
_DEF_ESPEAK_VER = get_espeak_version()
4448
else:
4549
_DEF_ESPEAK_LIB = None
4650
_DEF_ESPEAK_VER = None
4751

4852

49-
def _espeak_exe(espeak_lib: str, args: List, sync=False) -> List[str]:
53+
def _espeak_exe(espeak_lib: str, args: list, *, sync: bool = False) -> list[bytes]:
5054
"""Run espeak with the given arguments."""
5155
cmd = [
5256
espeak_lib,
@@ -73,9 +77,7 @@ def _espeak_exe(espeak_lib: str, args: List, sync=False) -> List[str]:
7377
if p.stdin:
7478
p.stdin.close()
7579
return res
76-
res2 = []
77-
for line in res:
78-
res2.append(line)
80+
res2 = list(res)
7981
p.stdout.close()
8082
if p.stderr:
8183
p.stderr.close()
@@ -86,7 +88,7 @@ def _espeak_exe(espeak_lib: str, args: List, sync=False) -> List[str]:
8688

8789

8890
class ESpeak(BasePhonemizer):
89-
"""ESpeak wrapper calling `espeak` or `espeak-ng` from the command-line the perform G2P
91+
"""Wrapper calling `espeak` or `espeak-ng` from the command-line to perform G2P.
9092
9193
Args:
9294
language (str):
@@ -111,13 +113,17 @@ class ESpeak(BasePhonemizer):
111113
112114
"""
113115

114-
_ESPEAK_LIB = _DEF_ESPEAK_LIB
115-
_ESPEAK_VER = _DEF_ESPEAK_VER
116-
117-
def __init__(self, language: str, backend=None, punctuations=Punctuation.default_puncs(), keep_puncs=True):
118-
if self._ESPEAK_LIB is None:
119-
raise Exception(" [!] No espeak backend found. Install espeak-ng or espeak to your system.")
120-
self.backend = self._ESPEAK_LIB
116+
def __init__(
117+
self,
118+
language: str,
119+
backend: Optional[str] = None,
120+
punctuations: str = Punctuation.default_puncs(),
121+
keep_puncs: bool = True,
122+
):
123+
if _DEF_ESPEAK_LIB is None:
124+
msg = "[!] No espeak backend found. Install espeak-ng or espeak to your system."
125+
raise FileNotFoundError(msg)
126+
self.backend = _DEF_ESPEAK_LIB
121127

122128
# band-aid for backwards compatibility
123129
if language == "en":
@@ -130,35 +136,37 @@ def __init__(self, language: str, backend=None, punctuations=Punctuation.default
130136
self.backend = backend
131137

132138
@property
133-
def backend(self):
139+
def backend(self) -> str:
134140
return self._ESPEAK_LIB
135141

136142
@property
137-
def backend_version(self):
143+
def backend_version(self) -> str:
138144
return self._ESPEAK_VER
139145

140146
@backend.setter
141-
def backend(self, backend):
147+
def backend(self, backend: str) -> None:
142148
if backend not in ["espeak", "espeak-ng"]:
143-
raise Exception("Unknown backend: %s" % backend)
149+
msg = f"Unknown backend: {backend}"
150+
raise ValueError(msg)
144151
self._ESPEAK_LIB = backend
145152
self._ESPEAK_VER = get_espeakng_version() if backend == "espeak-ng" else get_espeak_version()
146153

147154
def auto_set_espeak_lib(self) -> None:
148-
if is_tool("espeak-ng"):
155+
if _is_tool("espeak-ng"):
149156
self._ESPEAK_LIB = "espeak-ng"
150157
self._ESPEAK_VER = get_espeakng_version()
151-
elif is_tool("espeak"):
158+
elif _is_tool("espeak"):
152159
self._ESPEAK_LIB = "espeak"
153160
self._ESPEAK_VER = get_espeak_version()
154161
else:
155-
raise Exception("Cannot set backend automatically. espeak-ng or espeak not found")
162+
msg = "Cannot set backend automatically. espeak-ng or espeak not found"
163+
raise FileNotFoundError(msg)
156164

157165
@staticmethod
158-
def name():
166+
def name() -> str:
159167
return "espeak"
160168

161-
def phonemize_espeak(self, text: str, separator: str = "|", tie=False) -> str:
169+
def phonemize_espeak(self, text: str, separator: str = "|", *, tie: bool = False) -> str:
162170
"""Convert input text to phonemes.
163171
164172
Args:
@@ -193,7 +201,7 @@ def phonemize_espeak(self, text: str, separator: str = "|", tie=False) -> str:
193201
args.append(text)
194202
# compute phonemes
195203
phonemes = ""
196-
for line in _espeak_exe(self._ESPEAK_LIB, args, sync=True):
204+
for line in _espeak_exe(self.backend, args, sync=True):
197205
logger.debug("line: %s", repr(line))
198206
ph_decoded = line.decode("utf8").strip()
199207
# espeak:
@@ -210,11 +218,11 @@ def phonemize_espeak(self, text: str, separator: str = "|", tie=False) -> str:
210218
phonemes += ph_decoded.strip()
211219
return phonemes.replace("_", separator)
212220

213-
def _phonemize(self, text, separator=None):
221+
def _phonemize(self, text: str, separator: str = "") -> str:
214222
return self.phonemize_espeak(text, separator, tie=False)
215223

216224
@staticmethod
217-
def supported_languages() -> Dict:
225+
def supported_languages() -> dict[str, str]:
218226
"""Get a dictionary of supported languages.
219227
220228
Returns:
@@ -224,16 +232,14 @@ def supported_languages() -> Dict:
224232
return {}
225233
args = ["--voices"]
226234
langs = {}
227-
count = 0
228-
for line in _espeak_exe(_DEF_ESPEAK_LIB, args, sync=True):
235+
for count, line in enumerate(_espeak_exe(_DEF_ESPEAK_LIB, args, sync=True)):
229236
line = line.decode("utf8").strip()
230237
if count > 0:
231238
cols = line.split()
232239
lang_code = cols[1]
233240
lang_name = cols[3]
234241
langs[lang_code] = lang_name
235242
logger.debug("line: %s", repr(line))
236-
count += 1
237243
return langs
238244

239245
def version(self) -> str:
@@ -242,16 +248,12 @@ def version(self) -> str:
242248
Returns:
243249
str: Version of the used backend.
244250
"""
245-
args = ["--version"]
246-
for line in _espeak_exe(self.backend, args, sync=True):
247-
version = line.decode("utf8").strip().split()[2]
248-
logger.debug("line: %s", repr(line))
249-
return version
251+
return self.backend_version
250252

251253
@classmethod
252-
def is_available(cls):
253-
"""Return true if ESpeak is available else false"""
254-
return is_tool("espeak") or is_tool("espeak-ng")
254+
def is_available(cls) -> bool:
255+
"""Return true if ESpeak is available else false."""
256+
return _is_tool("espeak") or _is_tool("espeak-ng")
255257

256258

257259
if __name__ == "__main__":

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ requires = [
88
]
99

1010
[tool.ruff]
11+
target-version = "py39"
1112
line-length = 120
1213
lint.extend-select = [
1314
"B033", # duplicate-value

0 commit comments

Comments
 (0)