def test_namedArguments(self):
        resolvedArguments = [
            ResolvedArgument(
                'myNumber',
                PrimitiveArgument(123, 'myNumber'),
                InspectedArgument('myNumber', DType('builtins', 'int'))
            ),
            ResolvedArgument(
                'manuallyWiredService',
                ServiceArgument('my.module.ManuallyWiredClass', 'manuallyWiredService'),
                InspectedArgument('manuallyWiredService', DType('my.module.ManuallyWiredClass', 'ManuallyWiredClass'))
            ),
            ResolvedArgument(
                'autowiredService',
                None,
                InspectedArgument('autowiredService', DType('my.module.OtherClass', 'OtherClass')),
            )
        ]

        classes2Services = {
            'my.module.OtherClass': {'OtherClass': ['my.module.OtherClass']}
        }

        newResolvedArguments = self.__argumentsAutowirer.autowire(
            'my.module.MyClass',
            resolvedArguments,
            classes2Services,
        )

        self.assertEqual(3, len(newResolvedArguments))
        self.assertEqual(PrimitiveArgument(123, 'myNumber'), newResolvedArguments[0].argument)
        self.assertEqual(ServiceArgument('my.module.ManuallyWiredClass', 'manuallyWiredService'), newResolvedArguments[1].argument)
        self.assertEqual(ServiceArgument('my.module.OtherClass', 'autowiredService'), newResolvedArguments[2].argument)
Пример #2
0
    def test_basic(self):
        serviceArgument = ServiceArgument('foo.Bar')
        inspectedArgument = InspectedArgument('bar', DType('foo.Bar', 'Bar'))
        services2Classes = {'foo.Bar': DType('foo.Bar', 'Bar')}
        aliases2Services = {}

        serviceArgument.checkTypeMatchesDefinition(inspectedArgument,
                                                   services2Classes,
                                                   aliases2Services)
Пример #3
0
    def test_basic(self):
        service_argument = ServiceArgument("foo.Bar")
        inspected_argument = InspectedArgument("bar", DType("foo.Bar", "Bar"))
        services2_classes = {"foo.Bar": DType("foo.Bar", "Bar")}
        aliases2_services = {}

        service_argument.check_type_matches_definition(inspected_argument,
                                                       services2_classes,
                                                       aliases2_services)
Пример #4
0
    def test_undefined_service(self):
        service_argument = ServiceArgument("foo.Bar")
        inspected_argument = InspectedArgument("bar", DType("foo.Bar", "Bar"))
        services2_classes = {}
        aliases2_services = {}

        with self.assertRaises(Exception) as error:
            service_argument.check_type_matches_definition(
                inspected_argument, services2_classes, aliases2_services)

        self.assertEqual("Undefined service foo.Bar", str(error.exception))
Пример #5
0
    def test_interface(self):
        serviceArgument = ServiceArgument('injecta.mocks.Bar')
        inspectedArgument = InspectedArgument(
            'bar', DType('injecta.mocks.BarInterface', 'BarInterface'))
        services2Classes = {
            'injecta.mocks.Bar': DType('injecta.mocks.Bar', 'Bar')
        }
        aliases2Services = {}

        serviceArgument.checkTypeMatchesDefinition(inspectedArgument,
                                                   services2Classes,
                                                   aliases2Services)
Пример #6
0
    def test_unknown_aliased_service(self):
        service_argument = ServiceArgument("foo.BarAlias")
        inspected_argument = InspectedArgument("bar", DType("foo.Bar", "Bar"))
        services2_classes = {}
        aliases2_services = {"foo.BarAlias": "foo.Bar"}

        with self.assertRaises(Exception) as error:
            service_argument.check_type_matches_definition(
                inspected_argument, services2_classes, aliases2_services)

        self.assertEqual('Aliased service "foo.Bar" does not exist',
                         str(error.exception))
