From 5f55431a28509fd4f4f7b40dc246f3d34fa8549e Mon Sep 17 00:00:00 2001 From: Christoph Reiter <reiter.christoph@gmail.com> Date: Sun, 26 Jun 2022 23:14:28 +0200 Subject: [PATCH] builtin cover: fix handling of invalid glob ranges with Python 3.10.5+ (#4027) Previously Python would raise if an invalid range was given to glob, but with 3.10.5 they fixed it to not match anything. https://github.com/python/cpython/issues/89973 Our tests depended on the previous logic and treating the glob pattern as a literal file name in that case. One could argue that this is wrong since a range that doesn't contain anything should also not match anything, so wrap glob() to make it not match for all Python versions in that case and adjust the tests accordingly. This should fix the Windows CI, which is currently the only job using 3.10.5 --- quodlibet/util/cover/built_in.py | 22 +++++++++++----------- tests/test_util_cover.py | 12 +++--------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/quodlibet/util/cover/built_in.py b/quodlibet/util/cover/built_in.py index f2a8791a2..01474c9b6 100644 --- a/quodlibet/util/cover/built_in.py +++ b/quodlibet/util/cover/built_in.py @@ -100,6 +100,15 @@ class FilesystemCover(CoverSourcePlugin): base = self.song('~dirname') images = [] + def safe_glob(*args, **kwargs): + try: + return glob.glob(*args, **kwargs) + except sre_constants.error: + # https://github.com/python/cpython/issues/89973 + # old glob would fail with invalid ranges, newer one + # handles it correctly. + return [] + if config.getboolean("albumart", "force_filename"): score = 100 for filename in config.get("albumart", "filename").split(","): @@ -107,17 +116,8 @@ class FilesystemCover(CoverSourcePlugin): filename = filename.strip() escaped_path = os.path.join(glob.escape(base), filename) - try: - for path in glob.glob(escaped_path): - images.append((score, path)) - except sre_constants.error: - # Use literal filename if globbing causes errors - path = os.path.join(base, filename) - - # We check this here, so we can search for alternative - # files in case no preferred file was found. - if os.path.isfile(path): - images.append((score, path)) + for path in safe_glob(escaped_path): + images.append((score, path)) # So names and patterns at the start are preferred score -= 1 diff --git a/tests/test_util_cover.py b/tests/test_util_cover.py index db81e4d1f..71a48ad9a 100644 --- a/tests/test_util_cover.py +++ b/tests/test_util_cover.py @@ -105,15 +105,9 @@ class TCoverManager(TestCase): config.set("albumart", "force_filename", str(True)) config.set("albumart", "filename", "[a-2].jpg") - # Should match - f = self.add_file("[a-2].jpg") - assert path_equal( - os.path.abspath(self._find_cover(self.song).name), f) - - # Should not crash - f = self.add_file("test.jpg") - assert not path_equal( - os.path.abspath(self._find_cover(self.song).name), f) + # Invalid glob range, should not match anything + self.add_file("a.jpg") + assert self._find_cover(self.song) is None def test_invalid_glob_path(self): config.set("albumart", "force_filename", str(True)) -- 2.39.2