PK!8DDwint/__init__.pyfrom .decorators import autowired, wire_class, wire_func, container PK!ަ!!wint/container.pyfrom . import punq class PunqContainer: EMPTY = "__EMPTY__" def __init__(self): self.container = punq.Container() def __str__(self): return f"<{self.__class__.__name__}>" def resolve(self, typ, *args, **kwargs): try: return self.container.resolve(typ, *args, **kwargs) except punq.MissingDependencyException: return self.EMPTY def register(self, typ, impl=None, **kwargs): return self.container.register(typ, impl, **kwargs) container = PunqContainer() PK!;;wint/decorators.pyimport inspect import typing from functools import wraps from .container import container from .descriptor import DependencyDescriptor def autowired(container=container): def inner(smth): if inspect.isclass(smth): return wire_class(container)(smth) return wire_func(container)(smth) return inner def wire_class(container=container): def inner(cls): annotations = typing.get_type_hints(cls) for attr, typ in annotations.items(): setattr(cls, attr, DependencyDescriptor(typ, container)) for method_name, method in inspect.getmembers(cls, inspect.isroutine): if method_name.startswith("__") and method_name.endswith("__"): continue wrapped_method = wire_func(container=container)(method) setattr(cls, method_name, wrapped_method) return cls return inner def wire_func(container=container): def inner(fn): @wraps(fn) def wrapper(*args, **kwargs): sig = inspect.signature(fn) if inspect.ismethod(fn): ba = sig.bind_partial(*args[1:], **kwargs) else: ba = sig.bind_partial(*args, **kwargs) for par_name, par in sig.parameters.items(): if par_name not in ba.arguments and par.annotation: a = container.resolve(par.annotation) if a != container.EMPTY: ba.arguments[par_name] = a return fn(*ba.args, **ba.kwargs) return wrapper return inner PK!(qqwint/descriptor.pyfrom .container import container class DependencyDescriptor: def __init__(self, typ, container=container): self.name = None self.typ = typ self.container = container def __get__(self, instance, owner): if self.name in instance.__dict__: return instance.__dict__[self.name] impl = self.container.resolve(self.typ) if impl == self.container.EMPTY: raise AttributeError() return impl def __set__(self, instance, value): instance.__dict__[self.name] = value def __set_name__(self, owner, name): self.name = name PK!G,,wint/punq/LICENSEMIT License Copyright (c) 2017 Bob Gregory Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!G,,wint/punq/LICENSEMIT License Copyright (c) 2017 Bob Gregory Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!p!ڝwint/punq/README.mdThis is vendored version of punq library. https://github.com/bobthemighty/punq License: MIT Version: 0.1.0 Commit: c99ed2a2dede74acd8bdd5a49510d869a9cc4559PK!p!ڝwint/punq/README.mdThis is vendored version of punq library. https://github.com/bobthemighty/punq License: MIT Version: 0.1.0 Commit: c99ed2a2dede74acd8bdd5a49510d869a9cc4559PK!_wint/punq/__init__.pyimport itertools from collections import defaultdict, namedtuple import typing import logging class MissingDependencyException (Exception): pass class InvalidRegistrationException (Exception): pass Registration = namedtuple('Registration', ['service', 'builder', 'needs', 'args']) class Registry: def __init__(self): self.__registrations = defaultdict(list) def _get_needs_for_ctor(self, cls): sig = typing.get_type_hints(cls.__init__) return sig def register_service_and_impl(self, service, impl, resolve_args): """Registers a concrete implementation of an abstract service. Examples: In this example, the EmailSender type is an abstract class and SmtpEmailSender is our concrete implementation. >>> class EmailSender: ... def send(self, msg): ... pass ... >>> class SmtpEmailSender (EmailSender): ... def send(self, msg): ... print("Sending message via smtp") ... >>> container.register(EmailSender, SmtpSender) >>> instance = container.resolve(EmailSender) >>> instance.send("Hello") >>> Sending message via smtp """ self.__registrations[service].append(Registration( service, impl, self._get_needs_for_ctor(impl), resolve_args)) def register_service_and_instance(self, service, instance): """Register a singleton instance to implement a service. Examples: If we have an object that is expensive to construct, or that wraps a resouce that must not be shared, we might choose to use a singleton instance. >>> class DataAccessLayer: ... pass ... >>> class SqlAlchemyDataAccessLayer (DataAccessLayer): ... def __init__(self, engine:SqlAlchemy.Engine): ... pass ... >>> container.register( ... DataAccessLayer, ... SqlAlchemyDataAccessLayer(create_engine(db_uri)))""" self.__registrations[service].append(Registration( service, lambda: instance, {}, {})) def register_concrete_service(self, service): """ Register a service as its own implementation. Examples: If we need to register a dependency, but we don't need to abstract it, we can register it as concrete. >>> class FileReader: ... def read (self): ... # Assorted legerdemain and rigmarole ... pass ... >>> container.register(FileReader)""" if not type(service) is type: raise InvalidRegistrationException( "The service %s can't be registered as its own implementation" % (repr(service))) self.__registrations[service].append(Registration( service, service, self._get_needs_for_ctor(service), {})) def build_context(self, key, existing=None): if existing is None: return ResolutionContext(key, list(self.__getitem__(key))) if key not in existing.targets: existing.targets[key] = ResolutionTarget(key, list(self.__getitem__(key))) return existing def register(self, service, _factory=None, **kwargs): resolve_args = kwargs or {} if _factory is None: self.register_concrete_service(service) elif callable(_factory): self.register_service_and_impl(service, _factory, resolve_args) else: self.register_service_and_instance(service, _factory) def __getitem__(self, service): return self.__registrations[service] @property def registrations(self): return typing.MappingProxyType(self.__registrations) class ResolutionTarget: def __init__(self, key, impls): self.service = key self.impls = impls def is_generic_list(self): try: if self.service.__origin__ == typing.List: return self.service.__args__[0] except AttributeError as e: return None @property def generic_parameter(self): return self.service.__args__[0] def next_impl(self): if len(self.impls) > 0: return self.impls.pop() class ResolutionContext: def __init__(self, key, impls): self.targets = {key: ResolutionTarget(key, impls)} self.cache = {} self.service = key def target(self, key): return self.targets.get(key) def has_cached(self, key): return key in self.cache def __getitem__(self, key): return self.cache.get(key) def __setitem__(self, key, instance): self.cache[key] = instance def all_registrations(self, service): return self.targets[service].impls class Container: def __init__(self): self.registrations = Registry() def register(self, service, _factory=None, **kwargs): self.registrations.register(service, _factory, **kwargs) def resolve_all(self, service, **kwargs): context = self.registrations.build_context(service) return [ self._build_impl(x, kwargs, context) for x in context.all_registrations(service) ] def _build_impl(self, registration, resolution_args, context): """Instantiate the registered service. """ args = { k: self._resolve_impl(v, resolution_args, context) for k, v in registration.needs.items() if k != 'return' and k not in registration.args } args.update(registration.args) args.update(resolution_args or {}) result = registration.builder(**args) context[registration.service] = result return result def _resolve_impl(self, service_key, kwargs, context): context = self.registrations.build_context(service_key, context) if context.has_cached(service_key): return context[service_key] target = context.target(service_key) if target.is_generic_list(): return self.resolve_all(target.generic_parameter) registration = target.next_impl() if registration is None: raise MissingDependencyException( 'Failed to resolve implementation for '+str(service_key)) if service_key in registration.needs.values(): self._resolve_impl(service_key, kwargs, context) return self._build_impl(registration, kwargs, context) def resolve(self, service_key, **kwargs): context = self.registrations.build_context(service_key) return self._resolve_impl(service_key, kwargs, context) PK!_wint/punq/__init__.pyimport itertools from collections import defaultdict, namedtuple import typing import logging class MissingDependencyException (Exception): pass class InvalidRegistrationException (Exception): pass Registration = namedtuple('Registration', ['service', 'builder', 'needs', 'args']) class Registry: def __init__(self): self.__registrations = defaultdict(list) def _get_needs_for_ctor(self, cls): sig = typing.get_type_hints(cls.__init__) return sig def register_service_and_impl(self, service, impl, resolve_args): """Registers a concrete implementation of an abstract service. Examples: In this example, the EmailSender type is an abstract class and SmtpEmailSender is our concrete implementation. >>> class EmailSender: ... def send(self, msg): ... pass ... >>> class SmtpEmailSender (EmailSender): ... def send(self, msg): ... print("Sending message via smtp") ... >>> container.register(EmailSender, SmtpSender) >>> instance = container.resolve(EmailSender) >>> instance.send("Hello") >>> Sending message via smtp """ self.__registrations[service].append(Registration( service, impl, self._get_needs_for_ctor(impl), resolve_args)) def register_service_and_instance(self, service, instance): """Register a singleton instance to implement a service. Examples: If we have an object that is expensive to construct, or that wraps a resouce that must not be shared, we might choose to use a singleton instance. >>> class DataAccessLayer: ... pass ... >>> class SqlAlchemyDataAccessLayer (DataAccessLayer): ... def __init__(self, engine:SqlAlchemy.Engine): ... pass ... >>> container.register( ... DataAccessLayer, ... SqlAlchemyDataAccessLayer(create_engine(db_uri)))""" self.__registrations[service].append(Registration( service, lambda: instance, {}, {})) def register_concrete_service(self, service): """ Register a service as its own implementation. Examples: If we need to register a dependency, but we don't need to abstract it, we can register it as concrete. >>> class FileReader: ... def read (self): ... # Assorted legerdemain and rigmarole ... pass ... >>> container.register(FileReader)""" if not type(service) is type: raise InvalidRegistrationException( "The service %s can't be registered as its own implementation" % (repr(service))) self.__registrations[service].append(Registration( service, service, self._get_needs_for_ctor(service), {})) def build_context(self, key, existing=None): if existing is None: return ResolutionContext(key, list(self.__getitem__(key))) if key not in existing.targets: existing.targets[key] = ResolutionTarget(key, list(self.__getitem__(key))) return existing def register(self, service, _factory=None, **kwargs): resolve_args = kwargs or {} if _factory is None: self.register_concrete_service(service) elif callable(_factory): self.register_service_and_impl(service, _factory, resolve_args) else: self.register_service_and_instance(service, _factory) def __getitem__(self, service): return self.__registrations[service] @property def registrations(self): return typing.MappingProxyType(self.__registrations) class ResolutionTarget: def __init__(self, key, impls): self.service = key self.impls = impls def is_generic_list(self): try: if self.service.__origin__ == typing.List: return self.service.__args__[0] except AttributeError as e: return None @property def generic_parameter(self): return self.service.__args__[0] def next_impl(self): if len(self.impls) > 0: return self.impls.pop() class ResolutionContext: def __init__(self, key, impls): self.targets = {key: ResolutionTarget(key, impls)} self.cache = {} self.service = key def target(self, key): return self.targets.get(key) def has_cached(self, key): return key in self.cache def __getitem__(self, key): return self.cache.get(key) def __setitem__(self, key, instance): self.cache[key] = instance def all_registrations(self, service): return self.targets[service].impls class Container: def __init__(self): self.registrations = Registry() def register(self, service, _factory=None, **kwargs): self.registrations.register(service, _factory, **kwargs) def resolve_all(self, service, **kwargs): context = self.registrations.build_context(service) return [ self._build_impl(x, kwargs, context) for x in context.all_registrations(service) ] def _build_impl(self, registration, resolution_args, context): """Instantiate the registered service. """ args = { k: self._resolve_impl(v, resolution_args, context) for k, v in registration.needs.items() if k != 'return' and k not in registration.args } args.update(registration.args) args.update(resolution_args or {}) result = registration.builder(**args) context[registration.service] = result return result def _resolve_impl(self, service_key, kwargs, context): context = self.registrations.build_context(service_key, context) if context.has_cached(service_key): return context[service_key] target = context.target(service_key) if target.is_generic_list(): return self.resolve_all(target.generic_parameter) registration = target.next_impl() if registration is None: raise MissingDependencyException( 'Failed to resolve implementation for '+str(service_key)) if service_key in registration.needs.values(): self._resolve_impl(service_key, kwargs, context) return self._build_impl(registration, kwargs, context) def resolve(self, service_key, **kwargs): context = self.registrations.build_context(service_key) return self._resolve_impl(service_key, kwargs, context) PK!6L,E22wint-0.1.0.dist-info/LICENSEMIT License Copyright (c) 2018 Stanislav Lobanov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK!H_zTTwint-0.1.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]n0H*J>mlcAPK!H=j{wint-0.1.0.dist-info/METADATAT]O0}h&!mRV @Z5`Vcpě?2i]'i)p:ܠ9< [0ОϏ-jm u:k@_yr_o*bjF/(Y}ɤ zgFMkt8i\ #Ǜ}fkl_)3W/M`N \f["T\q;+AO-,!Wt6=? ɝkIs8*k6w3? \)\5"aw^]ˬoх_f'ѫ5fw,[â:)o1~ei{Fp8eI)I M ydu!)G+ܣ%vCeAmѲ%Qko49RQfRD4"uȓdb@+5CBHQg rAuk|;W֚et?);rGh74]dk!D("6Rt ndA oZj8s%cGE>T*Ma:Aҽi:u-p7~Fhzb75Ԑq!iQ:*9lx;TPK!HA.wint-0.1.0.dist-info/RECORD˒@\ :" FrPaChDJJMvxa i5PM<FT0 Y70x#{Sx_LR6IZrX1=3(ioi|ٖ97ӤO>qv5u)q j`1«֯4dV.)PMRDq*צl.']!̪z~k.]GKh:vdk`Vش+u)(~%JWcȡu\aw*:Ks){/~ʺe*ŀ lkq?Fu!+|6̔i'99ghz1O@%%}4{K >