bobthemighty / punq

An IoC container for Python 3.6+
MIT License
301 stars 13 forks source link

Enable use of annotated types #180

Closed neilmacintyre closed 3 weeks ago

neilmacintyre commented 6 months ago

Changing to draft. This breaks backwards compatibility in cases where Annotated types are used for reasons other than punq resolutions. This is probably best solved by adding a flag in the annotations to indicate that they are for punq and falling back to the type in the annotated type if the flag is missing

Allows types to be register as annotated types to to allow for disambiguating between common types.

An example of this in use (previously the annotation part of the type was scrubbed before registering):

from typing import Annotated, Generic, Type, TypeVar

import punq

container = punq.Container()

T = TypeVar('T')

class Subscriber(Generic[T]):
    def __init__(self, msg_type: Type[T], topic: str):
        self.msg_type = msg_type
        self.topic = topic

class Test:
    def __init__(
        self,
        temp_sub: Annotated[Subscriber[float], '/topic/temp'],
        dist_sub: Annotated[Subscriber[float], '/topic/dist'],
    ):
        self.temp_sub = temp_sub
        self.dist_sub = dist_sub

    def print_topic_names(self) -> None:
        print(self.temp_sub.topic)
        print(self.dist_sub.topic)

if __name__ == '__main__':
    temp_sub = Subscriber(float, '/topic/temp')
    container.register(Annotated[Subscriber[float], 'punq::/topic/temp'], instance=temp_sub)

    dist_sub = Subscriber(float, '/topic/dist')
    container.register(Annotated[Subscriber[float], 'punq::/topic/dist'], instance=dist_sub)

    container.register(Test)
    test = container.resolve(Test)
    test.print_topic_names()
    print(test.temp_sub.topic)
    print(test.dist_sub.topic)