My brain feels slow today.
I'm writing pre/post/invariants in Python using decorators. Currently, I need each call to specify the locals and globals for context, and this feels ugly. Is there a way to get the locals and globals from the decorator application level even though it's an arbitrary depth.
That is, I'm trying to make this ugly code: from dectools import invariant, pre, post, call_if
@invariant("self.price >= 0 and self.inventory >= 0 and Item.tax_rate >= 0")
class Item(object):
tax_rate = 0.10 # California. No property taxes on old property.
@post("ItemDB.fetch(self) = (name, price)", locals(), globals())
def __init__(self, name, price):
self.name = name
self.price = price
self.total_sold = 0
self.inventory = 0
@call_if(check_level, "manager")
@post("self.total_sold > 0", locals(), globals())
@pre("discount > 0 and discount <= self.price * 0.50", locals(), globals())
def adjust_price(self, adjustment):
....
into the same ugly code without all the "locals(), globals()". I run into problems where the nested decorators give me arbitrary stack depths, so my implementation of dectools.pre couldn't grab from a constant depth sys._getframe(). The stack is not something I've played with much, and would appreciate it if someone has a trick. (Yes, I'm hacking the local variables into the locals by assuming self will be in the right stack frame. It's the Item.tax_rate that is always out of scope, and self, and ItemDB.)
Thank you in advance,
Charles