From 598f222ecace1d853d9dec2f803404f629c75104 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Tue, 7 Jul 2026 15:06:24 +0000 Subject: [PATCH] Fix video-gallery delete test to patch Path.unlink for Python 3.10 test_delete_keeps_sidecar_listable_when_mp4_unlink_fails patched os.unlink, but delete() calls path.unlink(). On Python 3.10 Path.unlink dispatches through a cached _accessor bound to os.unlink at import, so patching os.unlink had no effect there and the simulated mp4 unlink wrongly succeeded (the assert delete() is False failed on 3.10 while passing on 3.11+, where Path.unlink looks up os.unlink dynamically). Patch Path.unlink itself, which delete() invokes directly on every supported Python version. Test-only; no behavior change. --- studio/backend/tests/test_video_gallery.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/studio/backend/tests/test_video_gallery.py b/studio/backend/tests/test_video_gallery.py index 9ad0ec630a..21a8dac014 100644 --- a/studio/backend/tests/test_video_gallery.py +++ b/studio/backend/tests/test_video_gallery.py @@ -8,6 +8,7 @@ from __future__ import annotations import json import os +from pathlib import Path import core.inference.video_gallery as gallery @@ -127,18 +128,20 @@ def test_delete_keeps_sidecar_listable_when_mp4_unlink_fails(monkeypatch): mp4 = directory / f"{record['id']}.mp4" sidecar = directory / f"{record['id']}.json" - real_unlink = os.unlink + real_unlink = Path.unlink - def _fail_on_mp4(path, *a, **k): - if str(path).endswith(".mp4"): + def _fail_on_mp4(self, *a, **k): + if self.suffix == ".mp4": raise PermissionError("mp4 locked") - return real_unlink(path, *a, **k) + return real_unlink(self, *a, **k) - # Scope the os.unlink patch to its own context so undoing it does NOT also revert the autouse - # fixture's studio_root redirect (both share the function-scoped monkeypatch); otherwise - # list_videos below would read the real home dir instead of the tmp gallery. + # Patch Path.unlink (what delete() actually calls) rather than os.unlink: on Python 3.10 + # Path.unlink dispatches through a cached _accessor bound to os.unlink at import, so patching + # os.unlink there has no effect and the mp4 delete would wrongly succeed. Scope it to its own + # context so undoing it does NOT also revert the autouse fixture's studio_root redirect (both + # share the function-scoped monkeypatch); otherwise list_videos below would read the real home. with pytest.MonkeyPatch.context() as m: - m.setattr(os, "unlink", _fail_on_mp4) + m.setattr(Path, "unlink", _fail_on_mp4) assert gallery.delete(record["id"]) is False # mp4 unlink failed # The sidecar was NOT dropped, so the record is still listable and the user can retry. assert sidecar.exists() and mp4.exists()