






from importlib import import_module

from .logging import get_logger


SCREAMING_SNAKE_CASE__		:							Union[str, Any] 				=				get_logger(__name__)







class 				UpperCAmelCase_  :




     def __init__(				self	,						_lowerCAmelCase	,						_lowerCAmelCase=None		):
          UpperCAmelCase__      :  List[str]				      =			attrs or []
          if module is not None:
               for key in module.__dict__:
                    if key in attrs or not key.startswith("""__"""		):
                         setattr(self	,						_lowerCAmelCase	,						getattr(_lowerCAmelCase	,						_lowerCAmelCase		)		)
          UpperCAmelCase__      :  Tuple				      =			module._original_module if isinstance(_lowerCAmelCase	,						_PatchedModuleObj		) else module







class 				UpperCAmelCase_  :
     __lowerCamelCase      				=  []




     def __init__(				self	,						_lowerCAmelCase	,						_lowerCAmelCase	,						_lowerCAmelCase	,						_lowerCAmelCase=None		):
          UpperCAmelCase__      :  str				      =			obj
          UpperCAmelCase__      :  List[str]				      =			target
          UpperCAmelCase__      :  List[str]				      =			new
          UpperCAmelCase__      :  Any				      =			target.split("""."""		)[0]
          UpperCAmelCase__      :  Union[str, Any]				      =			{}
          UpperCAmelCase__      :  str				      =			attrs or []




     def __enter__(				self		):
          *UpperCAmelCase__      ,		UpperCAmelCase__      :  List[Any]				      =			self.target.split("""."""		)

          # Patch modules:
          # it's used to patch attributes of submodules like "os.path.join";
          # in this case we need to patch "os" and "os.path"

          for i in range(len(_lowerCAmelCase		)		):
               try:
                    UpperCAmelCase__      :  Optional[int]				      =			import_module(""".""".join(submodules[: i + 1]		)		)
               except ModuleNotFoundError:
                    continue
               # We iterate over all the globals in self.obj in case we find "os" or "os.path"
               for attr in self.obj.__dir__():
                    UpperCAmelCase__      :  Any				      =			getattr(self.obj	,						_lowerCAmelCase		)
                    # We don't check for the name of the global, but rather if its value *is* "os" or "os.path".
                    # This allows to patch renamed modules like "from os import path as ospath".
                    if obj_attr is submodule or (
                        (isinstance(_lowerCAmelCase	,						_PatchedModuleObj		) and obj_attr._original_module is submodule)
                    ):
                         UpperCAmelCase__      :  List[Any]				      =			obj_attr
                         # patch at top level
                         setattr(self.obj	,						_lowerCAmelCase	,						_PatchedModuleObj(_lowerCAmelCase	,						attrs=self.attrs		)		)
                         UpperCAmelCase__      :  Optional[Any]				      =			getattr(self.obj	,						_lowerCAmelCase		)
                         # construct lower levels patches
                         for key in submodules[i + 1 :]:
                              setattr(_lowerCAmelCase	,						_lowerCAmelCase	,						_PatchedModuleObj(getattr(_lowerCAmelCase	,						_lowerCAmelCase	,						_lowerCAmelCase		)	,						attrs=self.attrs		)		)
                              UpperCAmelCase__      :  Union[str, Any]				      =			getattr(_lowerCAmelCase	,						_lowerCAmelCase		)
                         # finally set the target attribute
                         setattr(_lowerCAmelCase	,						_lowerCAmelCase	,						self.new		)

        # Patch attribute itself:
        # it's used for builtins like "open",
        # and also to patch "os.path.join" we may also need to patch "join"
        # itself if it was imported as "from os.path import join".

          if submodules:  # if it's an attribute of a submodule like "os.path.join"
               try:
                    UpperCAmelCase__      :  Union[str, Any]				      =			getattr(import_module(""".""".join(_lowerCAmelCase		)		)	,						_lowerCAmelCase		)
               except (AttributeError, ModuleNotFoundError):
                    return
               # We iterate over all the globals in self.obj in case we find "os.path.join"
               for attr in self.obj.__dir__():
                    # We don't check for the name of the global, but rather if its value *is* "os.path.join".
                    # This allows to patch renamed attributes like "from os.path import join as pjoin".
                    if getattr(self.obj	,						_lowerCAmelCase		) is attr_value:
                         UpperCAmelCase__      :  Optional[int]				      =			getattr(self.obj	,						_lowerCAmelCase		)
                         setattr(self.obj	,						_lowerCAmelCase	,						self.new		)
          elif target_attr in globals()["__builtins__"]:  # if it'a s builtin like "open"
               UpperCAmelCase__      :  Dict				      =			globals()["""__builtins__"""][target_attr]
               setattr(self.obj	,						_lowerCAmelCase	,						self.new		)
          else:
               raise RuntimeError(f"Tried to patch attribute {target_attr} instead of a submodule."		)




     def __exit__(				self	,						*_lowerCAmelCase		):
          for attr in list(self.original		):
               setattr(self.obj	,						_lowerCAmelCase	,						self.original.pop(_lowerCAmelCase		)		)




     def   __UpperCAmelCase  (				self		):
          self.__enter__()
          self._active_patches.append(self		)




     def   __UpperCAmelCase  (				self		):
          try:
               self._active_patches.remove(self		)
          except ValueError:
               # If the patch hasn't been started this will fail
               return None

          return self.__exit__()











'''simple docstring'''





from abc import ABC, abstractmethod
from argparse import ArgumentParser



class  snake_case__						(    SCREAMING_SNAKE_CASE_				):
 @staticmethod
 @abstractmethod
 def A_   (   __a						:							ArgumentParser  )      ->   List[str]:







       '''simple docstring'''
       raise NotImplementedError()





 @abstractmethod
 def A_   (   self						:							Optional[Any]  )      ->   Optional[Any]:







       '''simple docstring'''
       raise NotImplementedError()



