Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-modelscope-hub for 
openSUSE:Factory checked in at 2026-09-10 17:40:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-modelscope-hub (Old)
 and      /work/SRC/openSUSE:Factory/.python-modelscope-hub.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-modelscope-hub"

Thu Sep 10 17:40:52 2026 rev:5 rq:1376808 version:0.4.2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-modelscope-hub/python-modelscope-hub.changes  
    2026-09-04 12:39:20.639337941 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-modelscope-hub.new.1265/python-modelscope-hub.changes
    2026-09-10 17:40:54.495489746 +0200
@@ -1,0 +2,11 @@
+Thu Sep 10 05:44:34 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 0.4.2:
+  * Commit manager supports deletion operations
+  * New delete_files API on HubApi and the legacy compat client
+- Ship the modelscope and ms console scripts again:
+  python-modelscope 1.40.0 moved them to this package (its update
+  also fixed CVE-2026-84202 boo#1278007 in the umbrella SDK), and
+  the 1.40.0 sdist declares no console scripts of its own
+
+-------------------------------------------------------------------

Old:
----
  modelscope_hub-0.4.0.tar.gz

New:
----
  modelscope_hub-0.4.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-modelscope-hub.spec ++++++
--- /var/tmp/diff_new_pack.vcJJfD/_old  2026-09-10 17:40:55.259521646 +0200
+++ /var/tmp/diff_new_pack.vcJJfD/_new  2026-09-10 17:40:55.261521730 +0200
@@ -19,7 +19,7 @@
 %bcond_without libalternatives
 %{?sle15_python_module_pythons}
 Name:           python-modelscope-hub
-Version:        0.4.0
+Version:        0.4.2
 Release:        0
 Summary:        Official Python client for ModelScope Hub
 License:        Apache-2.0
@@ -52,7 +52,8 @@
 %description
 Python SDK and CLI to download, upload and manage models, datasets,
 Studio spaces, skills and MCP servers on ModelScope Hub. Provides a
-HubApi class and the modelscope-hub and ms-hub commands.
+HubApi class and the modelscope, ms, modelscope-hub and ms-hub
+commands.
 
 %prep
 %autosetup -p1 -n modelscope_hub-%{version}
@@ -62,12 +63,14 @@
 
 %install
 %pyproject_install
-# 0.3.0 reclaimed the modelscope/ms scripts from the umbrella SDK, but 
Factory's
-# python-modelscope still ships them and Requires us -> co-installed file
-# conflict. Drop ours until python-modelscope stops installing them.
-rm %{buildroot}%{_bindir}/modelscope %{buildroot}%{_bindir}/ms
+# python-modelscope 1.40.0 dropped modelscope/ms; this package owns all
+# four console scripts (modelscope, ms, modelscope-hub, ms-hub).
+%python_clone -a %{buildroot}%{_bindir}/modelscope
+%python_clone -a %{buildroot}%{_bindir}/ms
 %python_clone -a %{buildroot}%{_bindir}/modelscope-hub
 %python_clone -a %{buildroot}%{_bindir}/ms-hub
+%python_group_libalternatives modelscope
+%python_group_libalternatives ms
 %python_group_libalternatives modelscope-hub
 %python_group_libalternatives ms-hub
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
@@ -80,15 +83,20 @@
 # that module checks the registry->method binding and still runs.
 %pytest -m "not remote" --deselect 
tests/test_openapi_coverage.py::test_every_covered_operation_is_registered 
--deselect 
tests/test_openapi_coverage.py::test_registry_has_no_unknown_operations 
--deselect 
tests/test_openapi_coverage.py::test_registry_does_not_claim_deferred_tags 
--deselect tests/test_openapi_coverage.py::test_every_tag_is_accounted_for 
--deselect tests/test_openapi_coverage.py::test_spec_is_the_expected_document 
--deselect 
tests/test_openapi_coverage.py::test_covered_tags_account_for_every_registered_entry
 %python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} $python -B -c "import 
