-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #2826 #3092
Fix #2826 #3092
Conversation
Test for major Python version and use inspect.getargspec() or inspect.getfullargspec() respectively to silence deprecation warnings in Python 3
Having another look at this I don't like the fact that To make the tuple identical in both cases I propose two solutions. The simple one: diff --git a/beets/plugins.py b/beets/plugins.py
index 69784d26..9a984cf5 100644
--- a/beets/plugins.py
+++ b/beets/plugins.py
@@ -130,7 +130,7 @@ class BeetsPlugin(object):
if six.PY2:
argspec = inspect.getargspec(func)
else:
- argspec = inspect.getfullargspec(func)
+ argspec = inspect.ArgSpec(*inspect.getfullargspec(func)[:4])
@wraps(func)
def wrapper(*args, **kwargs): What bugs me about this is that if The second solution is to replicate diff --git a/beets/plugins.py b/beets/plugins.py
index 69784d26..12d9dde5 100644
--- a/beets/plugins.py
+++ b/beets/plugins.py
@@ -21,6 +21,7 @@ import inspect
import traceback
import re
from collections import defaultdict
+from collections import namedtuple
from functools import wraps
@@ -130,7 +131,9 @@ class BeetsPlugin(object):
if six.PY2:
argspec = inspect.getargspec(func)
else:
- argspec = inspect.getfullargspec(func)
+ ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults',
+ defaults=([], None, None, None))
+ argspec = ArgSpec(*inspect.getfullargspec(func)[:4])
@wraps(func)
def wrapper(*args, **kwargs): What are your thoughts about my concerns? Leave it like it is, maybe just add a comment with a warning, or commit the second proposed solution which looks more robust, if a bit clunkier, to me? |
A third variant, stolen more or less from Django's code base, is to use from __future__ import absolute_import
import inspect
from collections import namedtuple
from six import PY2
def getargspec(func):
if PY2:
return inspect.getargspec(func)
ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
sig = inspect.signature(func)
args = [
p.name for p in sig.parameters.values()
if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
]
varargs = [
p.name for p in sig.parameters.values()
if p.kind == inspect.Parameter.VAR_POSITIONAL
]
varargs = varargs[0] if varargs else None
varkw = [
p.name for p in sig.parameters.values()
if p.kind == inspect.Parameter.VAR_KEYWORD
]
varkw = varkw[0] if varkw else None
defaults = tuple(p.default for p in sig.parameters.values()
if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
and p.default is not p.empty) or None
return ArgSpec(args, varargs, varkw, defaults) And import it elsewhere in place of diff --git a/beets/plugins.py b/beets/plugins.py
index 6dec7ef2..56bb07cb 100644
--- a/beets/plugins.py
+++ b/beets/plugins.py
@@ -17,7 +17,6 @@
from __future__ import division, absolute_import, print_function
-import inspect
import traceback
import re
from collections import defaultdict
@@ -27,6 +26,7 @@ from functools import wraps
import beets
from beets import logging
from beets import mediafile
+from beets.util import inspect
import six
PLUGIN_NAMESPACE = 'beetsplug' |
The wrapper option looks like the best path forwards to me. |
I've tested this PR and it fixes the deprecation warnings issue for me. Shall we merge it? Perhaps with a link back to the comment above documenting the potential gotcha for future devs? |
I am sorry about the delay, almost forgot about this issue actually. I pushed the wrapper option from my last post as suggested. Feel free to do as you please. Cheers. |
This does look like quite a complete solution! The only thing is: when we (hopefully before too long) transition to Python 3 exclusively, I predict that we may not need perfect emulation of |
Thought about the same thing. That's why I isolated the workaround in a separate file which can simply be removed after the transition of the code base to Python 3. I don't see a cleaner solution having in mind backward compatibility. |
Indeed; seems like a great idea for this to get isolated in its own separate file. The thing I was bringing up, however, is that we're currently emulating a Python 2 API on Python 3, not the other way around. So when we make the transition, we won't be able to just remove the file---we'll be able to remove the |
Fantastic; thank you! |
Test for major Python version and use inspect.getargspec() or
inspect.getfullargspec() respectively to silence deprecation warnings in
Python 3 as discussed in #2826