python - Detect if method is decorated before invoking it -


i wrote python flow control framework works unittest.testcase: user creates class derived framework class, , writes custom task_*(self) methods. framework discovers them , runs them:

################### # framework library ################### import functools  class skiptask(baseexception):     pass  def skip_if(condition):     def decorator(task):         @functools.wraps(task)         def wrapper(self, *args, **kargs):             if condition(self):                 raise skiptask()             return task(self, *args, **kargs)         return wrapper     return decorator  class myframework(object):     def run(self):         print "starting task"         try:             self.task()         except skiptask:             print "skipped task"         except exception:             print "failed task"             raise         else:             print "finished task"  ############# # user script ############# class myuserclass(myframework):     skip_flag = true      @skip_if(lambda self: self.skip_flag)     def task(self):         print "doing something"  if __name__ == '__main__':     myuserclass().run() 

output:

starting task skipped task 

i want change framework that, whenever condition of @skip_if true, wrapper not print "starting task". tried this, doesn't work:

def skip_if(condition):     def decorator(task):         print "decorating "  + str(task)         task.__skip_condition = condition         return task     return decorator  class myframework(object):     def run(self):         try:             if self.task.__skip_condition():                 print "skipped task"                 return         except attributeerror:             print str(self.task) + " not decorated"             pass          print "starting task"         try:             self.task()         except exception e:             print "failed task: " + str(e)             raise         else:             print "finished task" 

output:

decorating <function task @ 0x194fcd70> <bound method myuserclass.task of <__main__.myuserclass object @ 0x195010d0>> not decorated starting task doing finished task 

why wasn't task skipped instead?

you using double underscore name, has undergone private name mangling in run method.

when stepping through debugger, get:

attributeerror: "'function' object has no attribute '_myframework__skip_condition 

don't use double underscore names here; if rename function attribute _skip_condition code works (provided bind condition function or pass in self explicitly):

def skip_if(condition):     def decorator(task):         print "decorating "  + str(task)         task._skip_condition = condition         return task     return decorator  class myframework(object):     def run(self):         try:             if self.task._skip_condition(self):                 print "skipped task"                 return         except attributeerror:             print str(self.task) + " not decorated"             pass          print "starting task"         try:             self.task()         except exception e:             print "failed task: " + str(e)             raise         else:             print "finished task" 

with these changes output becomes:

decorating <function task @ 0x1071a1b90> skipped task 

Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -