Django 2.1 - 'functools.partial' object has no attribute '__name__'

前端 未结 1 1450
夕颜
夕颜 2021-01-21 06:34

I recently upgraded Django from 2.0.7 to 2.1.1, a new error occurs in which I get this error \'functools.partial\' object has no attribute \'__name__\'.

I\

相关标签:
1条回答
  • 2021-01-21 07:13

    Rather than manually copy things across, use the @functools.wraps() decorator to handle this for you:

    from functools import wraps
    
    def auth0_login_required(function):
        @wraps(function)
        def wrap(request, *args, **kwargs):
    
            if request.isAuthenticated or request.user.is_staff:
                pass
            else:
                raise Http404()
    
            return function(request, *args, **kwargs)
    
        return wrap
    

    The @wraps() decorator (via the functools.update_wrapper() function it calls knows how to handle functools.partial objects correctly (or rather, it can handle the fact that functools.partial objects have no __name__ attribute).

    It's fine that the wrapped functools.partial() object found on the View class doesn't have a __name__ attribute, what's not fine is that you then don't copy that attribute at all even when you are decorating functions that do have the attribute. If you don't want to use @wraps() you'd have to manually copy the attribute across and handle the exception yourself:

    try:
        wrap.__name__ = function.__name__
    except AttributeError:
        pass
    try:
        wrap.__doc__ = function.__doc__
    except AttributeError:
        pass
    

    but take into account that this doesn't copy the __qualname__, __module__ and __annotations__ attributes, doesn't handle any custom attributes set on function (which other decorators might rely on). @functools.wraps() does take care of all of those, plus it sets the __wrapped__ attribute on the decorator wrapper function that would let you unwrap the decorator again.

    0 讨论(0)
提交回复
热议问题