diff --git a/deepkit/__init__.py b/deepkit/__init__.py index 6615344..023fd72 100644 --- a/deepkit/__init__.py +++ b/deepkit/__init__.py @@ -59,19 +59,32 @@ class StdHook: def __init__(self, s): self.s = s - def fileno(self): - return self.s.fileno() - - def isatty(self): - return self.s.isatty() - - def flush(self): - self.s.flush() - def write(self, s): self.s.write(s) log(s) + def __getattr__(self, name): + """Forward the __getattr__ call to the wrapped object. + + From https://docs.python.org/3/reference/datamodel.html#object.__getattr__: + > Note that if the attribute is found through the normal mechanism, + > __getattr__() is not called. + + Therefore, `self.s` does not run into a recursion error. + """ + return getattr(self.s, name) + + def __setattr__(self, name, value): + """Set an attribute on the wrapped object. + + Taken from: https://stackoverflow.com/a/17020163/15235649 + + Note: `super(StdHook, self).__setattr__` returns the method from + `object.__setattr__. + """ + if name == "s": + return super(StdHook, self).__setattr__(name, value) + return setattr(self.s, name, value) sys.stdout = StdHook(sys.__stdout__) sys.stderr = StdHook(sys.__stderr__)