From c626b8c0b1a8147d06ca281c2fe9480fb252c7e3 Mon Sep 17 00:00:00 2001 From: Steven Van Ingelgem Date: Fri, 14 Aug 2026 07:02:00 +0200 Subject: [PATCH] Fix three failures when exporting on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_test_sample builds its download URL with os.path.join, which on Windows produces '.../raw/main/assets\clean_freesound_33711.wav' and 404s. The local branch still uses os.path.join, since that one is a filesystem path. download_file opens a file inside get_cache_dir() without creating it. That directory does not exist until something has downloaded before, so the first download on a clean machine raises FileNotFoundError rather than downloading. Affects every platform; it only shows up on a machine with no cache yet. The export tarball is built with tarfile.add() and no arcname, so every entry carries the exporter's own export_dir. Extracting recreates that tree instead of dropping five files, and the released artefact contains the path it was built in — on Windows that includes the builder's username, e.g. 'Users//AppData/Local/Temp/.../enc.onnx'. Passing arcname stores bare filenames. Verified on Windows 10 with python 3.11, torch 2.1.2: the sample downloads to a freshly removed cache, and the tar contains exactly enc.onnx, erb_dec.onnx, df_dec.onnx, config.ini and version.txt. --- DeepFilterNet/df/io.py | 8 +++++--- DeepFilterNet/df/scripts/export.py | 12 +++++++----- DeepFilterNet/df/utils.py | 4 ++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/DeepFilterNet/df/io.py b/DeepFilterNet/df/io.py index 58024b152..2c0c0f805 100644 --- a/DeepFilterNet/df/io.py +++ b/DeepFilterNet/df/io.py @@ -118,12 +118,14 @@ def resample(audio: Tensor, orig_sr: int, new_sr: int, method="sinc_fast"): def get_test_sample(sr: int = 48000) -> Tensor: dir = get_git_root() - file_path = os.path.join("assets", "clean_freesound_33711.wav") + rel_path = ("assets", "clean_freesound_33711.wav") if dir is None: - url = "https://github.com/Rikorose/DeepFilterNet/raw/main/" + file_path + # Join with "/" rather than os.path.join: on Windows the latter yields + # ".../raw/main/assets\clean_freesound_33711.wav", which 404s. + url = "https://github.com/Rikorose/DeepFilterNet/raw/main/" + "/".join(rel_path) save_dir = get_cache_dir() path = download_file(url, save_dir) else: - path = os.path.join(dir, file_path) + path = os.path.join(dir, *rel_path) sample, _ = load_audio(path, sr=sr) return sample diff --git a/DeepFilterNet/df/scripts/export.py b/DeepFilterNet/df/scripts/export.py index ea5afd752..19d23394e 100644 --- a/DeepFilterNet/df/scripts/export.py +++ b/DeepFilterNet/df/scripts/export.py @@ -330,11 +330,13 @@ def main(args): f.write(f"{model_name}_epoch_{epoch}") tar_name = export_dir / (Path(model_base_dir).name + "_onnx.tar.gz") with tarfile.open(tar_name, mode="w:gz") as f: - f.add(os.path.join(args.export_dir, "enc.onnx")) - f.add(os.path.join(args.export_dir, "erb_dec.onnx")) - f.add(os.path.join(args.export_dir, "df_dec.onnx")) - f.add(os.path.join(args.export_dir, "config.ini")) - f.add(os.path.join(args.export_dir, "version.txt")) + for name in ("enc.onnx", "erb_dec.onnx", "df_dec.onnx", "config.ini", "version.txt"): + # arcname, so the archive holds bare filenames. Without it every + # entry carries the exporter's own export_dir — "tmp/foo/enc.onnx", + # or on Windows "Users//AppData/Local/Temp/.../enc.onnx" — + # which recreates that tree on extraction and puts the builder's + # username in the released artefact. + f.add(os.path.join(args.export_dir, name), arcname=name) if __name__ == "__main__": diff --git a/DeepFilterNet/df/utils.py b/DeepFilterNet/df/utils.py index cea7a9b3e..7b123ef12 100644 --- a/DeepFilterNet/df/utils.py +++ b/DeepFilterNet/df/utils.py @@ -210,6 +210,10 @@ def download_file(url: str, download_dir: str, extract: bool = False): import requests local_filename = url.split("/")[-1] + # get_cache_dir() names a directory but does not create it, so on a machine + # that has not downloaded anything before, the open() below raises + # FileNotFoundError instead of downloading. + os.makedirs(download_dir, exist_ok=True) local_filename = os.path.join(download_dir, local_filename) with requests.get(url, stream=True) as r: if r.status_code >= 400: