This is a toy example of a larger code I'm working right now. Suppose I have a function and I want to decorate it in a way that I can keep record of arguments that are valid, legacy or forbidden:
@option("1")
@option("2", legacy=True)
def do_stuff(opt):
print(f"You chose {opt}!")
do_stuff("1")
do_stuff("2")
do_stuff("3")
The result of this would be something like
You chose 1!
2 is deprecated!
You chose 2!
3 is not allowed!
I tried implementing this behavior in some different ways now, my latest attempt is this:
from functools import wraps
def option(opt, legacy=False):
def add_opt(f, option):
if not hasattr(f, "opts"):
f.opts = []
f.opts.append(option)
def add_legacy_opt(f, option):
if not hasattr(f, "legacy"):
f.legacy = []
f.legacy.append(option)
def decorate(func):
@wraps(func)
def wrapper(option):
if hasattr(wrapper, "opts") and option not in wrapper.opts:
print(f"{option} is not allowed!")
return
if hasattr(wrapper, "legacy") and option in wrapper.legacy:
print(f"{option} is deprecated!")
return func(option)
add_opt(wrapper, opt)
if legacy:
add_legacy_opt(wrapper, opt)
return wrapper
return decorate
It almost works. The thing is that it gives me double legacy messages:
You chose 1!
2 is deprecated!
2 is deprecated!
You chose 2!
3 is not allowed!
If anyone has any ideas, let me know! Thanks :D
Update: Decorating in a different order works:
@option("2", legacy=True)
@option("1")
def do_stuff(opt):
print(f"You chose {opt}!")