inline: Fix a ridiculously subtle flexattr bug

As detailed here:
https://github.com/beetbox/beets/issues/2406#issuecomment-274423601

In a *function-style* definition, we didn't properly *un-define* the
values for a given item after each function invocation. So when a field
wasn't defined, it would get the value for the previously-formatted
object instead. It now properly throws a NameError.
This commit is contained in:
Adrian Sampson 2019-06-01 12:28:47 -04:00
parent cd66c5d752
commit 81b1faa053
2 changed files with 13 additions and 0 deletions

View file

@ -117,9 +117,13 @@ class InlinePlugin(BeetsPlugin):
# For function bodies, invoke the function with values as global
# variables.
def _func_func(obj):
old_globals = dict(func.__globals__)
func.__globals__.update(_dict_for(obj))
try:
return func()
except Exception as exc:
raise InlineError(python_code, exc)
finally:
func.__globals__.clear()
func.__globals__.update(old_globals)
return _func_func

View file

@ -12,6 +12,15 @@ New features:
Thanks to :user:`dosoe`.
:bug:`2580` :bug:`3272`
Fixes:
* :doc:`/plugins/inline`: In function-style field definitions that refer to
flexible attributes, values could stick around from one function invocation
to the next. This meant that, when displaying a list of objects, later
objects could seem to reuse values from earlier objects when they were
missing a value for a given field. These values are now properly undefined.
:bug:`2406`
For plugin developers:
* `MediaFile`_ has been split into a standalone project. Where you used to do