diff --git a/beetsplug/inline.py b/beetsplug/inline.py index 4092c46d0a..59139b0954 100644 --- a/beetsplug/inline.py +++ b/beetsplug/inline.py @@ -33,11 +33,13 @@ def __init__(self, code, exc): ) -def _compile_func(body): +def _compile_func(body, args=""): """Given Python code for a function body, return a compiled callable that invokes that code. """ - body = "def {}():\n {}".format(FUNC_NAME, body.replace("\n", "\n ")) + body = "def {}({}):\n {}".format( + FUNC_NAME, args, body.replace("\n", "\n ") + ) code = compile(body, "inline", "exec") env = {} eval(code, env) @@ -84,7 +86,9 @@ def compile_inline(self, python_code, album): except SyntaxError: # Fall back to a function body. try: - func = _compile_func(python_code) + func = _compile_func( + python_code, args="album" if album else "item" + ) except SyntaxError: self._log.error( "syntax error in inline field definition:\n" "{0}", @@ -106,6 +110,7 @@ def _dict_for(obj): # For expressions, just evaluate and return the result. def _expr_func(obj): values = _dict_for(obj) + values["album" if album else "item"] = obj try: return eval(code, values) except Exception as exc: @@ -119,7 +124,7 @@ def _func_func(obj): old_globals = dict(func.__globals__) func.__globals__.update(_dict_for(obj)) try: - return func() + return func(obj) except Exception as exc: raise InlineError(python_code, exc) finally: diff --git a/docs/plugins/inline.rst b/docs/plugins/inline.rst index 4dfca261d4..2cf18f0621 100644 --- a/docs/plugins/inline.rst +++ b/docs/plugins/inline.rst @@ -13,7 +13,10 @@ new template field; the key is the name of the field (you'll use the name to refer to the field in your templates) and the value is a Python expression or function body. The Python code has all of a track's fields in scope, so you can refer to any normal attributes (such as ``artist`` or ``title``) as Python -variables. +variables. The Python code also has direct access to the item object as ``item`` +for item fields, and as ``album`` for album fields. This allows use of computed +fields and plugin fields, for example ``album.albumtotal``, or ``album.missing`` +if the ``missing`` plugin is enabled. Here are a couple of examples of expressions::