Skip to content

Commit

Permalink
Merge pull request #255 from idiap/drop-py39
Browse files Browse the repository at this point in the history
Drop Python 3.9 support
  • Loading branch information
eginhard authored Jan 16, 2025
2 parents 44c3491 + 008912c commit 420a02f
Show file tree
Hide file tree
Showing 175 changed files with 1,091 additions and 1,296 deletions.
5 changes: 3 additions & 2 deletions .github/actions/setup-uv/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ runs:
using: 'composite'
steps:
- name: Install uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v5
with:
version: "0.5.4"
version: "0.5.17"
enable-cache: true
cache-dependency-glob: "**/pyproject.toml"
python-version: ${{ matrix.python-version }}
6 changes: 0 additions & 6 deletions .github/workflows/style_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ on:
jobs:
lint:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [3.9]
steps:
- uses: actions/checkout@v4
- name: Setup uv
uses: ./.github/actions/setup-uv
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Lint check
run: make lint
14 changes: 4 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]
subset: ["data_tests", "inference_tests", "test_aux", "test_text"]
steps:
- uses: actions/checkout@v4
- name: Setup uv
uses: ./.github/actions/setup-uv
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install Espeak
if: contains(fromJSON('["inference_tests", "test_text"]'), matrix.subset)
run: |
Expand All @@ -50,7 +48,7 @@ jobs:
- name: Unit tests
run: |
resolution=highest
if [ "${{ matrix.python-version }}" == "3.9" ]; then
if [ "${{ matrix.python-version }}" == "3.10" ]; then
resolution=lowest-direct
fi
uv run --resolution=$resolution --extra server --extra languages make ${{ matrix.subset }}
Expand All @@ -66,14 +64,12 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.12"]
python-version: ["3.10", "3.12"]
subset: ["test_tts", "test_tts2", "test_vocoder", "test_xtts"]
steps:
- uses: actions/checkout@v4
- name: Setup uv
uses: ./.github/actions/setup-uv
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install Espeak
if: contains(fromJSON('["test_tts", "test_tts2", "test_xtts"]'), matrix.subset)
run: |
Expand All @@ -94,7 +90,7 @@ jobs:
- name: Integration tests
run: |
resolution=highest
if [ "${{ matrix.python-version }}" == "3.9" ]; then
if [ "${{ matrix.python-version }}" == "3.10" ]; then
resolution=lowest-direct
fi
uv run --resolution=$resolution --extra server --extra languages make ${{ matrix.subset }}
Expand All @@ -116,8 +112,6 @@ jobs:
- uses: actions/checkout@v4
- name: Setup uv
uses: ./.github/actions/setup-uv
- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}
- name: Install Espeak
run: |
sudo apt-get update
Expand Down
8 changes: 2 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ repos:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: "https://github.com/psf/black"
rev: 24.2.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.0
rev: v0.9.1
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
uv run make test_all # run all the tests, report all the errors
```

9. Format your code. We use ```black``` for code formatting.
9. Format your code. We use ```ruff``` for code formatting.

```bash
make style
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ test_failed: ## only run tests failed the last time.
coverage run -m pytest -x -v --last-failed tests

style: ## update code style.
uv run --only-dev black ${target_dirs}
uv run --only-dev ruff format ${target_dirs}

lint: ## run linters.
uv run --only-dev ruff check ${target_dirs}
uv run --only-dev black ${target_dirs} --check
uv run --only-dev ruff format ${target_dirs} --check

system-deps: ## install linux system deps
sudo apt-get install -y libsndfile1-dev
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ You can also help us implement more models.
<!-- start installation -->
## Installation

🐸TTS is tested on Ubuntu 24.04 with **python >= 3.9, < 3.13**, but should also
🐸TTS is tested on Ubuntu 24.04 with **python >= 3.10, < 3.13**, but should also
work on Mac and Windows.

