PK!|$55wint/__init__.pyfrom .decorators import autowired, ContainerProvider PK!qqwint/container.pyfrom . import punq class Container: EMPTY = "__EMPTY__" def __init__(self): self._initialize_container() def _initialize_container(self): self._container = punq.Container() def resolve(self, typ, **kwargs): try: return self._container.resolve(typ, **kwargs) except punq.MissingDependencyException: return self.EMPTY def register(self, typ, impl=None, **kwargs): return self._container.register(typ, impl, **kwargs) class ContainerProvider: INSTANCE: Container = None @classmethod def get(cls) -> Container: if cls.INSTANCE is None: cls.set(cls._create_container()) return cls.INSTANCE @classmethod def set(cls, container: Container, force=False): if cls.INSTANCE is not None and not force: raise ValueError("Can not set container, because it is already set.") cls.INSTANCE = container @classmethod def _create_container(cls): return Container() @classmethod def resolve(cls, typ, **kwargs): return cls.get().resolve(typ, **kwargs) PK!fDcyywint/decorators.pyimport functools import typing from .container import ContainerProvider from .descriptor import DependencyDescriptor def autowired(cls=None, *, container=None): container = container or ContainerProvider.get() def inner(class_): annotations = typing.get_type_hints(cls) for attr, typ in annotations.items(): try: getattr(cls, attr) except AttributeError: setattr(cls, attr, DependencyDescriptor(typ, container)) return class_ if cls is not None: return inner(cls) return functools.partial(autowired, container=container) PK!`wint/descriptor.pyclass DependencyDescriptor: def __init__(self, typ, container): self.name = None self.typ = typ self.container = container self._cached_impl = None def __get__(self, instance, owner): if self.name in instance.__dict__: return instance.__dict__[self.name] if self._cached_impl is not None: return self._cached_impl impl = self.container.resolve(self.typ) if impl == self.container.EMPTY: raise AttributeError() self._cached_impl = impl 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!ymPwint/punq/README.mdThis is vendored version of punq library. https://github.com/bobthemighty/punq License: MIT Version: 0.1.0 Commit: c99ed2a2dede74acd8bdd5a49510d869a9cc4559 PK!ymPwint/punq/README.mdThis is vendored version of punq library. https://github.com/bobthemighty/punq License: MIT Version: 0.1.0 Commit: c99ed2a2dede74acd8bdd5a49510d869a9cc4559 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!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.2.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.2.0.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]n0H*J>mlcAPK!Hq;{ wint-0.2.0.dist-info/METADATAVmo6_ql/,)0wi4!,Z:I\%R%)90`?bpdGR4Ɉ͐sGASnF(3WOSvT .FL:7L, -v5BA*\<'cY-94(QՒN&KJ$( ܲ+^+\ SԎK' (W = p0;fqݑ(EE (1"Hf{pZ78kZLw8>Q*׼"\q7'Ջ/s4eh-jŅ]RV`.R<ф?k_0vF+m̯Ӂ VVE"">DͿi.b]qcQ>Gm|]PmKCw?(K X+rGLRݣ5)l鴪KV񂴂qD΅{ q̾vKUBmj= |#jw} f\6DsePGJcXNL㘢NVi.:$p&JN;&MvZpRA 6cz(@"*uߚ Q/ f%Әhѱ/#;$ȳodqkʿ&+(YAaVgr ..ͬiXHõ& f L&;CMqCE61bl>Ĥ9h.o DG1g#Q˷KmTr Dj[7a >|9p:; ꖮqTW:!6 8:4bpnG`^ԫi6d8=@Dۭkltv%=`)U-?;Jꓘ\ƒbXt*ҽ&f!"Yp4ܺ$;Fb*EgkqT[Һ"Սxo^vjG^+[:@KCh㨇PK!H݁wint-0.2.0.dist-info/RECORDn@}, 0E "6A?=iLeoɗXku1`<|oD+6X8eP~P:ouڡ Ix2qSQQos8.8fzz;z7-v.dgcl