





import enum
import inspect
from typing import Iterable, List, Optional, Tuple, Union



class 				_lowerCAmelCase			(	enum.Enum							):


  '''simple docstring'''
  a_							:				List[Any]					    ="""timm"""
  a_							:				int					    ="""transformers"""




def 			lowerCamelCase_		(					lowerCAmelCase:		str			,							lowerCAmelCase:		Tuple			,							lowerCAmelCase:		Tuple )->						Any:
  if stage_names is None:
    raise ValueError('Stage_names must be set for transformers backbones' )

  if out_features is not None:
    if not isinstance(__UpperCamelCase			,							(list,) ):
      raise ValueError(F"""out_features must be a list {type(__UpperCamelCase )}""" )
    if any(feat not in stage_names for feat in out_features ):
      raise ValueError(F"""out_features must be a subset of stage_names: {stage_names} got {out_features}""" )

  if out_indices is not None:
    if not isinstance(__UpperCamelCase			,							(list, tuple) ):
      raise ValueError(F"""out_indices must be a list or tuple, got {type(__UpperCamelCase )}""" )
    if any(idx >= len(__UpperCamelCase ) for idx in out_indices ):
      raise ValueError('out_indices must be valid indices for stage_names {stage_names}, got {out_indices}' )

  if out_features is not None and out_indices is not None:
    if len(__UpperCamelCase ) != len(__UpperCamelCase ):
      raise ValueError('out_features and out_indices should have the same length if both are set' )
    if out_features != [stage_names[idx] for idx in out_indices]:
      raise ValueError('out_features and out_indices should correspond to the same stages if both are set' )


def 			lowerCamelCase_		(					lowerCAmelCase:		Dict			,							lowerCAmelCase:		Union[str, Any]			,							lowerCAmelCase:		Tuple			,							)->						Union[str, Any]:
  if out_indices is None and out_features is None:
    _snake_case      : str														=		[len(__UpperCamelCase ) - 1]
    _snake_case      : Optional[int]														=		[stage_names[-1]]
  elif out_indices is None and out_features is not None:
    _snake_case      : int														=		[stage_names.index(__UpperCamelCase ) for layer in out_features]
  elif out_features is None and out_indices is not None:
    _snake_case      : Optional[int]														=		[stage_names[idx] for idx in out_indices]
  return out_features, out_indices


def 			lowerCamelCase_		(					lowerCAmelCase:		Optional[int]			,							lowerCAmelCase:		str			,							lowerCAmelCase:		Optional[int]			,							)->						Tuple[List[str], List[int]]:
  verify_out_features_out_indices(out_features=__UpperCamelCase			,							out_indices=__UpperCamelCase			,							stage_names=__UpperCamelCase )
  _snake_case							,    _snake_case      : List[Any]														=		_align_output_features_output_indices(
      out_features=__UpperCamelCase			,							out_indices=__UpperCamelCase			,							stage_names=__UpperCamelCase )
  # Verify that the aligned out_features and out_indices are valid
  verify_out_features_out_indices(out_features=__UpperCamelCase			,							out_indices=__UpperCamelCase			,							stage_names=__UpperCamelCase )
  return output_features, output_indices



