mirror of
https://github.com/beetbox/beets.git
synced 2026-01-27 10:33:33 +01:00
plugins: Python 3.10 compatibility
In766c8b190bfrom [1] a slight hack was introduced that allowed to add new arguments to plugin events without breaking legacy plugins that did not feature those arguments in the signature of their handler functions. When improving logging management for plugins in327b62b610from [2] this hack was removed, to be restored with7f34c101d7from [3] Now in addition to inspecting the function signature, an assumption is made about the string message of the TypeError that occurs for legacy handler functions (namely, that it start with func.__name__). In Python 3.10, the TypeError uses func.__qualname__ [4], however, due to the patch [5]. Thus, checking whether the TypeError is due to an outdated function signature or something internal to the handler fais. As a fix, instead of using __name__ or __qualname__ depending on Python version, let's just revert to the old hack from [1], I'm not seeing a significant advantage in [3]. The latter might be a bit faster since it doesn't construct a new dict for each call, but only for legacy calls in the excption handler. I doubt that really matters, and if it does, we should try to think of a better fix than inspecting error messages with no guarantees about their content in such a central place in the code. [1] https://github.com/beetbox/beets/pull/652 [2] https://github.com/beetbox/beets/pull/1320 [3] https://github.com/beetbox/beets/pull/1359 [4] https://docs.python.org/3.10/glossary.html#term-qualified-name [5] https://bugs.python.org/issue40679
This commit is contained in:
parent
fdd1deed22
commit
64dc3ec2a2
1 changed files with 13 additions and 12 deletions
|
|
@ -130,29 +130,30 @@ class BeetsPlugin(object):
|
|||
be sent for backwards-compatibility.
|
||||
"""
|
||||
if six.PY2:
|
||||
func_args = inspect.getargspec(func).args
|
||||
argspec = inspect.getargspec(func)
|
||||
func_args = argspec.args
|
||||
has_varkw = argspec.keywords is not None
|
||||
else:
|
||||
func_args = inspect.getfullargspec(func).args
|
||||
argspec = inspect.getfullargspec(func)
|
||||
func_args = argspec.args
|
||||
has_varkw = argspec.varkw is not None
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
assert self._log.level == logging.NOTSET
|
||||
|
||||
verbosity = beets.config['verbose'].get(int)
|
||||
log_level = max(logging.DEBUG, base_log_level - 10 * verbosity)
|
||||
self._log.setLevel(log_level)
|
||||
if not has_varkw:
|
||||
kwargs = dict((k, v) for k, v in kwargs.items()
|
||||
if k in func_args)
|
||||
|
||||
try:
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except TypeError as exc:
|
||||
if exc.args[0].startswith(func.__name__):
|
||||
# caused by 'func' and not stuff internal to 'func'
|
||||
kwargs = dict((arg, val) for arg, val in kwargs.items()
|
||||
if arg in func_args)
|
||||
return func(*args, **kwargs)
|
||||
else:
|
||||
raise
|
||||
return func(*args, **kwargs)
|
||||
finally:
|
||||
self._log.setLevel(logging.NOTSET)
|
||||
|
||||
return wrapper
|
||||
|
||||
def queries(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue