probably want a `@functools.wraps(fn)` decorator here