class 				_lowerCAmelCase			:


  '''simple docstring'''
  a_							:				List[Any]					    =None







  def UpperCamelCase_       (					self					:    Dict					, UpperCamelCase					:    Optional[Any]							):


    '''simple docstring'''





    if getattr(self					, '_backbone'					, __UpperCAmelCase							) is None:
      raise ValueError('self._backbone must be set before calling _init_timm_backbone'							)

    # These will diagree with the defaults for the transformers models e.g. for resnet50
    # the transformer model has out_features = ['stem', 'stage1', 'stage2', 'stage3', 'stage4']
    # the timm model has out_features = ['act', 'layer1', 'layer2', 'layer3', 'layer4']
    _snake_case      : Union[str, Any]														=		[stage['module'] for stage in self._backbone.feature_info.info]
    _snake_case      : Optional[Any]														=		[stage['num_chs'] for stage in self._backbone.feature_info.info]
    _snake_case      : Tuple														=		self._backbone.feature_info.out_indices
    _snake_case      : Optional[Any]														=		self._backbone.feature_info.module_name()

    # We verify the out indices and out features are valid
    verify_out_features_out_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=self.stage_names							)
    _snake_case							,    _snake_case      : List[str]														=		out_features, out_indices







  def UpperCamelCase_       (					self					:    List[Any]					, UpperCamelCase					:    Union[str, Any]							):


    '''simple docstring'''





    _snake_case      : Dict														=		getattr(__UpperCAmelCase					, 'stage_names'							)
    _snake_case      : List[str]														=		getattr(__UpperCAmelCase					, 'out_features'					, __UpperCAmelCase							)
    _snake_case      : Union[str, Any]														=		getattr(__UpperCAmelCase					, 'out_indices'					, __UpperCAmelCase							)

    _snake_case      : Tuple														=		stage_names
    _snake_case							,    _snake_case      : List[str]														=		get_aligned_output_features_output_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=__UpperCAmelCase							)
    # Number of channels for each stage. This is set in the transformer backbone model init
    _snake_case      : Optional[Any]														=		None







  def UpperCamelCase_       (					self					:    Optional[Any]					, UpperCamelCase					:    List[Any]							):


    '''simple docstring'''





    _snake_case      : Optional[int]														=		config

    _snake_case      : Dict														=		getattr(__UpperCAmelCase					, 'use_timm_backbone'					, __UpperCAmelCase							)
    _snake_case      : Any														=		BackboneType.TIMM if self.use_timm_backbone else BackboneType.TRANSFORMERS

    if self.backbone_type == BackboneType.TIMM:
      self._init_timm_backbone(__UpperCAmelCase							)
    elif self.backbone_type == BackboneType.TRANSFORMERS:
      self._init_transformers_backbone(__UpperCAmelCase							)
    else:
      raise ValueError(f"""backbone_type {self.backbone_type} not supported."""							)







  @property
  def UpperCamelCase_       (					self					:    Optional[int]							):


    '''simple docstring'''





    return self._out_features







  @out_features.setter
  def UpperCamelCase_       (					self					:    str					, UpperCamelCase					:    Tuple							):


    '''simple docstring'''





    _snake_case							,    _snake_case      : str														=		get_aligned_output_features_output_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=self.stage_names							)







  @property
  def UpperCamelCase_       (					self					:    Any							):


    '''simple docstring'''





    return self._out_indices







  @out_indices.setter
  def UpperCamelCase_       (					self					:    Optional[int]					, UpperCamelCase					:    Tuple							):


    '''simple docstring'''





    _snake_case							,    _snake_case      : List[Any]														=		get_aligned_output_features_output_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=self.stage_names							)







  @property
  def UpperCamelCase_       (					self					:    List[str]							):


    '''simple docstring'''





    return {stage: self.num_features[i] for i, stage in enumerate(self.stage_names							)}







  @property
  def UpperCamelCase_       (					self					:    Union[str, Any]							):


    '''simple docstring'''





    return [self.out_feature_channels[name] for name in self.out_features]







  def UpperCamelCase_       (					self					:    Tuple					, *UpperCamelCase					:    List[Any]					, **UpperCamelCase					:    int							):


    '''simple docstring'''





    _snake_case      : int														=		dict(inspect.signature(self.forward							).parameters							)
    _snake_case      : Dict														=		{k: v for k, v in kwargs.items() if k in signature}
    return self(*__UpperCAmelCase					, **__UpperCAmelCase							)







  def UpperCamelCase_       (					self					:    List[Any]					, UpperCamelCase					:    str					, UpperCamelCase					:    Tuple = None					, UpperCamelCase					:    Optional[Any] = None					, UpperCamelCase					:    Union[str, Any] = None					, ):


    '''simple docstring'''





    raise NotImplementedError('This method should be implemented by the derived class.'							)







  def UpperCamelCase_       (					self					:    Dict							):


    '''simple docstring'''





    _snake_case      : Optional[int]														=		super().to_dict()
    _snake_case      : Optional[Any]														=		output.pop('_out_features'							)
    _snake_case      : Dict														=		output.pop('_out_indices'							)
    return output




class 				_lowerCAmelCase			:


  '''simple docstring'''







  @property
  def UpperCamelCase_       (					self					:    Dict							):


    '''simple docstring'''





    return self._out_features







  @out_features.setter
  def UpperCamelCase_       (					self					:    List[str]					, UpperCamelCase					:    List[str]							):


    '''simple docstring'''





    _snake_case							,    _snake_case      : List[Any]														=		get_aligned_output_features_output_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=self.stage_names							)







  @property
  def UpperCamelCase_       (					self					:    Any							):


    '''simple docstring'''





    return self._out_indices







  @out_indices.setter
  def UpperCamelCase_       (					self					:    Union[str, Any]					, UpperCamelCase					:    Optional[int]							):


    '''simple docstring'''





    _snake_case							,    _snake_case      : int														=		get_aligned_output_features_output_indices(
        out_features=__UpperCAmelCase					, out_indices=__UpperCAmelCase					, stage_names=self.stage_names							)







  def UpperCamelCase_       (					self					:    Dict							):


    '''simple docstring'''





    _snake_case      : Any														=		super().to_dict()
    _snake_case      : Dict														=		output.pop('_out_features'							)
    _snake_case      : int														=		output.pop('_out_indices'							)
    return output






