From 4782e96599e39efebd1a592a1df5acecc9c11c55 Mon Sep 17 00:00:00 2001 From: Sebastian Mohr <39738318+semohr@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:28:18 +0200 Subject: [PATCH] Move `vfs.py` to `beetsplug._utils` package to avoid polluting core namespace (#6017) This PR moves the `vfs.py` module, which is only used by plugins, to avoid polluting the main beets namespace. Also exposes the `vfs` and `art` module from beets with a deprecation warning. --- .git-blame-ignore-revs | 2 +- beets/__init__.py | 15 +++++++++++++++ beetsplug/_utils/__init__.py | 3 +++ {beets => beetsplug/_utils}/vfs.py | 18 +++++++++++++----- beetsplug/bench.py | 3 ++- beetsplug/bpd/__init__.py | 3 ++- docs/changelog.rst | 3 +++ test/{ => plugins/utils}/test_vfs.py | 2 +- 8 files changed, 40 insertions(+), 9 deletions(-) rename {beets => beetsplug/_utils}/vfs.py (82%) rename test/{ => plugins/utils}/test_vfs.py (97%) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 2ee64a97d..14b50859f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -72,4 +72,4 @@ d93ddf8dd43e4f9ed072a03829e287c78d2570a2 # Moved plugin docs Further Reading chapter 33f1a5d0bef8ca08be79ee7a0d02a018d502680d # Moved art.py utility module from beets into beetsplug -28aee0fde463f1e18dfdba1994e2bdb80833722f \ No newline at end of file +28aee0fde463f1e18dfdba1994e2bdb80833722f diff --git a/beets/__init__.py b/beets/__init__.py index 10b0f58b0..65094330b 100644 --- a/beets/__init__.py +++ b/beets/__init__.py @@ -17,10 +17,25 @@ from sys import stderr import confuse +from .util import deprecate_imports + __version__ = "2.4.0" __author__ = "Adrian Sampson " +def __getattr__(name: str): + """Handle deprecated imports.""" + return deprecate_imports( + old_module=__name__, + new_module_by_name={ + "art": "beetsplug._utils", + "vfs": "beetsplug._utils", + }, + name=name, + version="3.0.0", + ) + + class IncludeLazyConfig(confuse.LazyConfig): """A version of Confuse's LazyConfig that also merges in data from YAML files specified in an `include` setting. diff --git a/beetsplug/_utils/__init__.py b/beetsplug/_utils/__init__.py index e69de29bb..7453f88bf 100644 --- a/beetsplug/_utils/__init__.py +++ b/beetsplug/_utils/__init__.py @@ -0,0 +1,3 @@ +from . import art, vfs + +__all__ = ["art", "vfs"] diff --git a/beets/vfs.py b/beetsplug/_utils/vfs.py similarity index 82% rename from beets/vfs.py rename to beetsplug/_utils/vfs.py index 4fd133f5a..6294b644c 100644 --- a/beets/vfs.py +++ b/beetsplug/_utils/vfs.py @@ -16,17 +16,25 @@ libraries. """ -from typing import Any, NamedTuple +from __future__ import annotations + +from typing import TYPE_CHECKING, NamedTuple from beets import util +if TYPE_CHECKING: + from beets.library import Library + class Node(NamedTuple): - files: dict[str, Any] - dirs: dict[str, Any] + files: dict[str, int] + # Maps filenames to Item ids. + + dirs: dict[str, Node] + # Maps directory names to child nodes. -def _insert(node, path, itemid): +def _insert(node: Node, path: list[str], itemid: int): """Insert an item into a virtual filesystem node.""" if len(path) == 1: # Last component. Insert file. @@ -40,7 +48,7 @@ def _insert(node, path, itemid): _insert(node.dirs[dirname], rest, itemid) -def libtree(lib): +def libtree(lib: Library) -> Node: """Generates a filesystem-like directory tree for the files contained in `lib`. Filesystem nodes are (files, dirs) named tuples in which both components are dictionaries. The first diff --git a/beetsplug/bench.py b/beetsplug/bench.py index cf72527e8..d77f1f92a 100644 --- a/beetsplug/bench.py +++ b/beetsplug/bench.py @@ -17,10 +17,11 @@ import cProfile import timeit -from beets import importer, library, plugins, ui, vfs +from beets import importer, library, plugins, ui from beets.autotag import match from beets.plugins import BeetsPlugin from beets.util.functemplate import Template +from beetsplug._utils import vfs def aunique_benchmark(lib, prof): diff --git a/beetsplug/bpd/__init__.py b/beetsplug/bpd/__init__.py index aa7013150..1a4f505dd 100644 --- a/beetsplug/bpd/__init__.py +++ b/beetsplug/bpd/__init__.py @@ -30,10 +30,11 @@ from typing import TYPE_CHECKING import beets import beets.ui -from beets import dbcore, logging, vfs +from beets import dbcore, logging from beets.library import Item from beets.plugins import BeetsPlugin from beets.util import as_string, bluelet +from beetsplug._utils import vfs if TYPE_CHECKING: from beets.dbcore.query import Query diff --git a/docs/changelog.rst b/docs/changelog.rst index 38037955e..b22bcd44b 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -48,6 +48,9 @@ Other changes: - Moved ``art.py`` utility module from ``beets`` into ``beetsplug`` namespace as it is not used in the core beets codebase. It can now be found in ``beetsplug._utils``. +- Moved ``vfs.py`` utility module from ``beets`` into ``beetsplug`` namespace as + it is not used in the core beets codebase. It can now be found in + ``beetsplug._utils``. - :class:`beets.metadata_plugin.MetadataSourcePlugin`: Remove discogs specific disambiguation stripping. diff --git a/test/test_vfs.py b/test/plugins/utils/test_vfs.py similarity index 97% rename from test/test_vfs.py rename to test/plugins/utils/test_vfs.py index 7f75fbd83..9505075f9 100644 --- a/test/test_vfs.py +++ b/test/plugins/utils/test_vfs.py @@ -14,9 +14,9 @@ """Tests for the virtual filesystem builder..""" -from beets import vfs from beets.test import _common from beets.test.helper import BeetsTestCase +from beetsplug._utils import vfs class VFSTest(BeetsTestCase):