Пример #7
0
    def test_interface(self):
        service_argument = ServiceArgument("injecta.mocks.Bar")
        inspected_argument = InspectedArgument(
            "bar", DType("injecta.mocks.BarInterface", "BarInterface"))
        services2_classes = {
            "injecta.mocks.Bar": DType("injecta.mocks.Bar", "Bar")
        }
        aliases2_services = {}

        service_argument.check_type_matches_definition(inspected_argument,
                                                       services2_classes,
                                                       aliases2_services)
Пример #8
0
    def test_undefinedService(self):
        serviceArgument = ServiceArgument('foo.Bar')
        inspectedArgument = InspectedArgument('bar', DType('foo.Bar', 'Bar'))
        services2Classes = {}
        aliases2Services = {}

        with self.assertRaises(Exception) as error:
            serviceArgument.checkTypeMatchesDefinition(inspectedArgument,
                                                       services2Classes,
                                                       aliases2Services)

        self.assertEqual('Undefined service foo.Bar', str(error.exception))
Пример #9
0
    def test_unknownAliasedService(self):
        serviceArgument = ServiceArgument('foo.BarAlias')
        inspectedArgument = InspectedArgument('bar', DType('foo.Bar', 'Bar'))
        services2Classes = {}
        aliases2Services = {'foo.BarAlias': 'foo.Bar'}

        with self.assertRaises(Exception) as error:
            serviceArgument.checkTypeMatchesDefinition(inspectedArgument,
                                                       services2Classes,
                                                       aliases2Services)

        self.assertEqual('Aliased service "foo.Bar" does not exist',
                         str(error.exception))
Пример #10
0
    def resolve(self, inspected_argument: InspectedArgument, service_name: str,
                classes2_services: dict):
        module_name = inspected_argument.dtype.module_name
        class_name = inspected_argument.dtype.class_name

        if class_name == "_empty":
            raise Exception("Cannot resolve argument {} for service {}".format(
                inspected_argument.name, service_name))

        if module_name not in classes2_services:
            module_name_stripped = module_name[:module_name.rfind(".")]

            if module_name_stripped in classes2_services:
                raise Exception(
                    "Consider changing service dtype from {} -> {} (invalid dtype)"
                    .format(module_name_stripped + "." + class_name,
                            module_name + "." + class_name))

            raise Exception("Service not found for {} used in {}".format(
                module_name + "." + class_name, service_name))

        if class_name not in classes2_services[module_name]:
            raise Exception("Service not found for {} used in {}".format(
                module_name + "." + class_name, service_name))

        if len(classes2_services[module_name][class_name]) > 1:
            service_names = ", ".join(
                classes2_services[module_name][class_name])
            raise Exception(
                "Multiple services of dtype {} in dtype {} defined ({}), dtype used in service {}"
                .format(class_name, module_name, service_names, service_name))

        return ServiceArgument(classes2_services[module_name][class_name][0],
                               inspected_argument.name)
