| |
| import copy |
| import time |
| from contextlib import contextmanager |
| from typing import Generator, Optional |
|
|
| from mmengine.utils.manager import ManagerMixin, _accquire_lock, _release_lock |
|
|
|
|
| class DefaultScope(ManagerMixin): |
| """Scope of current task used to reset the current registry, which can be |
| accessed globally. |
| |
| Consider the case of resetting the current ``Registry`` by |
| ``default_scope`` in the internal module which cannot access runner |
| directly, it is difficult to get the ``default_scope`` defined in |
| ``Runner``. However, if ``Runner`` created ``DefaultScope`` instance |
| by given ``default_scope``, the internal module can get |
| ``default_scope`` by ``DefaultScope.get_current_instance`` everywhere. |
| |
| Args: |
| name (str): Name of default scope for global access. |
| scope_name (str): Scope of current task. |
| |
| Examples: |
| >>> from mmengine.model import MODELS |
| >>> # Define default scope in runner. |
| >>> DefaultScope.get_instance('task', scope_name='mmdet') |
| >>> # Get default scope globally. |
| >>> scope_name = DefaultScope.get_instance('task').scope_name |
| """ |
|
|
| def __init__(self, name: str, scope_name: str): |
| super().__init__(name) |
| assert isinstance( |
| scope_name, |
| str), (f'scope_name should be a string, but got {scope_name}') |
| self._scope_name = scope_name |
|
|
| @property |
| def scope_name(self) -> str: |
| """ |
| Returns: |
| str: Get current scope. |
| """ |
| return self._scope_name |
|
|
| @classmethod |
| def get_current_instance(cls) -> Optional['DefaultScope']: |
| """Get latest created default scope. |
| |
| Since default_scope is an optional argument for ``Registry.build``. |
| ``get_current_instance`` should return ``None`` if there is no |
| ``DefaultScope`` created. |
| |
| Examples: |
| >>> default_scope = DefaultScope.get_current_instance() |
| >>> # There is no `DefaultScope` created yet, |
| >>> # `get_current_instance` return `None`. |
| >>> default_scope = DefaultScope.get_instance( |
| >>> 'instance_name', scope_name='mmengine') |
| >>> default_scope.scope_name |
| mmengine |
| >>> default_scope = DefaultScope.get_current_instance() |
| >>> default_scope.scope_name |
| mmengine |
| |
| Returns: |
| Optional[DefaultScope]: Return None If there has not been |
| ``DefaultScope`` instance created yet, otherwise return the |
| latest created DefaultScope instance. |
| """ |
| _accquire_lock() |
| if cls._instance_dict: |
| instance = super().get_current_instance() |
| else: |
| instance = None |
| _release_lock() |
| return instance |
|
|
| @classmethod |
| @contextmanager |
| def overwrite_default_scope(cls, scope_name: Optional[str]) -> Generator: |
| """overwrite the current default scope with `scope_name`""" |
| if scope_name is None: |
| yield |
| else: |
| tmp = copy.deepcopy(cls._instance_dict) |
| |
| time.sleep(1e-6) |
| cls.get_instance(f'overwrite-{time.time()}', scope_name=scope_name) |
| try: |
| yield |
| finally: |
| cls._instance_dict = tmp |
|
|