Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting local variables of function

I'm trying to get a local variable from a decorator. An example:

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else: 
            return func(self, *args, **kwargs)

    return decorator(validate)

After decorating a function, like this:

 @needs_privilege("some_privilege")
 def some_function():
     pass

I would like to retrieve the 'privilige' variable (which validate() uses) from some_function. After searching more than one hour, I'm feeling pretty lost. Is this possible?

Edit: Let me describe my problem a bit more thoroughly: can I get the string "some_prvilege" without executing some_function? Something like:

a = getattr(module, 'somefunction')
print a.decorator_arguments

? Thanks for helping me so far!

like image 201
Martijn Avatar asked Mar 04 '26 07:03

Martijn


2 Answers

Your decorator basically check if a user have the permission to execute a given function, i don't actually understand why you want to retrieve (to attach) the privilege to the function that was being wrapped but you can do this without adding another argument to all your functions.

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else:
            return func(self, *args, **kwargs)
    validate.privelege = privelege
    return decorator(validate)

by the way your decorator should be like this :

def needs_privilege(privilege, project=None):
    def validate(func):
        def new_func(self, *args, **kwargs):
            try: 
                check(self.user, privilege, project)
            except AccessDenied:
                return abort(status_code=401)
            else:
                return func(self, *args, **kwargs)
        new_func.privilege = privilege
        return new_func
    return validate
like image 86
mouad Avatar answered Mar 05 '26 19:03

mouad


You could pass it as a parameter:

def needs_privilege(privilege, project=None):
    """Check whether the logged-in user is authorised based on the
    given privilege

    @type privilege: Privilege object, id, or str
    @param privilege: The requested privilege"""

    def validate(func, self, *args, **kwargs):
        """Validator of needs_privillige"""
        try: check(self.user, privilege, project)
        except AccessDenied:
            return abort(status_code=401)
        else: 
            return func(self, privilege, *args, **kwargs)

    return decorator(validate)

@needs_privilege("some_privilege")
def some_function(privilege):
    pass
like image 39
Radomir Dopieralski Avatar answered Mar 05 '26 19:03

Radomir Dopieralski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!