* fix(diarization): shim use_auth_token->token for pyannote on HF Hub 1.x (#167) pyannote-audio 3.x (pipeline.py:102) calls hf_hub_download(use_auth_token=...), which huggingface_hub 1.x removed (only 'token' now) -> 'unexpected keyword argument use_auth_token', breaking speaker diarization. Wrap hf_hub_download/ snapshot_download to translate the dead kwarg, applied before pyannote's 'from huggingface_hub import hf_hub_download' binds it (+ patch already-loaded pyannote modules). Verified the real pyannote reference binds the shim. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(diarization): use pytest.importorskip (fixes CodeQL uninitialized-local) CodeQL doesn't model pytest.skip() as no-return, so it flagged _pp as a possibly-uninitialized local (py/uninitialized-local-variable, error). Switch to pytest.importorskip — cleaner and CodeQL-clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""#167 — pyannote-audio 3.x passes the removed `use_auth_token` kwarg to
|
|
huggingface_hub.hf_hub_download (HF Hub 1.x only accepts `token`), breaking
|
|
diarization. Verify the compat shim translates the kwarg and that pyannote
|
|
actually binds the wrapped function."""
|
|
import pytest
|
|
|
|
from services.model_manager import _ensure_pyannote_hf_token_compat
|
|
|
|
|
|
def test_shim_translates_use_auth_token_to_token(monkeypatch):
|
|
import huggingface_hub
|
|
|
|
seen = {}
|
|
|
|
def fake(*args, token=None, **kwargs):
|
|
# Mimic HF Hub 1.x: `use_auth_token` is no longer accepted.
|
|
if "use_auth_token" in kwargs:
|
|
raise TypeError(
|
|
"hf_hub_download() got an unexpected keyword argument 'use_auth_token'"
|
|
)
|
|
seen["token"] = token
|
|
return "downloaded"
|
|
|
|
monkeypatch.setattr(huggingface_hub, "hf_hub_download", fake, raising=False)
|
|
monkeypatch.setattr(huggingface_hub, "snapshot_download", fake, raising=False)
|
|
|
|
_ensure_pyannote_hf_token_compat()
|
|
|
|
# The wrapped fn must translate the dead kwarg instead of raising.
|
|
result = huggingface_hub.hf_hub_download(repo_id="r", filename="f", use_auth_token="secret")
|
|
assert result == "downloaded"
|
|
assert seen["token"] == "secret"
|
|
|
|
|
|
def test_shim_is_idempotent(monkeypatch):
|
|
import huggingface_hub
|
|
|
|
def fake(*args, token=None, **kwargs):
|
|
return token
|
|
|
|
monkeypatch.setattr(huggingface_hub, "hf_hub_download", fake, raising=False)
|
|
_ensure_pyannote_hf_token_compat()
|
|
once = huggingface_hub.hf_hub_download
|
|
_ensure_pyannote_hf_token_compat()
|
|
twice = huggingface_hub.hf_hub_download
|
|
assert once is twice # not re-wrapped
|
|
assert getattr(twice, "_ov_uat_shim", False) is True
|
|
|
|
|
|
def test_pyannote_binds_the_shim():
|
|
"""The real proof: after the shim, pyannote's own `hf_hub_download`
|
|
reference translates `use_auth_token` rather than raising."""
|
|
_ensure_pyannote_hf_token_compat()
|
|
# importorskip imports the module (or skips) — and since the shim patched
|
|
# huggingface_hub first, pyannote's `from huggingface_hub import
|
|
# hf_hub_download` (pipeline.py:34) binds the wrapped fn. (Also avoids the
|
|
# CodeQL "possibly-uninitialized local" false positive from a try/skip.)
|
|
_pp = pytest.importorskip("pyannote.audio.core.pipeline")
|
|
assert getattr(_pp.hf_hub_download, "_ov_uat_shim", False), (
|
|
"pyannote.audio.core.pipeline.hf_hub_download is not the use_auth_token shim"
|
|
)
|