Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3 type hinting for dynamic attributes through __getattr__ [duplicate]

To wrap all function calls of a module and access it via an wrapper class's __getattr__ method, I tried to use typing library but I could not figure out on how to do this correctly.

import interface

"""
>>> print(interface.__all__)
['execute_foo_operation', ...]
"""

class InterfaceWrapper(object):
    def __init__(self, job_queue):
        self.job_queue = job_queue
        self.callbacks = []

    def __getattr__(self, name):
        func = getattr(interface, name)
        return functools.partial(self._wrapper, func)

    def _wrapper(self, func, *args, **kwargs):
        job = func(*args, **kwargs)
        self.job_queue.push(job)
        for callback in self.callbacks:
            callback(job)
        return job

    def register_callback(self, callback):
        self.callbacks.append(callback)


class Operator(object):
    def __init__(self, job_queue):
        self.interface = InterfaceWrapper(job_queue)

    def after_queuing(self):
        # do something

    def execute_foo_operation(self):
        self.interface.register_callback(self.after_queuing)
        self.interface.execute_foo_operation()  # unresolved attribute

Can anyone guide my code to work correctly?

like image 927
junsang Avatar asked Mar 01 '26 22:03

junsang


1 Answers

Usually, __getattr__ can return anything. So you could use Typing.Any

From Typing import Any

def __getattr__(self, name: str) -> Any:
    ...

But it looks like your implementation of __getattr__ is to return a callable

From Typing import Callable

def __getattr__(self, name: str) -> Callable:
    ...
like image 51
Laurent Pinson Avatar answered Mar 03 '26 10:03

Laurent Pinson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!