Пример #11
0
    def test_basic(self):
        raw_services = {
            "injecta.mocks.Bar.Bar": {"arguments": ["Jiri Koutny"]},
            "injecta.mocks.Foo.Foo": {"arguments": ["@injecta.mocks.Bar.Bar"]},
            "injecta.mocks.Bar.BarAlias": "@injecta.mocks.Bar.Bar",
        }

        expected_service1 = Service(
            "injecta.mocks.Bar.Bar",
            DType("injecta.mocks.Bar", "Bar"),
            [
                PrimitiveArgument("Jiri Koutny"),
            ],
        )

        expected_service2 = Service(
            "injecta.mocks.Foo.Foo",
            DType("injecta.mocks.Foo", "Foo"),
            [
                ServiceArgument("injecta.mocks.Bar.Bar"),
            ],
        )

        expected_alias1 = ServiceAlias("injecta.mocks.Bar.BarAlias", "injecta.mocks.Bar.Bar")

        services, aliases = self.__services_preparer.prepare(raw_services)

        self.assertEqual(expected_service1, services[0])
        self.assertEqual(expected_service2, services[1])
        self.assertEqual(expected_alias1, aliases[0])
    def resolve(self, resolvedArgument: ResolvedArgument,
                containerBuild: ContainerBuild):
        argument = resolvedArgument.argument

        if not isinstance(argument, TaggedAliasedServiceArgument):
            return resolvedArgument

        servicesForTag = containerBuild.getServicesByTag(argument.tagName)

        if isinstance(argument.tagAlias, str):
            tagAlias = self.__resolveParameterValue(argument.tagAlias,
                                                    containerBuild.parameters)
        else:
            tagAlias = argument.tagAlias

        for service in servicesForTag:
            tagAttributes = service.getTagAttributes(argument.tagName)

            if 'alias' not in tagAttributes:
                raise Exception(
                    f'"alias" attribute is missing for tag {argument.tagName}')

            if tagAttributes['alias'] == tagAlias:
                resolvedArgument.modifyArgument(
                    ServiceArgument(service.name, argument.name),
                    'tagged_aliased')
                return resolvedArgument

        raise Exception(
            f'No service tagged with {argument.tagName} found for alias: {tagAlias}'
        )
Пример #13
0
    def parse(self, argument, name=None):
        if isinstance(argument, str):
            if argument[0:1] == '@':
                return ServiceArgument(argument[1:], name)

            return PrimitiveArgument(argument, name)

        if isinstance(argument, TaggedServices):
            return TaggedServicesArgument(argument.val, name)

        if isinstance(argument, TaggedAliasedService):
            return TaggedAliasedServiceArgument(argument.tagName,
                                                argument.tagAlias, name)

        if isinstance(argument, (int, bool)):
            return PrimitiveArgument(argument, name)

        if isinstance(argument, list):
            return ListArgument(list(map(self.parse, argument)), name)

        if isinstance(argument, dict):
            return DictArgument(
                {k: self.parse(v)
                 for k, v in argument.items()}, name)

        raise Exception('Unexpected argument type: {}'.format(type(argument)))
Пример #14
0
    def parse(self, service_name: str, raw_service: dict = None):
        if raw_service is None:
            return Service(service_name,
                           self.__type_resolver.resolve(service_name))

        arguments = self.__parse_arguments(raw_service)
        tags = raw_service["tags"] if "tags" in raw_service else []
        class_ = self.__type_resolver.resolve(
            raw_service["class"] if "class" in raw_service else service_name)

        service = Service(service_name, class_, arguments, tags)

        if "autowire" in raw_service:
            service.set_autowire(raw_service["autowire"] is True)

        if "factory" in raw_service:
            if raw_service["factory"][0][0:1] != "@":
                raise Exception(
                    "Factory service name must be prefixed with @ (service {})"
                    .format(service_name))

            service.set_factory(ServiceArgument(raw_service["factory"][0][1:]),
                                raw_service["factory"][1])

        return service
Пример #15
0
    def parse(self, serviceName: str, rawService: dict = None):
        if rawService is None:
            return Service(serviceName,
                           self.__typeResolver.resolve(serviceName))

        arguments = self.__parseArguments(rawService)
        tags = rawService['tags'] if 'tags' in rawService else []
        class_ = self.__typeResolver.resolve(
            rawService['class'] if 'class' in rawService else
            serviceName)  # pylint: disable = invalid-name

        service = Service(serviceName, class_, arguments, tags)

        if 'autowire' in rawService:
            service.setAutowire(rawService['autowire'] is True)

        if 'factory' in rawService:
            if rawService['factory'][0][0:1] != '@':
                raise Exception(
                    'Factory service name must be prefixed with @ (service {})'
                    .format(serviceName))

            service.setFactory(ServiceArgument(rawService['factory'][0][1:]),
                               rawService['factory'][1])

        return service