If you are only interested in [synthesizing speech](https://coqui-tts.readthedocs.io/en/latest/inference.html) with the pretrained 🐸TTS models, installing from PyPI is the easiest option.
Expand Down
77 changes: 38 additions & 39 deletions TTS/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import tempfile
import warnings
from pathlib import Path
from typing import Optional, Union

from torch import nn

Expand All @@ -22,15 +21,15 @@ def __init__(
self,
model_name: str = "",
*,
model_path: Optional[str] = None,
config_path: Optional[str] = None,
vocoder_name: Optional[str] = None,
vocoder_path: Optional[str] = None,
vocoder_config_path: Optional[str] = None,
encoder_path: Optional[str] = None,
encoder_config_path: Optional[str] = None,
speakers_file_path: Optional[str] = None,
language_ids_file_path: Optional[str] = None,
model_path: str | None = None,
config_path: str | None = None,
vocoder_name: str | None = None,
vocoder_path: str | None = None,
vocoder_config_path: str | None = None,
encoder_path: str | None = None,
encoder_config_path: str | None = None,
speakers_file_path: str | None = None,
language_ids_file_path: str | None = None,
progress_bar: bool = True,
gpu: bool = False,
) -> None:
Expand Down Expand Up @@ -77,8 +76,8 @@ def __init__(
super().__init__()
self.manager = ModelManager(models_file=self.get_models_file_path(), progress_bar=progress_bar)
self.config = load_config(config_path) if config_path else None
self.synthesizer: Optional[Synthesizer] = None
self.voice_converter: Optional[Synthesizer] = None
self.synthesizer: Synthesizer | None = None
self.voice_converter: Synthesizer | None = None
self.model_name = ""

self.vocoder_path = vocoder_path
Expand Down Expand Up @@ -156,8 +155,8 @@ def list_models() -> list[str]:
return ModelManager(models_file=TTS.get_models_file_path(), progress_bar=False).list_models()

def download_model_by_name(
self, model_name: str, vocoder_name: Optional[str] = None
) -> tuple[Optional[Path], Optional[Path], Optional[Path], Optional[Path], Optional[Path]]:
self, model_name: str, vocoder_name: str | None = None
) -> tuple[Path | None, Path | None, Path | None, Path | None, Path | None]:
model_path, config_path, model_item = self.manager.download_model(model_name)
if "fairseq" in model_name or (model_item is not None and isinstance(model_item["model_url"], list)):
# return model directory if there are multiple files
Expand All @@ -176,7 +175,7 @@ def download_model_by_name(
vocoder_path, vocoder_config_path, _ = self.manager.download_model(vocoder_name)
return model_path, config_path, vocoder_path, vocoder_config_path, None

def load_model_by_name(self, model_name: str, vocoder_name: Optional[str] = None, *, gpu: bool = False) -> None:
def load_model_by_name(self, model_name: str, vocoder_name: str | None = None, *, gpu: bool = False) -> None:
"""Load one of the 🐸TTS models by name.
Args:
Expand All @@ -185,7 +184,7 @@ def load_model_by_name(self, model_name: str, vocoder_name: Optional[str] = None
"""
self.load_tts_model_by_name(model_name, vocoder_name, gpu=gpu)

def load_vc_model_by_name(self, model_name: str, vocoder_name: Optional[str] = None, *, gpu: bool = False) -> None:
def load_vc_model_by_name(self, model_name: str, vocoder_name: str | None = None, *, gpu: bool = False) -> None:
"""Load one of the voice conversion models by name.
Args:
Expand All @@ -205,7 +204,7 @@ def load_vc_model_by_name(self, model_name: str, vocoder_name: Optional[str] = N
use_cuda=gpu,
)

def load_tts_model_by_name(self, model_name: str, vocoder_name: Optional[str] = None, *, gpu: bool = False) -> None:
def load_tts_model_by_name(self, model_name: str, vocoder_name: str | None = None, *, gpu: bool = False) -> None:
"""Load one of 🐸TTS models by name.
Args:
Expand Down Expand Up @@ -261,11 +260,11 @@ def load_tts_model_by_path(self, model_path: str, config_path: str, *, gpu: bool

def _check_arguments(
self,
speaker: Optional[str] = None,
language: Optional[str] = None,
speaker_wav: Optional[str] = None,
emotion: Optional[str] = None,
speed: Optional[float] = None,
speaker: str | None = None,
language: str | None = None,
speaker_wav: str | None = None,
emotion: str | None = None,
speed: float | None = None,
**kwargs,
) -> None:
"""Check if the arguments are valid for the model."""
Expand All @@ -284,11 +283,11 @@ def _check_arguments(
def tts(
self,
text: str,
speaker: Optional[str] = None,
language: Optional[str] = None,
speaker_wav: Optional[str] = None,
emotion: Optional[str] = None,
speed: Optional[float] = None,
speaker: str | None = None,
language: str | None = None,
speaker_wav: str | None = None,
emotion: str | None = None,
speed: float | None = None,
split_sentences: bool = True,
**kwargs,
):
Expand Down Expand Up @@ -333,10 +332,10 @@ def tts(
def tts_to_file(
self,
text: str,
speaker: Optional[str] = None,
language: Optional[str] = None,
speaker_wav: Optional[str] = None,
emotion: Optional[str] = None,
speaker: str | None = None,
language: str | None = None,
speaker_wav: str | None = None,
emotion: str | None = None,
speed: float = 1.0,
pipe_out=None,
file_path: str = "output.wav",
Expand Down Expand Up @@ -388,7 +387,7 @@ def tts_to_file(
def voice_conversion(
self,
source_wav: str,
target_wav: Union[str, list[str]],
target_wav: str | list[str],
):
"""Voice conversion with FreeVC. Convert source wav to target speaker.
Expand All @@ -406,7 +405,7 @@ def voice_conversion(
def voice_conversion_to_file(
self,
source_wav: str,
target_wav: Union[str, list[str]],
target_wav: str | list[str],
file_path: str = "output.wav",
pipe_out=None,
) -> str:
Expand All @@ -430,9 +429,9 @@ def tts_with_vc(
self,
text: str,
*,
language: Optional[str] = None,
speaker_wav: Union[str, list[str]],
speaker: Optional[str] = None,
language: str | None = None,
speaker_wav: str | list[str],
speaker: str | None = None,
split_sentences: bool = True,
):
"""Convert text to speech with voice conversion.
Expand Down Expand Up @@ -473,10 +472,10 @@ def tts_with_vc_to_file(
self,
text: str,
*,
language: Optional[str] = None,
speaker_wav: Union[str, list[str]],
language: str | None = None,
speaker_wav: str | list[str],
file_path: str = "output.wav",
speaker: Optional[str] = None,
speaker: str | None = None,
split_sentences: bool = True,
pipe_out=None,
) -> str:
Expand Down
5 changes: 2 additions & 3 deletions TTS/bin/compute_embeddings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import sys
from argparse import RawTextHelpFormatter
from typing import Optional

import torch
from tqdm import tqdm
Expand All @@ -16,7 +15,7 @@
from TTS.utils.generic_utils import ConsoleFormatter, setup_logger


def parse_args(arg_list: Optional[list[str]]) -> argparse.Namespace:
def parse_args(arg_list: list[str] | None) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="""Compute embedding vectors for each audio file in a dataset and store them keyed by `{dataset_name}#{file_path}` in a .pth file\n\n"""
"""
Expand Down Expand Up @@ -185,7 +184,7 @@ def compute_embeddings(
print("Speaker embeddings saved at:", mapping_file_path)


def main(arg_list: Optional[list[str]] = None):
def main(arg_list: list[str] | None = None):
setup_logger("TTS", level=logging.INFO, stream=sys.stdout, formatter=ConsoleFormatter())
args = parse_args(arg_list)

Expand Down
6 changes: 2 additions & 4 deletions TTS/bin/compute_statistics.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import glob
import logging
import os
import sys
from typing import Optional

import numpy as np
from tqdm import tqdm
Expand All @@ -18,7 +16,7 @@
from TTS.utils.generic_utils import ConsoleFormatter, setup_logger


def parse_args(arg_list: Optional[list[str]]) -> tuple[argparse.Namespace, list[str]]:
def parse_args(arg_list: list[str] | None) -> tuple[argparse.Namespace, list[str]]:
parser = argparse.ArgumentParser(description="Compute mean and variance of spectrogtram features.")
parser.add_argument("config_path", type=str, help="TTS config file path to define audio processin parameters.")
parser.add_argument("out_path", type=str, help="save path (directory and filename).")
Expand All @@ -31,7 +29,7 @@ def parse_args(arg_list: Optional[list[str]]) -> tuple[argparse.Namespace, list[
return parser.parse_known_args(arg_list)


def main(arg_list: Optional[list[str]] = None):
def main(arg_list: list[str] | None = None):
"""Run preprocessing process."""
setup_logger("TTS", level=logging.INFO, stream=sys.stderr, formatter=ConsoleFormatter())
args, overrides = parse_args(arg_list)
Expand Down
5 changes: 2 additions & 3 deletions TTS/bin/extract_tts_spectrograms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging
import sys
from pathlib import Path
from typing import Optional

import numpy as np
import torch
Expand All @@ -27,7 +26,7 @@
use_cuda = torch.cuda.is_available()


def parse_args(arg_list: Optional[list[str]]) -> argparse.Namespace:
def parse_args(arg_list: list[str] | None) -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--config_path", type=str, help="Path to config file for training.", required=True)
parser.add_argument("--checkpoint_path", type=str, help="Model file to be restored.", required=True)
Expand Down Expand Up @@ -244,7 +243,7 @@ def extract_spectrograms(
f.write(f"{data[0] / data[1]}.npy\n")


def main(arg_list: Optional[list[str]] = None) -> None:
def main(arg_list: list[str] | None = None) -> None:
setup_logger("TTS", level=logging.INFO, stream=sys.stdout, formatter=ConsoleFormatter())
args = parse_args(arg_list)
config = load_config(args.config_path)
Expand Down
Loading

0 comments on commit 420a02f

Please sign in to comment.