Closed
Description
The decorators capture their secrets at import time, and do not re-get their secrets when the target function is called. So the cache logic doesn't have a chance to run again, and the values stay potentially stale. This code illustrates the problem:
class Cache():
def __init__(self):
self.n = 0
def get_secret_string(self, secret_id):
self.n += 1
return str(self.n)
cache = Cache()
class InjectSecretString:
def __init__(self, secret_id, cache):
self.cache = cache
self.secret_id = secret_id
def __call__(self, func):
secret = self.cache.get_secret_string(secret_id=self.secret_id)
def _wrapped_func(*args, **kwargs):
return func(secret, *args, **kwargs)
return _wrapped_func
@InjectSecretString("mysecretid", cache)
def test_function(args):
print(f"{args=}")
def main():
# NOTE: decorated function doesn't refresh cache
test_function()
test_function()
print(f'{cache.get_secret_string("mysecretid")}')
print(f'{cache.get_secret_string("mysecretid")}')
if __name__ == "__main__":
main()