Пример #16
0
    def resolve(self, inspectedArgument: InspectedArgument, serviceName: str,
                classes2Services: dict):
        moduleName = inspectedArgument.dtype.moduleName
        className = inspectedArgument.dtype.className

        if className == '_empty':
            raise Exception('Cannot resolve argument {} for service {}'.format(
                inspectedArgument.name, serviceName))

        if moduleName not in classes2Services:
            moduleNameStripped = moduleName[:moduleName.rfind('.')]

            if moduleNameStripped in classes2Services:
                raise Exception(
                    'Consider changing service dtype from {} -> {} (invalid dtype)'
                    .format(moduleNameStripped + '.' + className,
                            moduleName + '.' + className))

            raise Exception('Service not found for {} used in {}'.format(
                moduleName + '.' + className, serviceName))

        if className not in classes2Services[moduleName]:
            raise Exception('Service not found for {} used in {}'.format(
                moduleName + '.' + className, serviceName))

        if len(classes2Services[moduleName][className]) > 1:
            serviceNames = ', '.join(classes2Services[moduleName][className])
            raise Exception(
                'Multiple services of dtype {} in dtype {} defined ({}), dtype used in service {}'
                .format(className, moduleName, serviceNames, serviceName))

        return ServiceArgument(classes2Services[moduleName][className][0],
                               inspectedArgument.name)
Пример #17
0
    def test_named_arguments(self):
        resolved_arguments = [
            ResolvedArgument(
                "my_number", PrimitiveArgument(123, "my_number"),
                InspectedArgument("my_number", DType("builtins", "int"))),
            ResolvedArgument(
                "manually_wired_service",
                ServiceArgument("my.module.ManuallyWiredClass",
                                "manually_wired_service"),
                InspectedArgument(
                    "manually_wired_service",
                    DType("my.module.ManuallyWiredClass",
                          "ManuallyWiredClass")),
            ),
            ResolvedArgument(
                "autowired_service",
                None,
                InspectedArgument("autowired_service",
                                  DType("my.module.OtherClass", "OtherClass")),
            ),
        ]

        classes2_services = {
            "my.module.OtherClass": {
                "OtherClass": ["my.module.OtherClass"]
            }
        }

        new_resolved_arguments = self.__arguments_autowirer.autowire(
            "my.module.MyClass",
            resolved_arguments,
            classes2_services,
        )

        self.assertEqual(3, len(new_resolved_arguments))
        self.assertEqual(PrimitiveArgument(123, "my_number"),
                         new_resolved_arguments[0].argument)
        self.assertEqual(
            ServiceArgument("my.module.ManuallyWiredClass",
                            "manually_wired_service"),
            new_resolved_arguments[1].argument)
        self.assertEqual(
            ServiceArgument("my.module.OtherClass", "autowired_service"),
            new_resolved_arguments[2].argument)
Пример #18
0
    def resolve(self, resolvedArgument: ResolvedArgument, containerBuild: ContainerBuild):
        argument = resolvedArgument.argument

        if not isinstance(argument, TaggedServicesArgument):
            return resolvedArgument

        servicesForTag = containerBuild.getServicesByTag(argument.tagName)
        serviceArguments = list(map(lambda service: ServiceArgument(service.name), servicesForTag))

        resolvedArgument.modifyArgument(ListArgument(serviceArguments, argument.name), 'tags')
        return resolvedArgument
Пример #19
0
    def test_exception_object_for_string(self):
        with self.assertRaises(Exception) as error:
            self.__arguments_validator.validate(
                "injecta.mocks.Bar",
                [ResolvedArgument("name", ServiceArgument("injecta.mocks.Empty"), InspectedArgument("name", DType("builtins", "str")))],
                {"injecta.mocks.Empty": DType("injecta.mocks.Empty", "Empty")},
                {},
            )

        self.assertEqual(
            'Expected dtype "str", got "injecta.mocks.Empty.Empty" (argument "name", service "injecta.mocks.Bar")', str(error.exception)
        )
Пример #20
0
    def modify_services(self, services: List[Service],
                        aliases: List[ServiceAlias], parameters: Box):
        if is_running_in_console():
            aliases.append(
                ServiceAlias("databricksbundle.logger",
                             "consolebundle.logger"))
        else:
            service = Service("databricksbundle.logger",
                              DType("logging", "Logger"))
            service.set_factory(
                ServiceArgument(NotebookLoggerFactory.__module__), "create")

            services.append(service)

        return services, aliases
Пример #21
0
    def resolve(self, resolved_argument: ResolvedArgument,
                container_build: ContainerBuild):
        argument = resolved_argument.argument

        if not isinstance(argument, TaggedServicesArgument):
            return resolved_argument

        services_for_tag = container_build.get_services_by_tag(
            argument.tag_name)
        service_arguments = list(
            map(lambda service: ServiceArgument(service.name),
                services_for_tag))

        resolved_argument.modify_argument(
            ListArgument(service_arguments, argument.name), "tags")
        return resolved_argument
Пример #22
0
    def test_exceptionObjectForString(self):
        with self.assertRaises(Exception) as error:
            self.__argumentsValidator.validate(
                'injecta.mocks.Bar',
                [
                    ResolvedArgument(
                        'name', ServiceArgument('injecta.mocks.Empty'),
                        InspectedArgument('name', DType('builtins', 'str')))
                ],
                {'injecta.mocks.Empty': DType('injecta.mocks.Empty', 'Empty')},
                {},
            )

        self.assertEqual(
            'Expected dtype "str", got "injecta.mocks.Empty.Empty" (argument "name", service "injecta.mocks.Bar")',
            str(error.exception))
Пример #23
0
    def test_factory(self):
        result = self.__serviceParser.parse('injecta.api.ApiClient', {
            'factory': ['@injecta.api.ApiClientFactory.ApiClientFactory', 'create'],
            'arguments': [
                'Jirka',
            ]
        })
        expected = Service(
            'injecta.api.ApiClient',
            DType('injecta.api', 'ApiClient'),
            [
                PrimitiveArgument('Jirka'),
            ]
        )
        expected.setFactory(ServiceArgument('injecta.api.ApiClientFactory.ApiClientFactory'), 'create')

        self.assertEqual(expected, result)
Пример #24
0
        def autowireArgument(resolvedArgument: ResolvedArgument):
            if resolvedArgument.argument or resolvedArgument.inspectedArgument.hasDefaultValue(
            ):
                return resolvedArgument

            if resolvedArgument.inspectedArgument.dtype.moduleName == ContainerInterface.__module__:
                serviceArgument = ServiceArgument('serviceContainer',
                                                  resolvedArgument.name)
                resolvedArgument.modifyArgument(serviceArgument,
                                                'container autowiring')

                return resolvedArgument

            serviceArgument = self.__argumentResolver.resolve(
                resolvedArgument.inspectedArgument, serviceName,
                classes2Services)
            resolvedArgument.modifyArgument(serviceArgument, 'autowiring')

            return resolvedArgument
Пример #25
0
        def autowire_argument(resolved_argument: ResolvedArgument):
            if resolved_argument.argument or resolved_argument.inspected_argument.has_default_value(
            ):
                return resolved_argument

            if resolved_argument.inspected_argument.dtype.module_name == ContainerInterface.__module__:
                service_argument = ServiceArgument("service_container",
                                                   resolved_argument.name)
                resolved_argument.modify_argument(service_argument,
                                                  "container autowiring")

                return resolved_argument

            service_argument = self.__argument_resolver.resolve(
                resolved_argument.inspected_argument, service_name,
                classes2_services)
            resolved_argument.modify_argument(service_argument, "autowiring")

            return resolved_argument
Пример #26
0
    def test_basic(self):
        result = self.__service_parser.parse(
            "injecta.api.ApiClient_test",
            {
                "class": "injecta.api.ApiClient.ApiClient",
                "autowire": True,
                "arguments": ["Jirka", 15, False, "@injecta.api.Connector"]
            },
        )
        expected = Service(
            "injecta.api.ApiClient_test",
            DType("injecta.api.ApiClient", "ApiClient"),
            [
                PrimitiveArgument("Jirka"),
                PrimitiveArgument(15),
                PrimitiveArgument(False),
                ServiceArgument("injecta.api.Connector"),
            ],
        )
        expected.set_autowire(True)

        self.assertEqual(expected, result)
Пример #27
0
    def test_basic(self):
        rawServices = {
            'injecta.mocks.Bar.Bar': {
                'arguments': [
                    'Jiri Koutny'
                ]
            },
            'injecta.mocks.Foo.Foo': {
                'arguments': [
                    '@injecta.mocks.Bar.Bar'
                ]
            },
            'injecta.mocks.Bar.BarAlias': '@injecta.mocks.Bar.Bar',
        }

        expectedService1 = Service(
            'injecta.mocks.Bar.Bar',
            DType('injecta.mocks.Bar', 'Bar'),
            [
                PrimitiveArgument('Jiri Koutny'),
            ]
        )

        expectedService2 = Service(
            'injecta.mocks.Foo.Foo',
            DType('injecta.mocks.Foo', 'Foo'),
            [
                ServiceArgument('injecta.mocks.Bar.Bar'),
            ]
        )

        expectedAlias1 = ServiceAlias('injecta.mocks.Bar.BarAlias', 'injecta.mocks.Bar.Bar')

        services, aliases = self.__servicesPreparer.prepare(rawServices)

        self.assertEqual(expectedService1, services[0])
        self.assertEqual(expectedService2, services[1])
        self.assertEqual(expectedAlias1, aliases[0])
Пример #28
0
    def test_factory(self):
        result = self.__service_parser.parse(
            "injecta.api.ApiClient",
            {
                "factory":
                ["@injecta.api.ApiClientFactory.ApiClientFactory", "create"],
                "arguments": [
                    "Jirka",
                ],
            },
        )
        expected = Service(
            "injecta.api.ApiClient",
            DType("injecta.api", "ApiClient"),
            [
                PrimitiveArgument("Jirka"),
            ],
        )
        expected.set_factory(
            ServiceArgument("injecta.api.ApiClientFactory.ApiClientFactory"),
            "create")

        self.assertEqual(expected, result)
Пример #29
0
    def test_basic(self):
        result = self.__serviceParser.parse('injecta.api.ApiClient_test', {
            'class': 'injecta.api.ApiClient.ApiClient',
            'autowire': True,
            'arguments': [
                'Jirka',
                15,
                False,
                '@injecta.api.Connector'
            ]
        })
        expected = Service(
            'injecta.api.ApiClient_test',
            DType('injecta.api.ApiClient', 'ApiClient'),
            [
                PrimitiveArgument('Jirka'),
                PrimitiveArgument(15),
                PrimitiveArgument(False),
                ServiceArgument('injecta.api.Connector'),
            ]
        )
        expected.setAutowire(True)

        self.assertEqual(expected, result)
    def resolve(self, resolved_argument: ResolvedArgument, container_build: ContainerBuild):
        argument = resolved_argument.argument

        if not isinstance(argument, TaggedAliasedServiceArgument):
            return resolved_argument

        services_for_tag = container_build.get_services_by_tag(argument.tag_name)

        if isinstance(argument.tag_alias, str):
            tag_alias = self.__resolve_parameter_value(argument.tag_alias, container_build.parameters)
        else:
            tag_alias = argument.tag_alias

        for service in services_for_tag:
            tag_attributes = service.get_tag_attributes(argument.tag_name)

            if "alias" not in tag_attributes:
                raise Exception(f'"alias" attribute is missing for tag {argument.tag_name}')

            if tag_attributes["alias"] == tag_alias:
                resolved_argument.modify_argument(ServiceArgument(service.name, argument.name), "tagged_aliased")
                return resolved_argument

        raise Exception(f"No service tagged with {argument.tag_name} found for alias: {tag_alias}")