Is there a way I can extract which subclass was instantiated given a method from a base class?
I know the question is a bit complicated, so here's an example:
from functools import wraps
def my_wrapper(fn_to_wrap):
@wraps(fn_to_wrap)
async def async_wrapper(*args, **kwargs):
await do_some_async_stuff()
print('Did some async stuff')
return fn_to_wrap(*args, **kwargs)
@wraps(fn_to_wrap)
def sync_wrapper(*args, **kwargs):
do some_sync_stuff()
print('Did some sync stuff')
return fn_to_wrap(*args, **kwargs)
# <my_problem>
if fn_to_wrap belongs_to(SyncClass):
return sync_wrapper
else:
return async_wrapper
# </my_problem>
class BaseClass:
@my_wrapper
def fn_to_wrap(self):
return 'Finally a return a value'
class SyncClass(BaseClass):
def fn_to_call(self):
return self.fn_to_wrap()
class AsyncClass(BaseClass):
async def fn_to_call(self):
return await self.fn_to_wrap()
The problem is that the method fn_to_wrap belongs to the BaseClass. Which my Sync and Async classes inherit from.
Is there a way I can know whether fn_to_wrap belongs to an instance of AsyncClass or SyncClass?
Simply, I want my console to print:
>>> my_sync_class = SyncClass()
>>> print(my_sync_class.fn_to_call())
Done some sync stuff
Finally a return value
and
>>> my_async_class = AsyncClass()
# not in a coroutine for brevity
>>> print(await my_async_class.fn_to_call())
Done some async stuff
FInally a return value
So, how would you implement </my_problem> to achieve those results?
[EDIT]
I'm aware of the existence of inspect.iscoroutinefunction and inspect.iscoroutine. But those won't help because the wrapped method is always synchronous while the wrapper is what does the async tasks.