modelscope_hub"
+%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
%{buildroot}%{_bindir}/modelscope-%{$python_bin_suffix} --help
 %python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} 
%{buildroot}%{_bindir}/ms-hub-%{$python_bin_suffix} --help
 
 %pre
+%python_libalternatives_reset_alternative modelscope
+%python_libalternatives_reset_alternative ms
 %python_libalternatives_reset_alternative modelscope-hub
 %python_libalternatives_reset_alternative ms-hub
 
 %files %{python_files}
 %license LICENSE
 %doc README.md
+%python_alternative %{_bindir}/modelscope
+%python_alternative %{_bindir}/ms
 %python_alternative %{_bindir}/modelscope-hub
 %python_alternative %{_bindir}/ms-hub
 %{python_sitelib}/modelscope_hub

++++++ modelscope_hub-0.4.0.tar.gz -> modelscope_hub-0.4.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/modelscope_hub-0.4.0/PKG-INFO 
new/modelscope_hub-0.4.2/PKG-INFO
--- old/modelscope_hub-0.4.0/PKG-INFO   2026-09-02 08:46:29.727967700 +0200
+++ new/modelscope_hub-0.4.2/PKG-INFO   2026-09-10 04:59:09.073332300 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: modelscope-hub
-Version: 0.4.0
+Version: 0.4.2
 Summary: The official Python client to connect with ModelScope Hub.
 License: Apache-2.0
 Keywords: modelscope,hub,sdk,openapi,machine-learning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/modelscope_hub-0.4.0/src/modelscope_hub/_upload.py 
new/modelscope_hub-0.4.2/src/modelscope_hub/_upload.py
--- old/modelscope_hub-0.4.0/src/modelscope_hub/_upload.py      2026-09-02 
08:46:14.456071600 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub/_upload.py      2026-09-10 
04:58:57.682107400 +0200
@@ -636,6 +636,42 @@
         )
 
     # ------------------------------------------------------------------
+    # Public: delete_files
+    # ------------------------------------------------------------------
+    def delete_files(
+        self,
+        repo_id: str,
+        repo_type: str,
+        file_paths: list[str],
+        *,
+        commit_message: str = "Delete files",
+        revision: str = "master",
+    ) -> dict:
+        """Delete repository files through a commit operation.
+
+        The direct repository DELETE endpoints reject API-token authentication.
+        Commit ``delete`` actions use the same supported write path as uploads
+        and are applied atomically in a single commit.
+        """
+        paths = list(dict.fromkeys(path for path in file_paths if path))
+        if not paths:
+            raise InvalidParameter(
+                "file_paths must contain at least one non-empty path.")
+
+        self._commit_with_retry(
+            repo_id=repo_id,
+            repo_type=repo_type,
+            operations=self._build_delete_operations(paths),
+            commit_message=commit_message,
+            revision=revision,
+        )
+        return {
+            "deleted_files": paths,
+            "failed_files": [],
+            "total_files": len(paths),
+        }
+
+    # ------------------------------------------------------------------
     # Public: upload_folder
     # ------------------------------------------------------------------
     def upload_folder(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/modelscope_hub-0.4.0/src/modelscope_hub/api.py 
new/modelscope_hub-0.4.2/src/modelscope_hub/api.py
--- old/modelscope_hub-0.4.0/src/modelscope_hub/api.py  2026-09-02 
08:46:14.457071500 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub/api.py  2026-09-10 
04:58:57.683107600 +0200
@@ -23,6 +23,7 @@
 
 from __future__ import annotations
 
+import fnmatch
 import time
 from collections.abc import Iterable, Mapping
 from pathlib import Path
@@ -46,7 +47,6 @@
     AuthenticationError,
     HubError,
     InvalidParameter,
-    NetworkError,
     NotExistError,
     NotSupportedError,
     PermissionDeniedError,
@@ -1670,17 +1670,18 @@
         self,
         repo_id: str,
         repo_type: RepoTypeLike,
-        file_paths: Iterable[str],
+        file_paths: Iterable[str] | str | None = None,
         *,
+        delete_patterns: Iterable[str] | str | None = None,
         commit_message: str | None = None,
         revision: str | None = None,
     ) -> dict:
