I have a proxy class with an underlying object. I wish to pass the proxy object to a function that expects and underlying object type. How do I make the proxy typing match the underlying object?
class Proxy:
def __init__(self, obj):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Warning: expected 'MyClass', got 'Proxy' instead
Credit to @SUTerliakov for actually providing the essence of this answer in the comment on the question. The code should look something along the lines of the following:
from typing import TYPE_CHECKING
from my_module import MyClass
if TYPE_CHECKING:
base = MyClass
else:
base = object
class Proxy(base):
def __init__(self, obj):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Works!
Note that your class may not always be available - but that's no real problem. The trick works perfectly fine with TypeVars.
# proxy.py
from typing import TYPE_CHECKING, TypeVar
Proxied = TypeVar('Proxied')
if TYPE_CHECKING:
base = Proxied
else:
base = object
class Proxy(base):
def __init__(self, obj: Proxied):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
And in the file where you use it:
from proxy import Proxy
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Works!