Fix recursion in inline plugin when item_fields shadow DB fields (#6115)

This commit is contained in:
Gabriel Push 2025-11-20 15:57:22 -05:00
parent beda6fc71b
commit aced802c56
2 changed files with 40 additions and 4 deletions

View file

@ -61,18 +61,18 @@ class InlinePlugin(BeetsPlugin):
config["item_fields"].items(), config["pathfields"].items()
):
self._log.debug("adding item field {}", key)
func = self.compile_inline(view.as_str(), False)
func = self.compile_inline(view.as_str(), False, key)
if func is not None:
self.template_fields[key] = func
# Album fields.
for key, view in config["album_fields"].items():
self._log.debug("adding album field {}", key)
func = self.compile_inline(view.as_str(), True)
func = self.compile_inline(view.as_str(), True, key)
if func is not None:
self.album_template_fields[key] = func
def compile_inline(self, python_code, album):
def compile_inline(self, python_code, album, field_name):
"""Given a Python expression or function body, compile it as a path
field function. The returned function takes a single argument, an
Item, and returns a Unicode string. If the expression cannot be
@ -97,7 +97,12 @@ class InlinePlugin(BeetsPlugin):
is_expr = True
def _dict_for(obj):
out = dict(obj)
out = {}
for key in obj.keys(computed=False):
if key == field_name:
continue
out[key] = obj._get(key)
if album:
out["items"] = list(obj.items())
return out

View file

@ -0,0 +1,31 @@
# test/plugins/test_plugins.py
from beets import config, plugins
from beets.test.helper import PluginTestCase
class TestInlineRecursion(PluginTestCase):
def test_no_recursion_when_inline_shadows_fixed_field(self):
config['plugins'] = ['inline']
config['item_fields'] = {
'track_no': (
"f'{disc:02d}-{track:02d}' if disctotal > 1 "
"else f'{track:02d}'"
)
}
plugins._instances.clear()
plugins.load_plugins()
item = self.add_item_fixture(
artist='Artist',
album='Album',
title='Title',
track=1,
disc=1,
disctotal=1,
)
out = item.evaluate_template('$track_no')
assert out == '01'