-        """Delete one or more files from a repository.
+        """Delete repository files selected by paths or glob patterns.
 
-        .. note::
-           File deletion is restricted by the server to cookie-based session
-           auth (interactive login). API tokens (``ms-...``) may receive a 401
-           "token no longer supports deletion operations" error.
+        The direct repository DELETE endpoints reject API-token authentication.
+        This method resolves optional glob patterns against the remote file 
list,
+        then sends commit ``delete`` actions through the same supported write
+        path as :meth:`upload_file` and :meth:`upload_folder`.
 
         Parameters
         ----------
@@ -1688,53 +1689,80 @@
             Canonical ``owner/name`` identifier.
         repo_type : str or RepoType
             Repository type.
-        file_paths : iterable of str
-            Paths of files to remove. Empty entries are ignored.
+        file_paths : iterable of str or str, optional
+            Explicit repository-relative paths to remove.
+        delete_patterns : iterable of str or str, optional
+            Glob patterns matched against remote file paths. For example,
+            ``"*.json"`` matches JSON files at any repository depth.
         commit_message : str, optional
-            Unused (kept for API compatibility).
+            Message for the delete commit. Defaults to ``"Delete files"``.
         revision : str, optional
             Branch to delete from. Defaults to ``"master"``.
 
         Returns
         -------
         dict
