Skip to content

Instantly share code, notes, and snippets.

@simleo
Created July 15, 2017 09:12
Show Gist options
  • Save simleo/64556c03d20ba4640303ccc3d62f3984 to your computer and use it in GitHub Desktop.
Save simleo/64556c03d20ba4640303ccc3d62f3984 to your computer and use it in GitHub Desktop.
Python decorator with arguments
from functools import wraps
def admin_only(*fargs):
def _admin_only(func):
@wraps(func)
def _check_admin(*args, **kwargs):
self = args[0]
if not self.user.isAdmin:
raise RuntimeError("ERROR: admin only")
elif not set(fargs) <= set(self.user.adminPrivileges):
raise RuntimeError("ERROR: insufficient privileges")
return func(*args, **kwargs)
return _check_admin
return _admin_only
class User(object):
def __init__(self, is_admin, admin_privileges=None):
self._is_admin = is_admin
self._admin_privileges = admin_privileges or []
@property
def isAdmin(self):
return self._is_admin
@property
def adminPrivileges(self):
return self._admin_privileges
def __repr__(self):
return "User(admin=%r, privileges=%r)" % (
self.isAdmin, self.adminPrivileges
)
class Consumer(object):
def __init__(self, user):
self.user = user
@admin_only()
def m1(self):
"""m1, only for admins"""
return "m1"
@admin_only("Foo")
def m2(self):
"""m2, only for Foo-enabled admins"""
return "m2"
@admin_only("Foo", "Bar")
def m3(self):
"""m3, only for Foo- and Bar-enabled admins"""
return "m3"
def main():
all_users = [
User(True, ["Foo", "Bar"]),
User(True, ["Foo"]),
User(True, ["Bar"]),
User(False),
]
for user in all_users:
consumer = Consumer(user)
print consumer.m1.__doc__
try:
print "%r: %r" % (user, consumer.m1())
except RuntimeError as e:
print "%r: %r" % (user, e)
print consumer.m2.__doc__
try:
print "%r: %r" % (user, consumer.m2())
except RuntimeError as e:
print "%r: %r" % (user, e)
print consumer.m3.__doc__
try:
print "%r: %r" % (user, consumer.m3())
except RuntimeError as e:
print "%r: %r" % (user, e)
print
if __name__ == "__main__":
main()
@simleo
Copy link
Author

simleo commented Jul 15, 2017

% python try_decorators_args.py
m1, only for admins
User(admin=True, privileges=['Foo', 'Bar']): 'm1'
m2, only for Foo-enabled admins
User(admin=True, privileges=['Foo', 'Bar']): 'm2'
m3, only for Foo- and Bar-enabled admins
User(admin=True, privileges=['Foo', 'Bar']): 'm3'

m1, only for admins
User(admin=True, privileges=['Foo']): 'm1'
m2, only for Foo-enabled admins
User(admin=True, privileges=['Foo']): 'm2'
m3, only for Foo- and Bar-enabled admins
User(admin=True, privileges=['Foo']): RuntimeError('ERROR: insufficient privileges',)

m1, only for admins
User(admin=True, privileges=['Bar']): 'm1'
m2, only for Foo-enabled admins
User(admin=True, privileges=['Bar']): RuntimeError('ERROR: insufficient privileges',)
m3, only for Foo- and Bar-enabled admins
User(admin=True, privileges=['Bar']): RuntimeError('ERROR: insufficient privileges',)

m1, only for admins
User(admin=False, privileges=[]): RuntimeError('ERROR: admin only',)
m2, only for Foo-enabled admins
User(admin=False, privileges=[]): RuntimeError('ERROR: admin only',)
m3, only for Foo- and Bar-enabled admins
User(admin=False, privileges=[]): RuntimeError('ERROR: admin only',)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment