mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 16:07:51 +03:00 
			
		
		
		
	Improve resource subclasses typing and make shutdown definition optional (#492)
* Improve resource subclasses typing and make shutdown definition optional * Update mypy tests
This commit is contained in:
		
							parent
							
								
									83c2af0e7e
								
							
						
					
					
						commit
						36bfd2ed58
					
				|  | @ -1,7 +1,7 @@ | ||||||
| """Resources module.""" | """Resources module.""" | ||||||
| 
 | 
 | ||||||
| import abc | import abc | ||||||
| from typing import TypeVar, Generic | from typing import TypeVar, Generic, Optional | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| T = TypeVar('T') | T = TypeVar('T') | ||||||
|  | @ -10,20 +10,18 @@ T = TypeVar('T') | ||||||
| class Resource(Generic[T], metaclass=abc.ABCMeta): | class Resource(Generic[T], metaclass=abc.ABCMeta): | ||||||
| 
 | 
 | ||||||
|     @abc.abstractmethod |     @abc.abstractmethod | ||||||
|     def init(self, *args, **kwargs) -> T: |     def init(self, *args, **kwargs) -> Optional[T]: | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
|     @abc.abstractmethod |     def shutdown(self, resource: Optional[T]) -> None: | ||||||
|     def shutdown(self, resource: T) -> None: |  | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AsyncResource(Generic[T], metaclass=abc.ABCMeta): | class AsyncResource(Generic[T], metaclass=abc.ABCMeta): | ||||||
| 
 | 
 | ||||||
|     @abc.abstractmethod |     @abc.abstractmethod | ||||||
|     async def init(self, *args, **kwargs) -> T: |     async def init(self, *args, **kwargs) -> Optional[T]: | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
|     @abc.abstractmethod |     async def shutdown(self, resource: Optional[T]) -> None: | ||||||
|     async def shutdown(self, resource: T) -> None: |  | ||||||
|         ... |         ... | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| from typing import List, Iterator, Generator, AsyncIterator, AsyncGenerator | from typing import List, Iterator, Generator, AsyncIterator, AsyncGenerator, Optional | ||||||
| 
 | 
 | ||||||
| from dependency_injector import providers, resources | from dependency_injector import providers, resources | ||||||
| 
 | 
 | ||||||
|  | @ -35,7 +35,7 @@ class MyResource4(resources.Resource[List[int]]): | ||||||
|     def init(self, *args, **kwargs) -> List[int]: |     def init(self, *args, **kwargs) -> List[int]: | ||||||
|         return [] |         return [] | ||||||
| 
 | 
 | ||||||
|     def shutdown(self, resource: List[int]) -> None: |     def shutdown(self, resource: Optional[List[int]]) -> None: | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -87,7 +87,7 @@ class MyResource8(resources.AsyncResource[List[int]]): | ||||||
|     async def init(self, *args, **kwargs) -> List[int]: |     async def init(self, *args, **kwargs) -> List[int]: | ||||||
|         return [] |         return [] | ||||||
| 
 | 
 | ||||||
|     async def shutdown(self, resource: List[int]) -> None: |     async def shutdown(self, resource: Optional[List[int]]) -> None: | ||||||
|         ... |         ... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| """Dependency injector resource provider unit tests.""" | """Dependency injector resource provider unit tests.""" | ||||||
| 
 | 
 | ||||||
| import asyncio | import asyncio | ||||||
|  | import inspect | ||||||
| import unittest | import unittest | ||||||
| from typing import Any | from typing import Any | ||||||
| 
 | 
 | ||||||
|  | @ -158,7 +159,7 @@ class ResourceTests(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|         self.assertTrue(issubclass(TestResource, resources.Resource)) |         self.assertTrue(issubclass(TestResource, resources.Resource)) | ||||||
| 
 | 
 | ||||||
|     def test_init_class_abc_definition_is_required(self): |     def test_init_class_abc_init_definition_is_required(self): | ||||||
|         class TestResource(resources.Resource): |         class TestResource(resources.Resource): | ||||||
|             ... |             ... | ||||||
| 
 | 
 | ||||||
|  | @ -166,19 +167,13 @@ class ResourceTests(unittest.TestCase): | ||||||
|             TestResource() |             TestResource() | ||||||
| 
 | 
 | ||||||
|         self.assertIn("Can't instantiate abstract class TestResource", str(context.exception)) |         self.assertIn("Can't instantiate abstract class TestResource", str(context.exception)) | ||||||
|         self.assertIn("init, shutdown", str(context.exception)) |         self.assertIn("init", str(context.exception)) | ||||||
| 
 | 
 | ||||||
| 
 |     def test_init_class_abc_shutdown_definition_is_not_required(self): | ||||||
|     def test_init_class_abc_shutdown_definition_is_required(self): |  | ||||||
|         class TestResource(resources.Resource): |         class TestResource(resources.Resource): | ||||||
|             def init(self): |             def init(self): | ||||||
|                 ... |                 ... | ||||||
| 
 |         self.assertTrue(hasattr(TestResource(), 'shutdown')) | ||||||
|         with self.assertRaises(TypeError) as context: |  | ||||||
|             TestResource() |  | ||||||
| 
 |  | ||||||
|         self.assertIn("Can't instantiate abstract class TestResource", str(context.exception)) |  | ||||||
|         self.assertIn("shutdown", str(context.exception)) |  | ||||||
| 
 | 
 | ||||||
|     def test_init_not_callable(self): |     def test_init_not_callable(self): | ||||||
|         provider = providers.Resource(1) |         provider = providers.Resource(1) | ||||||
|  | @ -497,7 +492,7 @@ class AsyncResourceTest(AsyncTestCase): | ||||||
| 
 | 
 | ||||||
|         self.assertTrue(issubclass(TestAsyncResource, resources.AsyncResource)) |         self.assertTrue(issubclass(TestAsyncResource, resources.AsyncResource)) | ||||||
| 
 | 
 | ||||||
|     def test_init_async_class_abc_definition_is_required(self): |     def test_init_async_class_abc_init_definition_is_required(self): | ||||||
|         class TestAsyncResource(resources.AsyncResource): |         class TestAsyncResource(resources.AsyncResource): | ||||||
|             ... |             ... | ||||||
| 
 | 
 | ||||||
|  | @ -505,18 +500,14 @@ class AsyncResourceTest(AsyncTestCase): | ||||||
|             TestAsyncResource() |             TestAsyncResource() | ||||||
| 
 | 
 | ||||||
|         self.assertIn("Can't instantiate abstract class TestAsyncResource", str(context.exception)) |         self.assertIn("Can't instantiate abstract class TestAsyncResource", str(context.exception)) | ||||||
|         self.assertIn("init, shutdown", str(context.exception)) |         self.assertIn("init", str(context.exception)) | ||||||
| 
 | 
 | ||||||
|     def test_init_async_class_abc_shutdown_definition_is_required(self): |     def test_init_async_class_abc_shutdown_definition_is_not_required(self): | ||||||
|         class TestAsyncResource(resources.AsyncResource): |         class TestAsyncResource(resources.AsyncResource): | ||||||
|             async def init(self): |             async def init(self): | ||||||
|                 ... |                 ... | ||||||
| 
 |         self.assertTrue(hasattr(TestAsyncResource(), 'shutdown')) | ||||||
|         with self.assertRaises(TypeError) as context: |         self.assertTrue(inspect.iscoroutinefunction(TestAsyncResource.shutdown)) | ||||||
|             TestAsyncResource() |  | ||||||
| 
 |  | ||||||
|         self.assertIn("Can't instantiate abstract class TestAsyncResource", str(context.exception)) |  | ||||||
|         self.assertIn("shutdown", str(context.exception)) |  | ||||||
| 
 | 
 | ||||||
|     def test_init_with_error(self): |     def test_init_with_error(self): | ||||||
|         async def _init(): |         async def _init(): | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user