-            Summary with ``deleted_files`` and ``failed_files`` lists.
-
-        Raises
-        ------
-        InvalidParameter
-            When ``file_paths`` resolves to an empty list.
-
-        Examples
-        --------
-        >>> api.delete_files(
-        ...     "alice/llama-7b",
-        ...     "model",
-        ...     ["old_weights.bin", "deprecated/config.json"],
-        ... )
+            Summary with ``deleted_files``, ``failed_files``, and 
``total_files``.
+            A pattern with no remote matches returns an empty successful 
summary.
         """
         rt = self._normalize_repo_type(repo_type)
-        paths = [p for p in file_paths if p]
-        if not paths:
-            raise InvalidParameter("file_paths must contain at least one 
non-empty path.")
+        paths = self._normalize_delete_values(file_paths, "file_paths")
+        patterns = self._normalize_delete_values(
+            delete_patterns, "delete_patterns")
+        if not paths and not patterns:
+            raise InvalidParameter(
+                "Provide at least one file path or delete pattern.")
 
-        deleted, failed = [], []
-        for p in paths:
-            try:
-                self.legacy.delete_file(
-                    repo_id=repo_id,
-                    repo_type=str(rt),
-                    file_path=p,
-                    revision=revision or "master",
+        resolved_revision = revision or "master"
+        if patterns:
+            remote_paths = [
+                file.path
+                for file in self.list_repo_files(
+                    repo_id,
+                    rt,
+                    revision=resolved_revision,
+                    recursive=True,
                 )
-                deleted.append(p)
-            except (AuthenticationError, NetworkError):
-                failed.append(p)
-                raise
-            except Exception:
-                failed.append(p)
+                if file.path and file.type != "tree"
+            ]
+            paths.extend(
+                path for path in remote_paths
+                if any(fnmatch.fnmatchcase(path, pattern)
+                       for pattern in patterns))
+
+        paths = list(dict.fromkeys(paths))
+        if not paths:
+            return {
+                "deleted_files": [],
+                "failed_files": [],
+                "total_files": 0,
+            }
 
-        return {"deleted_files": deleted, "failed_files": failed, 
"total_files": len(paths)}
+        return self.uploader.delete_files(
+            repo_id=repo_id,
+            repo_type=str(rt),
+            file_paths=paths,
+            commit_message=commit_message or "Delete files",
+            revision=resolved_revision,
+        )
+
+    @staticmethod
+    def _normalize_delete_values(
+        values: Iterable[str] | str | None,
+        parameter_name: str,
+    ) -> list[str]:
+        """Normalize a delete path or glob-pattern argument."""
+        if values is None:
+            return []
+        raw_values = [values] if isinstance(values, str) else list(values)
+        normalized: list[str] = []
+        for value in raw_values:
+            if not isinstance(value, str):
+                raise InvalidParameter(
+                    f"{parameter_name} must contain only strings.")
+            if value:
+                normalized.append(value)
+        return normalized
 
     # ==================================================================
     # Versioning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/modelscope_hub-0.4.0/src/modelscope_hub/compat/hub_api.py 
new/modelscope_hub-0.4.2/src/modelscope_hub/compat/hub_api.py
--- old/modelscope_hub-0.4.0/src/modelscope_hub/compat/hub_api.py       
2026-09-02 08:46:14.458071500 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub/compat/hub_api.py       
2026-09-10 04:58:57.684107500 +0200
@@ -195,6 +195,36 @@
             result = [f for f in result if f["Path"] == prefix or 
str(f["Path"]).startswith(prefix + "/")]
         return result
 
+    def delete_files(
+        self,
+        repo_id: str,
+        repo_type: str | RepoType = RepoType.MODEL,
+        delete_patterns: str | list[str] | None = None,
+        *,
+        file_paths: str | list[str] | None = None,
+        revision: str | None = DEFAULT_DATASET_REVISION,
+        commit_message: str | None = None,
+        endpoint: str | None = None,
+        token: str | None = None,
+    ) -> dict:
+        """Delete files selected by legacy glob patterns or explicit paths.
+
+        ``delete_patterns`` preserves the historical ``modelscope.hub.api``
+        contract. Patterns are resolved against the remote repository by the
+        modelscope-hub facade before it commits atomic delete actions.
+        """
+        api = self._api
+        if token or endpoint:
+            api = HubApi(endpoint=endpoint or self._endpoint, token=token)
+        return api.delete_files(
+            repo_id,
+            repo_type,
+            file_paths=file_paths,
+            delete_patterns=delete_patterns,
+            commit_message=commit_message,
+            revision=revision,
+        )
+
     def create_repo(
         self,
         repo_id: str,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/modelscope_hub-0.4.0/src/modelscope_hub/version.py 
new/modelscope_hub-0.4.2/src/modelscope_hub/version.py
--- old/modelscope_hub-0.4.0/src/modelscope_hub/version.py      2026-09-02 
08:46:14.459071400 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub/version.py      2026-09-10 
04:58:57.685107700 +0200
@@ -1,3 +1,3 @@
 """Version information for modelscope_hub."""
 
-__version__ = "0.4.0"
+__version__ = "0.4.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/modelscope_hub-0.4.0/src/modelscope_hub.egg-info/PKG-INFO 
new/modelscope_hub-0.4.2/src/modelscope_hub.egg-info/PKG-INFO
--- old/modelscope_hub-0.4.0/src/modelscope_hub.egg-info/PKG-INFO       
2026-09-02 08:46:29.696967800 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub.egg-info/PKG-INFO       
2026-09-10 04:59:09.045331700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: modelscope-hub
-Version: 0.4.0
+Version: 0.4.2
 Summary: The official Python client to connect with ModelScope Hub.
 License: Apache-2.0
 Keywords: modelscope,hub,sdk,openapi,machine-learning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/modelscope_hub-0.4.0/src/modelscope_hub.egg-info/SOURCES.txt 
new/modelscope_hub-0.4.2/src/modelscope_hub.egg-info/SOURCES.txt
--- old/modelscope_hub-0.4.0/src/modelscope_hub.egg-info/SOURCES.txt    
2026-09-02 08:46:29.706967800 +0200
+++ new/modelscope_hub-0.4.2/src/modelscope_hub.egg-info/SOURCES.txt    
2026-09-10 04:59:09.054332000 +0200
@@ -55,6 +55,7 @@
 tests/test_agent_idp.py
 tests/test_agent_idp_keys.py
 tests/test_cache_verification.py
+tests/test_compat_delete_files.py
 tests/test_compat_get_model_files.py
 tests/test_compat_snapshot_download.py
 tests/test_compat_studio.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/modelscope_hub-0.4.0/tests/test_compat_delete_files.py 
new/modelscope_hub-0.4.2/tests/test_compat_delete_files.py
--- old/modelscope_hub-0.4.0/tests/test_compat_delete_files.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/modelscope_hub-0.4.2/tests/test_compat_delete_files.py  2026-09-10 
04:58:57.689107700 +0200
@@ -0,0 +1,54 @@
+from __future__ import annotations
+
+from unittest import mock
+
+from modelscope_hub.compat import LegacyHubApi
+from modelscope_hub.constants import RepoType
+
+
+def test_legacy_hub_api_preserves_delete_patterns_contract() -> None:
+    api = LegacyHubApi(endpoint="https://modelscope.cn";, token="test-token")
+    expected = {
+        "deleted_files": ["config.json"],
+        "failed_files": [],
+        "total_files": 1,
+    }
+
+    with mock.patch.object(api._api, "delete_files", return_value=expected) as 
delete_files:
+        result = api.delete_files(
+            repo_id="owner/repo",
+            repo_type=RepoType.MODEL,
+            delete_patterns="*.json",
+            revision="main",
+            commit_message="Delete JSON files",
+        )
+
+    delete_files.assert_called_once_with(
+        "owner/repo",
+        RepoType.MODEL,
+        file_paths=None,
+        delete_patterns="*.json",
+        commit_message="Delete JSON files",
+        revision="main",
+    )
+    assert result == expected
+
+
+def test_legacy_hub_api_delete_files_supports_explicit_paths() -> None:
+    api = LegacyHubApi(token="test-token")
+
+    with mock.patch.object(api._api, "delete_files", return_value={}) as 
delete_files:
+        api.delete_files(
+            "owner/repo",
+            repo_type="dataset",
+            file_paths=["data/old.json"],
+        )
+
+    delete_files.assert_called_once_with(
+        "owner/repo",
+        "dataset",
+        file_paths=["data/old.json"],
+        delete_patterns=None,
+        commit_message=None,
+        revision="master",
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/modelscope_hub-0.4.0/tests/test_upload_lfs_gate.py 
new/modelscope_hub-0.4.2/tests/test_upload_lfs_gate.py
--- old/modelscope_hub-0.4.0/tests/test_upload_lfs_gate.py      2026-09-02 
08:46:14.463071000 +0200
+++ new/modelscope_hub-0.4.2/tests/test_upload_lfs_gate.py      2026-09-10 
04:58:57.690107600 +0200
@@ -4,11 +4,15 @@
 import hashlib
 import json
 from pathlib import Path
+from types import SimpleNamespace
 from unittest.mock import MagicMock
 
+import pytest
+
 import modelscope_hub._upload as upload_module
+from modelscope_hub import HubApi
 from modelscope_hub._upload import UploadManager
-from modelscope_hub.errors import NetworkError
+from modelscope_hub.errors import InvalidParameter, NetworkError
 
 
 def _make_manager() -> tuple[UploadManager, MagicMock]:
@@ -27,6 +31,142 @@
     return UploadManager(client, MagicMock()), client
 
 
[email protected]("repo_type", ["model", "dataset"])
+def test_delete_files_commits_atomic_delete_actions(repo_type: str) -> None:
+    manager, client = _make_manager()
+
+    result = manager.delete_files(
+        repo_id="owner/repo",
+        repo_type=repo_type,
+        file_paths=["old.bin", "nested/deprecated.json", "old.bin"],
+        commit_message="Remove obsolete files",
+        revision="main",
+    )
+
+    client.create_commit.assert_called_once_with(
+        repo_id="owner/repo",
+        repo_type=repo_type,
+        operations=[
+            {
+                "action": "delete",
+                "path": "old.bin",
+                "type": "normal",
+                "size": 0,
+                "sha256": "",
+                "content": "",
+                "encoding": "",
+            },
+            {
+                "action": "delete",
+                "path": "nested/deprecated.json",
+                "type": "normal",
+                "size": 0,
+                "sha256": "",
+                "content": "",
+                "encoding": "",
+            },
+        ],
+        commit_message="Remove obsolete files",
+        revision="main",
+    )
+    assert result == {
+        "deleted_files": ["old.bin", "nested/deprecated.json"],
+        "failed_files": [],
+        "total_files": 2,
+    }
+
+
+def test_delete_files_rejects_empty_paths() -> None:
+    manager, client = _make_manager()
+
+    with pytest.raises(InvalidParameter, match="at least one"):
+        manager.delete_files(
+            repo_id="owner/repo", repo_type="model", file_paths=["", ""])
+
+    client.create_commit.assert_not_called()
+
+
[email protected]("repo_type", ["model", "dataset"])
[email protected]("file_paths", [["", "old.bin"], "old.bin"])
+def test_hub_api_delete_files_delegates_to_upload_manager(
+    repo_type: str, file_paths: list[str] | str
+) -> None:
+    api = HubApi(token="test-token")
+    api._uploader = MagicMock()
+    api._uploader.delete_files.return_value = {"deleted_files": ["old.bin"]}
+
+    result = api.delete_files(
+        "owner/repo",
+        repo_type,
+        file_paths,
+        commit_message="Remove obsolete files",
+        revision="main",
+    )
+
+    api._uploader.delete_files.assert_called_once_with(
+        repo_id="owner/repo",
+        repo_type=repo_type,
+        file_paths=["old.bin"],
+        commit_message="Remove obsolete files",
+        revision="main",
+    )
+    assert result == {"deleted_files": ["old.bin"]}
+
+
[email protected]("repo_type", ["model", "dataset"])
+def test_hub_api_delete_patterns_resolve_remote_paths(repo_type: str) -> None:
+    api = HubApi(token="test-token")
+    api._uploader = MagicMock()
+    api._uploader.delete_files.return_value = {
+        "deleted_files": ["config.json", "nested/metadata.json"],
+        "failed_files": [],
+        "total_files": 2,
+    }
+    api.list_repo_files = MagicMock(
+        return_value=[
+            SimpleNamespace(path="config.json", type="blob"),
+            SimpleNamespace(path="nested/metadata.json", type="blob"),
+            SimpleNamespace(path="weights.bin", type="blob"),
+            SimpleNamespace(path="nested", type="tree"),
+        ])
+
+    result = api.delete_files(
+        "owner/repo",
+        repo_type,
+        delete_patterns="*.json",
+        commit_message="Remove JSON files",
+        revision="main",
+    )
+
+    api.list_repo_files.assert_called_once_with(
+        "owner/repo", repo_type, revision="main", recursive=True)
+    api._uploader.delete_files.assert_called_once_with(
+        repo_id="owner/repo",
+        repo_type=repo_type,
+        file_paths=["config.json", "nested/metadata.json"],
+        commit_message="Remove JSON files",
+        revision="main",
+    )
+    assert result["total_files"] == 2
+
+
+def test_hub_api_delete_patterns_with_no_match_is_noop() -> None:
+    api = HubApi(token="test-token")
+    api._uploader = MagicMock()
+    api.list_repo_files = MagicMock(
+        return_value=[SimpleNamespace(path="weights.bin", type="blob")])
+
+    result = api.delete_files(
+        "owner/repo", "model", delete_patterns="*.json")
+
+    api._uploader.delete_files.assert_not_called()
+    assert result == {
+        "deleted_files": [],
+        "failed_files": [],
+        "total_files": 0,
+    }
+
+
 def test_upload_file_normal_commits_inline_without_blob_api() -> None:
     manager, client = _make_manager()
 

Reply via email to