




# Lint as: python3
import dataclasses
import re
from dataclasses import dataclass
from functools import total_ordering
from typing import Optional, Union


__lowerCAmelCase		:				str       			=		re.compile(r'^(?P<major>\d+)' r'\.(?P<minor>\d+)' r'\.(?P<patch>\d+)$')




@total_ordering
@dataclass
class     snake_case__							:
				"""simple docstring"""



				SCREAMING_SNAKE_CASE_       :							str
				SCREAMING_SNAKE_CASE_       :							Optional[str]							 =					None
				SCREAMING_SNAKE_CASE_       :							Optional[Union[str, int]]							 =					None
				SCREAMING_SNAKE_CASE_       :							Optional[Union[str, int]]							 =					None
				SCREAMING_SNAKE_CASE_       :							Optional[Union[str, int]]							 =					None





				def 							__UpperCAmelCase							(      self				:     Tuple							)					->     Optional[Any]:
							a    ,		a    ,		a    =			_str_to_version_tuple(self.version_str							)





				def __repr__(      self				:     List[str]							)					->     Dict:
							return f"""{self.tuple[0]}.{self.tuple[1]}.{self.tuple[2]}"""





				@property
				def 							__UpperCAmelCase							(      self				:     Tuple							)					->     Any:
							return self.major, self.minor, self.patch





				def 							__UpperCAmelCase							(      self				:     List[str]					,      __lowerCamelCase				:     Optional[int]							)					->     Optional[Any]:
							if isinstance(__lowerCamelCase					,      __lowerCamelCase							):
										return Version(__lowerCamelCase							)
							elif isinstance(__lowerCamelCase					,      __lowerCamelCase							):
										return other
							raise TypeError(f"""{other} (type {type(__lowerCamelCase							)}) cannot be compared to version."""							)





				def __eq__(      self				:     int					,      __lowerCamelCase				:     Any							)					->     Optional[int]:
							try:
										a    =			self._validate_operand(__lowerCamelCase							)
							except (TypeError, ValueError):
										return False
							else:
										return self.tuple == other.tuple





				def __lt__(      self				:     Optional[Any]					,      __lowerCamelCase				:     Union[str, Any]							)					->     Dict:
							a    =			self._validate_operand(__lowerCamelCase							)
							return self.tuple < other.tuple





				def __hash__(      self				:     Any							)					->     Optional[Any]:
							return hash(_version_tuple_to_str(self.tuple							)							)





				@classmethod
				def 							__UpperCAmelCase							(      cls				:     Optional[Any]					,      __lowerCamelCase				:     Dict							)					->     Any:
							a    =			{f.name for f in dataclasses.fields(cls							)}
							return cls(**{k: v for k, v in dic.items() if k in field_names}							)





				def 							__UpperCAmelCase							(      self				:     List[Any]							)					->     str:
							return self.version_str




def 			__magic_name__				( A		:					Optional[int]   ):






			'''simple docstring'''







			a    =			_VERSION_REG.match(A   )
			if not res:
						raise ValueError(F"""Invalid version '{version_str}'. Format should be x.y.z with {{x,y,z}} being digits."""   )
			return tuple(int(A   ) for v in [res.group("major"   ), res.group("minor"   ), res.group("patch"   )]   )






def 			__magic_name__				( A		:					Optional[Any]   ):






			'''simple docstring'''







			return ".".join(str(A   ) for v in version_tuple   )










'''simple docstring'''



from importlib import import_module

from .logging import get_logger


A__		:					str												=  get_logger(__name__)





class    UpperCAmelCase_  :





    """simple docstring"""






    def __init__(							self			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_=None	)				->     List[Any]:
         __lowerCamelCase   :	List[str]								=		attrs or []
         if module is not None:
              for key in module.__dict__:
                   if key in attrs or not key.startswith('__'	):
                        setattr(self			,     SCREAMING_SNAKE_CASE_			,     getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)	)
         __lowerCamelCase   :	Optional[int]								=		module._original_module if isinstance(SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj	) else module







class    UpperCAmelCase_  :





    """simple docstring"""






    lowerCamelCase  :					Tuple							     =			[]







    def __init__(							self			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_=None	)				->     Union[str, Any]:
         __lowerCamelCase   :	Optional[int]								=		obj
         __lowerCamelCase   :	List[Any]								=		target
         __lowerCamelCase   :	Union[str, Any]								=		new
         __lowerCamelCase   :	Union[str, Any]								=		target.split('.'	)[0]
         __lowerCamelCase   :	Dict								=		{}
         __lowerCamelCase   :	Dict								=		attrs or []







    def __enter__(							self	)				->     Optional[int]:
         *__lowerCamelCase				,       __lowerCamelCase   :	int								=		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(SCREAMING_SNAKE_CASE_	)	):
              try:
                   __lowerCamelCase   :	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__():
                   __lowerCamelCase   :	List[Any]								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                   # 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(SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj	) and obj_attr._original_module is submodule)
                   ):
                        __lowerCamelCase   :	Optional[Any]								=		obj_attr
                        # patch at top level
                        setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj(SCREAMING_SNAKE_CASE_			,     attrs=self.attrs	)	)
                        __lowerCamelCase   :	str								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                        # construct lower levels patches
                        for key in submodules[i + 1 :]:
                             setattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj(getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)			,     attrs=self.attrs	)	)
                             __lowerCamelCase   :	List[Any]								=		getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)
                        # finally set the target attribute
                        setattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     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:
                   __lowerCamelCase   :	Union[str, Any]								=		getattr(import_module('.'.join(SCREAMING_SNAKE_CASE_	)	)			,     SCREAMING_SNAKE_CASE_	)
              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			,     SCREAMING_SNAKE_CASE_	) is attr_value:
                        __lowerCamelCase   :	Optional[int]								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                        setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.new	)
         elif target_attr in globals()["__builtins__"]:  # if it'a s builtin like "open"
              __lowerCamelCase   :	List[Any]								=		globals()['__builtins__'][target_attr]
              setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.new	)
         else:
              raise RuntimeError(f'Tried to patch attribute {target_attr} instead of a submodule.'	)







    def __exit__(							self			,     *SCREAMING_SNAKE_CASE_	)				->     Optional[Any]:
         for attr in list(self.original	):
              setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.original.pop(SCREAMING_SNAKE_CASE_	)	)







    def       lowercase_				(							self	)				->     Optional[int]:
         self.__enter__()
         self._active_patches.append(self	)







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

         return self.__exit__()






