#13854 closed (wontfix)
List of used decorators on a function
Reported by: | Mitar | Owned by: | nobody |
---|---|---|---|
Component: | Core (Other) | Version: | 1.2 |
Severity: | Keywords: | ||
Cc: | mmitar@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Sometimes it is useful to be able to check which decorators are already applied to a function (view mostly), especially when you are constructing them dynamically. I am proposing that all decorators in Django maintain a list of used decorators on a function. It is required that all decorators do this for the idea to be useful.
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME, decorator_id=None): """ Decorator for views that checks that the user passes the given test, redirecting to the log-in page if necessary. The test should be a callable that takes the user object and returns True if the user passes. It maintains `decorators` attribute on wrapped function with list of all ids of used decorators, where the first one is the first one used. """ if not login_url: from django.conf import settings login_url = settings.LOGIN_URL if decorator_id is None: decorator_id = id(user_test_required) def decorator(view_func): def _wrapped_view(request, *args, **kwargs): if test_func(request.user): return view_func(request, *args, **kwargs) path = urlquote(request.get_full_path()) tup = login_url, redirect_field_name, path return HttpResponseRedirect('%s?%s=%s' % tup) wrapped_view_func = wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view) wrapped_view_func.decorators = [] if hasattr(view_func, 'decorators'): wrapped_view_func.decorators += view_func.decorators wrapped_view_func.decorators.append(decorator_id) return wrapped_view_func return decorator
decorator_id
can in fact be anything. Developer can for example use a tuple with additional information. In this case it could be maybe useful to use (id(user_test_required), id(test_func))
to differentiate between different uses of decorator. Or in the case of permission_required
decorator perm
parameter could be stored in the tuple.
Of course this functionally can be also made into a decorator. ;-) So we could have a decorator which we would apply to decorators to have them registered in decorators
attribute.
I am willing to make a patch if there will be confirmation for this idea.
Change History (5)
follow-up: 2 comment:1 by , 14 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
comment:2 by , 14 years ago
Replying to russellm:
Trying to define decorators in a way that requires internal implementations to inspect what they are wrapped in defeats the purpose of being a black box.
Not require, but allow them to inspect. It is the same reasoning why inspect
module is in Python - to be able to inspect Python structures, to have this possibility. If you do not want it then you do can use Python structures as they were given to you. But you have an option.
And I would like the same to see from decorators. It is not really so important that all decorators update this. If they would not then they would be hidden from inspection. But if developer wants to use inspection then he would choose such decorators which use this (or change them in this way). If all Django's decorators would already be such it would be much easier to use them.
So for backwards compatibility available_attrs
would return also decorators
which would then make this attribute to be passed through decorated function. If decorator wants to add itself (it supports decorators
attribute) it can add itself. So there is no need that all decorators immediately start doing that - by extending available_attrs
and extending all Django decorators we would just make it easier to start doing that.
If you really want this, a better place to pursue this would be at the language level -- after all, decorators aren't a Django feature, they're a Python language feature.
Django defines its own decorators not just use Python decorators. Decorators in Python are mostly syntax question. How does they behave is open to developers. And Django developers could opt for such extension.
comment:3 by , 14 years ago
There is exactly *zero* difference between a decorator in Python and a decorator in Django. The syntax is identical, and the intended mode of usage is identical. If you want inspect-like features, then -- again -- you should be talking to the Python core team and convincing them to add decorator inspection to the features of the language. I'm not in favor of adding language-level features to Django. Django is a Python library. It shouldn't be trying to change the language.
comment:4 by , 14 years ago
Also - if you want to continue this discussion, please do so on Django-developers. Trac is a really bad place to hold design discussions.
Erm... no.
Firstly, any proposal that starts with "Assumes that every implementation in the world does X" is a non-starter, especially when there are so many decorators already in the field.
However, most importantly, the whole point of decorators is the anonymous black-box wrapping of functions. Trying to define decorators in a way that requires internal implementations to inspect what they are wrapped in defeats the purpose of being a black box.
If you really want this, a better place to pursue this would be at the language level -- after all, decorators aren't a Django feature, they're a Python language feature. However, I strongly suspect you'll get the same response from the Python core developers.