-
Notifications
You must be signed in to change notification settings - Fork 47
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
support python3 keyword-only arguments for function decorator #96
Comments
Mark Heppner (mheppner) wrote: I'm having the same issue, Python 3.6. Here's a formatted stack trace: ~/Documents/app/env/lib64/python3.6/site-packages/dogpile/cache/region.py in decorator(fn)
1213 if to_str is compat.string_type:
1214 # backwards compatible
-> 1215 key_generator = function_key_generator(namespace, fn)
1216 else:
1217 key_generator = function_key_generator(
~/Documents/app/env/lib64/python3.6/site-packages/dogpile/cache/util.py in function_key_generator(namespace, fn, to_str)
29 namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace)
30
---> 31 args = inspect.getargspec(fn)
32 has_self = args[0] and args[0][0] in ('self', 'cls')
33
/usr/lib64/python3.6/inspect.py in getargspec(func)
1043 getfullargspec(func)
1044 if kwonlyargs or ann:
-> 1045 raise ValueError("Function has keyword-only parameters or annotations"
1046 ", use getfullargspec() API which can support them")
1047 return ArgSpec(args, varargs, varkw, defaults)
ValueError: Function has keyword-only parameters or annotations, use getfullargspec() API which can support them |
Michael Bayer (zzzeek) wrote: Python3 style keyword-only parameters arent' supported as of yet. if someone wants to work on a PR for this feature that is fine. |
Changes by Michael Bayer (zzzeek):
|
Changes by Michael Bayer (zzzeek):
|
Mark Heppner (mheppner) wrote: I'm trying to figure out how to do this... Does this seem acceptable to you? If you ignore 3.2, you can either use |
Mark Heppner (mheppner) wrote: Nevermind, I see you have a value for 3.2. How about using |
Michael Bayer (zzzeek) wrote: using the correct function is not the hard part, it's having those new arguments added to be part of the cache key. there is currently function_key_generator which does not support keyword arguments at all (which is what your stack trace is), and there's also kwarg_function_key_generator which does. But neither know how to recognize keyword-only arguments. that has to be implemented appropriately for both. keyword-only arguments would likely continue to be not implemented by function_key_generator and would be supported by kwarg_function_key_generator. |
Mark Heppner (mheppner) wrote: Ah yes. I didn't see anything in the docs that mention it. I'm not that familiar with this code, so sorry if this is a bit naive, but couldn't a unified key generator be used instead? Something like this would give the same cache key, regardless of how the args or kwargs are invoked (Python 3 only): import inspect
def test(a1, a2, k1='k1', k2='k2', *args, **kwargs):
return True
sig = inspect.signature(test)
# apply user-supplied values
bound = sig.bind('test1', 'test2', 'overridden')
# apply any default values for kwargs
bound.apply_defaults()
# assumes all the values have str() version
cache_key = ' ' .join([key + '=' + str(value) for key, value in bound.arguments.items()])
# 'a1=test1 a2=test2 k1=overridden k2=k2 args=() kwargs={}' Basically, just treat any arg or kwarg as a named value as part of the cache key. Obviously this would increase key sizes, but I think it would only affect memcache's limit of 250 bytes. I haven't tried it yet, but a Python 2 version might be more challenging. Edit there is a backport of |
Michael Bayer (zzzeek) wrote: well it has to work on Python 2 to be "unified", but overall the "no-kwarg" key generator has been there much longer than the kwargs one, so there are two separate versions for stability and backwards compatilibity reasons. |
Mark Heppner (mheppner) wrote: I didn't link it correctly, but here's an initial idea. |
Rudolf Cardinal (RudolfCardinal) wrote: As the error message suggests, this also applies to type-annotated functions, as in
Not critical, obviously, but type-checking is a generally Good Thing. Thank you for dogpile.cache, Mike; this looks excellent (as ever!). all the best, |
Michael Bayer (zzzeek) wrote: I think we're still open to contributors on this one. |
Michael Bayer (zzzeek) wrote: that looks extremely useful thanks! |
Rudolf Cardinal (RudolfCardinal) wrote: Just noticed some comment errors in my code: (a) the docstring for |
Michael Bayer (zzzeek) wrote: it's fine to use |
Rudolf Cardinal (RudolfCardinal) wrote: Also possible to augment this to make the FKG distinguish class instances, so you can cache normal methods of a class in a per-instance way - here's the most general form:
I have test code too if it's of use; essentially you can then do:
... whereas with the default system, the per-instance specificity is lost. |
I haven't worked with type annotations. that looks like a lot of code, if we can get it into a PR here or a gerrit with some tests I can try to get people to help me look at it |
Migrated issue, originally created by Anonymous
getargspec() is deprecated in python 3.0
When running against 3.5, I get the following ValueError...
File "
/.pyenv/versions/env/lib/python3.5/site-packages/dogpile/cache/region.py", line 1037, in decorator/.pyenv/versions/env/lib/python3.5/site-packages/dogpile/cache/util.py", line 73, in function_key_generatorkey_generator = function_key_generator(namespace, fn)
File "
args = inspect.getargspec(fn)
File "~/.pyenv/versions/3.5.0/lib/python3.5/inspect.py", line 1044, in getargspec
raise ValueError("Function has keyword-only arguments or annotations"
ValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them
The text was updated successfully, but these errors were encountered: