mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 07:57:43 +03:00 
			
		
		
		
	Implement from_*() methods and add tests
This commit is contained in:
		
							parent
							
								
									3c3c6def6d
								
							
						
					
					
						commit
						73d9c97c1b
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -51,8 +51,8 @@ class Container: | ||||||
|     def reset_singletons(self) -> SingletonResetContext[C_Base]: ... |     def reset_singletons(self) -> SingletonResetContext[C_Base]: ... | ||||||
|     def check_dependencies(self) -> None: ... |     def check_dependencies(self) -> None: ... | ||||||
|     def from_schema(self, schema: Dict[Any, Any]) -> None: ... |     def from_schema(self, schema: Dict[Any, Any]) -> None: ... | ||||||
|     def from_yaml_schema(self, filepath: Union[Path, str]) -> None: |     def from_yaml_schema(self, filepath: Union[Path, str], loader: Optional[Any]=None) -> None: ... | ||||||
|     def from_json_schema(self, filepath: Union[Path, str]) -> None: |     def from_json_schema(self, filepath: Union[Path, str]) -> None: ... | ||||||
|     @overload |     @overload | ||||||
|     def resolve_provider_name(self, provider: Provider) -> str: ... |     def resolve_provider_name(self, provider: Provider) -> str: ... | ||||||
|     @classmethod |     @classmethod | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| """Containers module.""" | """Containers module.""" | ||||||
| 
 | 
 | ||||||
|  | import json | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|  | @ -7,6 +8,11 @@ try: | ||||||
| except ImportError: | except ImportError: | ||||||
|     asyncio = None |     asyncio = None | ||||||
| 
 | 
 | ||||||
|  | try: | ||||||
|  |     import yaml | ||||||
|  | except ImportError: | ||||||
|  |     yaml = None | ||||||
|  | 
 | ||||||
| import six | import six | ||||||
| 
 | 
 | ||||||
| from . import providers, errors | from . import providers, errors | ||||||
|  | @ -336,15 +342,32 @@ class DynamicContainer(Container): | ||||||
|         for name, provider in build_schema(schema).items(): |         for name, provider in build_schema(schema).items(): | ||||||
|             self.set_provider(name, provider) |             self.set_provider(name, provider) | ||||||
| 
 | 
 | ||||||
|     def from_yaml_schema(self, filepath): |     def from_yaml_schema(self, filepath, loader=None): | ||||||
|         """Build container providers from YAML file schema.""" |         """Build container providers from YAML schema. | ||||||
|         # TODO | 
 | ||||||
|         ... |         You can specify type of loader as a second argument. By default, method | ||||||
|  |         uses ``SafeLoader``. | ||||||
|  |         """ | ||||||
|  |         if yaml is None: | ||||||
|  |             raise errors.Error( | ||||||
|  |                 'Unable to load yaml schema - PyYAML is not installed. ' | ||||||
|  |                 'Install PyYAML or install Dependency Injector with yaml extras: ' | ||||||
|  |                 '"pip install dependency-injector[yaml]"' | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         if loader is None: | ||||||
|  |             loader = yaml.SafeLoader | ||||||
|  | 
 | ||||||
|  |         with open(filepath) as file: | ||||||
|  |             schema = yaml.load(file, loader) | ||||||
|  | 
 | ||||||
|  |         self.from_schema(schema) | ||||||
| 
 | 
 | ||||||
|     def from_json_schema(self, filepath): |     def from_json_schema(self, filepath): | ||||||
|         """Build container providers from JSON file schema.""" |         """Build container providers from JSON schema.""" | ||||||
|         # TODO |         with open(filepath) as file: | ||||||
|         ... |             schema = json.load(file) | ||||||
|  |         self.from_schema(schema) | ||||||
| 
 | 
 | ||||||
|     def resolve_provider_name(self, provider): |     def resolve_provider_name(self, provider): | ||||||
|         """Try to resolve provider name.""" |         """Try to resolve provider name.""" | ||||||
|  |  | ||||||
|  | @ -59,9 +59,14 @@ def _setup_injections( | ||||||
|         arg_injections = data.get('args') |         arg_injections = data.get('args') | ||||||
|         if arg_injections: |         if arg_injections: | ||||||
|             for arg in arg_injections: |             for arg in arg_injections: | ||||||
|  |                 injection = None | ||||||
|  | 
 | ||||||
|  |                 if isinstance(arg, str): | ||||||
|                     injection = _resolve_provider(container, arg) |                     injection = _resolve_provider(container, arg) | ||||||
|  | 
 | ||||||
|                 if not injection: |                 if not injection: | ||||||
|                     injection = arg |                     injection = arg | ||||||
|  | 
 | ||||||
|                 args.append(injection) |                 args.append(injection) | ||||||
|         if args: |         if args: | ||||||
|             provider.add_args(*args) |             provider.add_args(*args) | ||||||
|  | @ -69,9 +74,14 @@ def _setup_injections( | ||||||
|         kwarg_injections = data.get('kwargs') |         kwarg_injections = data.get('kwargs') | ||||||
|         if kwarg_injections: |         if kwarg_injections: | ||||||
|             for name, arg in kwarg_injections.items(): |             for name, arg in kwarg_injections.items(): | ||||||
|  |                 injection = None | ||||||
|  | 
 | ||||||
|  |                 if isinstance(arg, str): | ||||||
|                     injection = _resolve_provider(container, arg) |                     injection = _resolve_provider(container, arg) | ||||||
|  | 
 | ||||||
|                 if not injection: |                 if not injection: | ||||||
|                     injection = arg |                     injection = arg | ||||||
|  | 
 | ||||||
|                 kwargs[name] = injection |                 kwargs[name] = injection | ||||||
|         if kwargs: |         if kwargs: | ||||||
|             provider.add_kwargs(**kwargs) |             provider.add_kwargs(**kwargs) | ||||||
|  | @ -112,7 +122,7 @@ def _get_provider_cls(provider_cls_name: str) -> Type[providers.Provider]: | ||||||
|     if custom_provider_type: |     if custom_provider_type: | ||||||
|         return custom_provider_type |         return custom_provider_type | ||||||
| 
 | 
 | ||||||
|     raise SchemaError(f'Undefined provider class: "{provider_cls_name}"') |     raise SchemaError(f'Undefined provider class "{provider_cls_name}"') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def _fetch_provider_cls_from_std(provider_cls_name: str) -> Optional[Type[providers.Provider]]: | def _fetch_provider_cls_from_std(provider_cls_name: str) -> Optional[Type[providers.Provider]]: | ||||||
|  | @ -134,7 +144,16 @@ def _import_provider_cls(provider_cls_name: str) -> Optional[Type[providers.Prov | ||||||
| 
 | 
 | ||||||
| def _import_string(string_name: str) -> Optional[object]: | def _import_string(string_name: str) -> Optional[object]: | ||||||
|     segments = string_name.split('.') |     segments = string_name.split('.') | ||||||
|  | 
 | ||||||
|  |     if len(segments) == 1: | ||||||
|  |         member = __builtins__.get(segments[0]) | ||||||
|  |         if member: | ||||||
|  |             return member | ||||||
|  | 
 | ||||||
|     module_name = '.'.join(segments[:-1]) |     module_name = '.'.join(segments[:-1]) | ||||||
|  |     if not module_name: | ||||||
|  |         return None | ||||||
|  | 
 | ||||||
|     member = segments[-1] |     member = segments[-1] | ||||||
|     module = importlib.import_module(module_name) |     module = importlib.import_module(module_name) | ||||||
|     return getattr(module, member, None) |     return getattr(module, member, None) | ||||||
|  |  | ||||||
							
								
								
									
										162
									
								
								tests/unit/schema/test_containers_api_py36.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								tests/unit/schema/test_containers_api_py36.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,162 @@ | ||||||
|  | import contextlib | ||||||
|  | import json | ||||||
|  | import os.path | ||||||
|  | import tempfile | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | import yaml | ||||||
|  | from dependency_injector import containers, providers, errors | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FromSchemaTests(unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     def test(self): | ||||||
|  |         container = containers.DynamicContainer() | ||||||
|  |         container.from_schema( | ||||||
|  |             { | ||||||
|  |                 'version': '1', | ||||||
|  |                 'providers': { | ||||||
|  |                     'provider1': { | ||||||
|  |                         'provider': 'Factory', | ||||||
|  |                         'provides': 'list', | ||||||
|  |                         'args': [1, 2, 3], | ||||||
|  |                     }, | ||||||
|  |                     'provider2': { | ||||||
|  |                         'provider': 'Factory', | ||||||
|  |                         'provides': 'dict', | ||||||
|  |                         'kwargs': { | ||||||
|  |                             'one': 'provider1', | ||||||
|  |                             'two': 2, | ||||||
|  |                         }, | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|  |             }, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider1, providers.Factory) | ||||||
|  |         self.assertIs(container.provider1.provides, list) | ||||||
|  |         self.assertEqual(container.provider1.args, (1, 2, 3)) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider2, providers.Factory) | ||||||
|  |         self.assertIs(container.provider2.provides, dict) | ||||||
|  |         self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FromYamlSchemaTests(unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     def test(self): | ||||||
|  |         container = containers.DynamicContainer() | ||||||
|  | 
 | ||||||
|  |         with tempfile.TemporaryDirectory() as tmp_dir: | ||||||
|  |             schema_path = os.path.join(tmp_dir, 'schema.yml') | ||||||
|  |             with open(schema_path, 'w') as file: | ||||||
|  |                 file.write(""" | ||||||
|  |                 version: "1" | ||||||
|  |                 providers: | ||||||
|  |                   provider1: | ||||||
|  |                     provider: Factory | ||||||
|  |                     provides: list | ||||||
|  |                     args: | ||||||
|  |                       - 1 | ||||||
|  |                       - 2 | ||||||
|  |                       - 3 | ||||||
|  |                   provider2: | ||||||
|  |                     provider: Factory | ||||||
|  |                     provides: dict | ||||||
|  |                     kwargs: | ||||||
|  |                       one: provider1 | ||||||
|  |                       two: 2 | ||||||
|  |                 """) | ||||||
|  | 
 | ||||||
|  |             container.from_yaml_schema(schema_path) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider1, providers.Factory) | ||||||
|  |         self.assertIs(container.provider1.provides, list) | ||||||
|  |         self.assertEqual(container.provider1.args, (1, 2, 3)) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider2, providers.Factory) | ||||||
|  |         self.assertIs(container.provider2.provides, dict) | ||||||
|  |         self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2}) | ||||||
|  | 
 | ||||||
|  |     def test_with_loader(self): | ||||||
|  |         container = containers.DynamicContainer() | ||||||
|  | 
 | ||||||
|  |         with tempfile.TemporaryDirectory() as tmp_dir: | ||||||
|  |             schema_path = os.path.join(tmp_dir, 'schema.yml') | ||||||
|  |             with open(schema_path, 'w') as file: | ||||||
|  |                 file.write(""" | ||||||
|  |                 version: "1" | ||||||
|  |                 providers: | ||||||
|  |                   provider: | ||||||
|  |                     provider: Factory | ||||||
|  |                     provides: list | ||||||
|  |                     args: [1, 2, 3] | ||||||
|  |                 """) | ||||||
|  | 
 | ||||||
|  |             container.from_yaml_schema(schema_path, loader=yaml.Loader) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider, providers.Factory) | ||||||
|  |         self.assertIs(container.provider.provides, list) | ||||||
|  |         self.assertEqual(container.provider.args, (1, 2, 3)) | ||||||
|  | 
 | ||||||
|  |     def test_no_yaml_installed(self): | ||||||
|  |         @contextlib.contextmanager | ||||||
|  |         def no_yaml_module(): | ||||||
|  |             containers.yaml = None | ||||||
|  |             yield | ||||||
|  |             containers.yaml = yaml | ||||||
|  | 
 | ||||||
|  |         container = containers.DynamicContainer() | ||||||
|  |         with no_yaml_module(): | ||||||
|  |             with self.assertRaises(errors.Error) as error: | ||||||
|  |                 container.from_yaml_schema('./no-yaml-installed.yml') | ||||||
|  | 
 | ||||||
|  |         self.assertEqual( | ||||||
|  |             error.exception.args[0], | ||||||
|  |             'Unable to load yaml schema - PyYAML is not installed. ' | ||||||
|  |             'Install PyYAML or install Dependency Injector with yaml extras: ' | ||||||
|  |             '"pip install dependency-injector[yaml]"', | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class FromJsonSchemaTests(unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     def test(self): | ||||||
|  |         container = containers.DynamicContainer() | ||||||
|  | 
 | ||||||
|  |         with tempfile.TemporaryDirectory() as tmp_dir: | ||||||
|  |             schema_path = os.path.join(tmp_dir, 'schema.json') | ||||||
|  |             with open(schema_path, 'w') as file: | ||||||
|  |                 file.write( | ||||||
|  |                     json.dumps( | ||||||
|  |                         { | ||||||
|  |                             'version': '1', | ||||||
|  |                             'providers': { | ||||||
|  |                                 'provider1': { | ||||||
|  |                                     'provider': 'Factory', | ||||||
|  |                                     'provides': 'list', | ||||||
|  |                                     'args': [1, 2, 3], | ||||||
|  |                                 }, | ||||||
|  |                                 'provider2': { | ||||||
|  |                                     'provider': 'Factory', | ||||||
|  |                                     'provides': 'dict', | ||||||
|  |                                     'kwargs': { | ||||||
|  |                                         'one': 'provider1', | ||||||
|  |                                         'two': 2, | ||||||
|  |                                     }, | ||||||
|  |                                 }, | ||||||
|  |                             }, | ||||||
|  |                         }, | ||||||
|  |                         indent=4, | ||||||
|  |                     ), | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |             container.from_json_schema(schema_path) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider1, providers.Factory) | ||||||
|  |         self.assertIs(container.provider1.provides, list) | ||||||
|  |         self.assertEqual(container.provider1.args, (1, 2, 3)) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(container.provider2, providers.Factory) | ||||||
|  |         self.assertIs(container.provider2.provides, dict) | ||||||
|  |         self.assertEqual(container.provider2.kwargs, {'one': container.provider1, 'two': 2}) | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user