Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2d41bee
Update `list_video_files_in_folder` only filter explicitly provided f…
deruyter92 May 4, 2026
96e31be
add test for list_videos_in_folder
deruyter92 May 4, 2026
3c63e90
Add deprecation utils: decorator for deprecated functions
deruyter92 May 7, 2026
b92103e
move `list_videos_in_folder` to `collect_video_paths` in auxfun_video…
deruyter92 May 7, 2026
ee4d9b1
export `deeplabcut.collect_video_paths(..)` from auxfun_videos.py
deruyter92 May 8, 2026
2014a59
update `collect_video_paths`: add exclude patterns
deruyter92 May 8, 2026
f6f1ee5
deprecate auxfun `get_list_of_videos` in favor of `collect_video_paths`
deruyter92 May 8, 2026
f6b33d2
add pytest deprecation marker `test_get_list_of_videos`
deruyter92 May 8, 2026
659bf7d
Mark `get_video_list` as deprecated (keep for now for backward compat…
deruyter92 May 8, 2026
983951d
fix test_collect_video_paths: rename keyword -> extensions
deruyter92 May 8, 2026
7d71306
Adjust `extensions` parameter: flexibly coerce str / list / tuple ->…
deruyter92 May 8, 2026
bce0ba9
Merge branch 'main' into jaap/update_list_videos_in_folder
C-Achard May 12, 2026
adadf08
`collect_video_paths`: sort videos if shuffle=False
deruyter92 May 12, 2026
ce8bcf5
update docstring non-recursive directory scanning.
deruyter92 May 12, 2026
75a4d0a
update collect_video_paths: DEFAULT_EXCLUDE_PATTERNS
deruyter92 May 12, 2026
481d3fa
update _coerce_extensions: only "" and None normalize to None
deruyter92 May 12, 2026
8ca9b49
fix instance check in _coerce_video_extensions
deruyter92 May 12, 2026
39557ec
fix pytest: assert alphabetic ordering if shuffle=False
deruyter92 May 12, 2026
39cfd94
fix empty string case in _coerce_extensions
deruyter92 May 12, 2026
77a05dc
Add structured deprecation info and warnings (#3326)
C-Achard May 12, 2026
5610a49
Merge branch 'main' into jaap/update_list_videos_in_folder
C-Achard May 13, 2026
792d35d
guarantee unchanged behavior for deprecated `get_list_of_videos` and …
deruyter92 May 13, 2026
fe38152
add warning if still unsupported extensions encountered
deruyter92 May 13, 2026
69981f1
Consequently adjust `videotype` signatures of collect_video_path callers
deruyter92 May 15, 2026
096973e
refactor collect_video_paths: add warnings, raise for empty sequence.
deruyter92 May 15, 2026
0929e7b
update tests for collect_video_paths
deruyter92 May 15, 2026
996b220
Merge branch 'main' into jaap/update_list_videos_in_folder
MMathisLab May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add test for list_videos_in_folder
  • Loading branch information
deruyter92 committed May 4, 2026
commit 96e31be134729d5f38a2ac04e3964e0ceeb9b15b
162 changes: 162 additions & 0 deletions tests/pose_estimation_pytorch/apis/test_list_videos_in_folder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#
# DeepLabCut Toolbox (deeplabcut.org)
# © A. & M.W. Mathis Labs
# https://github.com/DeepLabCut/DeepLabCut
#
# Please see AUTHORS for contributors.
# https://github.com/DeepLabCut/DeepLabCut/blob/main/AUTHORS
#
# Licensed under GNU Lesser General Public License v3.0
#
"""Tests for ``list_videos_in_folder``.

These tests pin down the rule:

* When ``video_type`` is not set, directory enumeration filters by
``SUPPORTED_VIDEOS`` but explicitly-supplied files are trusted (returned
as-is, even if they have no suffix).
* When ``video_type`` is set, it is honoured everywhere — both for files
pulled from directories and for files supplied by the caller.
"""

from __future__ import annotations

from pathlib import Path

import pytest

from deeplabcut.pose_estimation_pytorch.apis.utils import list_videos_in_folder
from deeplabcut.utils.auxfun_videos import SUPPORTED_VIDEOS


def _touch(path: Path) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"")
return path


def test_keeps_suffixless_files_when_explicitly_listed(tmp_path):
"""Regression test: a caller-supplied file without an extension (e.g.
a content-addressed cache entry) must not be silently dropped."""
suffixed = _touch(tmp_path / "video.mp4")
hashed = _touch(tmp_path / "abcd1234")

result = list_videos_in_folder([suffixed, hashed], video_type=None)

assert {p.name for p in result} == {"video.mp4", "abcd1234"}


def test_accepts_path_objects_and_strings(tmp_path):
suffixed = _touch(tmp_path / "video.mp4")
hashed = _touch(tmp_path / "abcd1234")

result = list_videos_in_folder([str(suffixed), hashed], video_type=None)

assert {p.name for p in result} == {"video.mp4", "abcd1234"}


def test_accepts_single_path_argument(tmp_path):
"""A single path (not wrapped in a list) is also valid input."""
hashed = _touch(tmp_path / "abcd1234")

result = list_videos_in_folder(hashed, video_type=None)

assert [p.name for p in result] == ["abcd1234"]


def test_explicit_video_type_filters_listed_files(tmp_path):
"""When ``video_type`` is set, it filters explicitly-supplied files too."""
mp4 = _touch(tmp_path / "video.mp4")
avi = _touch(tmp_path / "video.avi")

result = list_videos_in_folder([mp4, avi], video_type="mp4")

assert [p.name for p in result] == ["video.mp4"]


def test_explicit_video_type_accepts_leading_dot(tmp_path):
mp4 = _touch(tmp_path / "video.mp4")
avi = _touch(tmp_path / "video.avi")

result = list_videos_in_folder([mp4, avi], video_type=".mp4")

assert [p.name for p in result] == ["video.mp4"]


def test_directory_enumeration_filters_by_supported_videos(tmp_path):
"""Directory scans must continue to discriminate videos from non-videos."""
mp4 = _touch(tmp_path / "video.mp4")
_touch(tmp_path / "notes.txt")
_touch(tmp_path / "results.h5")
_touch(tmp_path / "abcd1234") # suffix-less file in a directory: not a video

result = list_videos_in_folder(tmp_path, video_type=None)

assert [p.name for p in result] == [mp4.name]


def test_directory_enumeration_skips_dlc_artifacts(tmp_path):
"""``*_labeled.*`` and ``*_full.*`` are DLC outputs, not inputs."""
mp4 = _touch(tmp_path / "video.mp4")
_touch(tmp_path / "video_labeled.mp4")
_touch(tmp_path / "video_full.mp4")

result = list_videos_in_folder(tmp_path, video_type=None)

assert [p.name for p in result] == [mp4.name]


def test_mixed_files_and_directories(tmp_path):
"""The function handles a mix of explicit files and directories."""
folder = tmp_path / "folder"
in_folder = _touch(folder / "from_dir.mp4")
_touch(folder / "ignored.txt")

explicit_mp4 = _touch(tmp_path / "explicit.mp4")
explicit_hashed = _touch(tmp_path / "abcd1234")

result = list_videos_in_folder(
[folder, explicit_mp4, explicit_hashed],
video_type=None,
)

assert {p.name for p in result} == {
in_folder.name,
explicit_mp4.name,
explicit_hashed.name,
}


def test_duplicates_are_removed(tmp_path):
mp4 = _touch(tmp_path / "video.mp4")

result = list_videos_in_folder([mp4, mp4, str(mp4)], video_type=None)

assert len(result) == 1
assert result[0].name == "video.mp4"


def test_missing_path_raises(tmp_path):
with pytest.raises(FileNotFoundError):
list_videos_in_folder([tmp_path / "does_not_exist.mp4"], video_type=None)


@pytest.mark.parametrize("ext", SUPPORTED_VIDEOS)
def test_each_supported_extension_picked_up_in_directory(tmp_path, ext):
expected = _touch(tmp_path / f"clip.{ext}")

result = list_videos_in_folder(tmp_path, video_type=None)

assert [p.name for p in result] == [expected.name]


def test_sorted_by_default_when_not_shuffled(tmp_path):
a = _touch(tmp_path / "a.mp4")
b = _touch(tmp_path / "b.mp4")
c = _touch(tmp_path / "c.mp4")

# The resolution order in the function is dict-insertion-stable; given a
# sorted input list we expect a sorted output list.
result = list_videos_in_folder([c, a, b], video_type=None, shuffle=False)

assert [p.name for p in result] == ["c.mp4", "a.mp4", "b.mp4"]
Loading