"""simple docstring"""


import enum
import inspect
import warnings
from functools import wraps
from typing import Callable, Optional

from .logging import get_logger


__A       						=       set()
__A       						=       get_logger(__name__)



def     _lowerCamelCase(__UpperCamelCase = None       )				-> Optional[Any]:

	def decorator(__UpperCamelCase       ):
		global _emitted_deprecation_warnings

		if inspect.isclass(__UpperCamelCase       ):
			_lowerCAmelCase								=deprecated_class_or_function.__init__
			_lowerCAmelCase								=deprecated_class_or_function.__name__
		else:
			_lowerCAmelCase								=deprecated_class_or_function
			_lowerCAmelCase								=deprecated_function.__name__
			# Support deprecating __init__ class method: class name instead
			_lowerCAmelCase								=name if name != """__init__""" else deprecated_function.__qualname__.split("""."""       )[-2]

		_lowerCAmelCase								=(
		    F'''{name} is deprecated and will be removed in the next major version of datasets.''' + F''' {help_message}'''
		    if help_message
		    else """"""
		)

		@wraps(__UpperCamelCase       )
		def wrapper(*__UpperCamelCase    , **__UpperCamelCase       ):
			_lowerCAmelCase								=hash(__UpperCamelCase       )
			if func_hash not in _emitted_deprecation_warnings:
				warnings.warn(__UpperCamelCase    , category=__UpperCamelCase    , stacklevel=2       )
				_emitted_deprecation_warnings.add(__UpperCamelCase       )
			return deprecated_function(*__UpperCamelCase    , **__UpperCamelCase       )

		_lowerCAmelCase								="""deprecated"""

		if inspect.isclass(__UpperCamelCase       ):
			_lowerCAmelCase								=wrapper
			return deprecated_class_or_function
		else:
			return wrapper

	return decorator







class 		lowerCamelCase__					(					enum.EnumMeta				):





			'''simple docstring'''



			def __getattribute__(							cls     ,     __UpperCAmelCase  ) ->     Optional[int]:
				_lowerCAmelCase								=super().__getattribute__(__UpperCAmelCase  )
				if isinstance(__UpperCAmelCase     ,     enum.Enum  ) and obj._on_access:
					obj._on_access()
				return obj



			def __getitem__(							cls     ,     __UpperCAmelCase  ) ->     List[str]:
				_lowerCAmelCase								=super().__getitem__(__UpperCAmelCase  )
				if member._on_access:
					member._on_access()
				return member



			def __call__(							cls     ,     __UpperCAmelCase     ,     __UpperCAmelCase=None     ,     *, __UpperCAmelCase=None     ,     __UpperCAmelCase=None     ,     __UpperCAmelCase=None     ,     __UpperCAmelCase=1  ) ->     Optional[Any]:
				_lowerCAmelCase								=super().__call__(__UpperCAmelCase     ,     __UpperCAmelCase     ,     module=__UpperCAmelCase     ,     qualname=__UpperCAmelCase     ,     type=__UpperCAmelCase     ,     start=__UpperCAmelCase  )
				if isinstance(__UpperCAmelCase     ,     enum.Enum  ) and obj._on_access:
					obj._on_access()
				return obj







class 		lowerCamelCase__					(					enum.Enum ,	metaclass=__magic_name__				):





			'''simple docstring'''



			def __new__(							cls     ,     __UpperCAmelCase  ) ->     Optional[int]:
				_lowerCAmelCase								=object.__new__(cls  )
				_lowerCAmelCase								=value
				_lowerCAmelCase								=member.deprecate
				return member



			@property
			def 					_lowerCAmelCase		(							self  ) ->     List[Any]:
				return ""



			def 					_lowerCAmelCase		(							self  ) ->     Tuple:
				_lowerCAmelCase								=f''' {self.help_message}''' if self.help_message else """"""
				warnings.warn(
				    f'''\'{self.__objclass__.__name__}\' is deprecated and will be removed in the next major version of datasets.'''
				    + help_message     ,     __UpperCAmelCase     ,     stacklevel=3     ,     )



