



import inspect
import os
import re

from transformers.configuration_utils import PretrainedConfig
from transformers.utils import direct_transformers_import


# All paths are set with the intent you should run this script from the root of the repo with the command
# python utils/check_config_docstrings.py
A__  :  Tuple								=					'''src/transformers'''


# This is to make sure the transformers module imported is the one in the repo.
A__  :  Optional[int]								=					direct_transformers_import(PATH_TO_TRANSFORMERS)

A__  :  Optional[Any]								=					transformers.models.auto.configuration_auto.CONFIG_MAPPING

A__  :  List[Any]								=					{
    # used to compute the property `self.chunk_length`
    '''EncodecConfig''': ['''overlap'''],
    # used as `self.bert_model = BertModel(config, ...)`
    '''DPRConfig''': True,
    # not used in modeling files, but it's an important information
    '''FSMTConfig''': ['''langs'''],
    # used internally in the configuration class file
    '''GPTNeoConfig''': ['''attention_types'''],
    # used internally in the configuration class file
    '''EsmConfig''': ['''is_folding_model'''],
    # used during training (despite we don't have training script for these models yet)
    '''Mask2FormerConfig''': ['''ignore_value'''],
    # `ignore_value` used during training (despite we don't have training script for these models yet)
    # `norm` used in conversion script (despite not using in the modeling file)
    '''OneFormerConfig''': ['''ignore_value''', '''norm'''],
    # used during preprocessing and collation, see `collating_graphormer.py`
    '''GraphormerConfig''': ['''spatial_pos_max'''],
    # used internally in the configuration class file
    '''T5Config''': ['''feed_forward_proj'''],
    # used internally in the configuration class file
    # `tokenizer_class` get default value `T5Tokenizer` intentionally
    '''MT5Config''': ['''feed_forward_proj''', '''tokenizer_class'''],
    '''UMT5Config''': ['''feed_forward_proj''', '''tokenizer_class'''],
    # used internally in the configuration class file
    '''LongT5Config''': ['''feed_forward_proj'''],
    # used internally in the configuration class file
    '''SwitchTransformersConfig''': ['''feed_forward_proj'''],
    # having default values other than `1e-5` - we can't fix them without breaking
    '''BioGptConfig''': ['''layer_norm_eps'''],
    # having default values other than `1e-5` - we can't fix them without breaking
    '''GLPNConfig''': ['''layer_norm_eps'''],
    # having default values other than `1e-5` - we can't fix them without breaking
    '''SegformerConfig''': ['''layer_norm_eps'''],
    # having default values other than `1e-5` - we can't fix them without breaking
    '''CvtConfig''': ['''layer_norm_eps'''],
    # having default values other than `1e-5` - we can't fix them without breaking
    '''PerceiverConfig''': ['''layer_norm_eps'''],
    # used internally to calculate the feature size
    '''InformerConfig''': ['''num_static_real_features''', '''num_time_features'''],
    # used internally to calculate the feature size
    '''TimeSeriesTransformerConfig''': ['''num_static_real_features''', '''num_time_features'''],
    # used internally to calculate the feature size
    '''AutoformerConfig''': ['''num_static_real_features''', '''num_time_features'''],
    # used internally to calculate `mlp_dim`
    '''SamVisionConfig''': ['''mlp_ratio'''],
    # For (head) training, but so far not implemented
    '''ClapAudioConfig''': ['''num_classes'''],
    # Not used, but providing useful information to users
    '''SpeechT5HifiGanConfig''': ['''sampling_rate'''],
}


# TODO (ydshieh): Check the failing cases, try to fix them or move some cases to the above block once we are sure
SPECIAL_CASES_TO_ALLOW.update(
    {
        '''CLIPSegConfig''': True,
        '''DeformableDetrConfig''': True,
        '''DetaConfig''': True,
        '''DinatConfig''': True,
        '''DonutSwinConfig''': True,
        '''EfficientFormerConfig''': True,
        '''FSMTConfig''': True,
        '''JukeboxConfig''': True,
        '''LayoutLMv2Config''': True,
        '''MaskFormerSwinConfig''': True,
        '''MT5Config''': True,
        '''NatConfig''': True,
        '''OneFormerConfig''': True,
        '''PerceiverConfig''': True,
        '''RagConfig''': True,
        '''SpeechT5Config''': True,
        '''SwinConfig''': True,
        '''Swin2SRConfig''': True,
        '''Swinv2Config''': True,
        '''SwitchTransformersConfig''': True,
        '''TableTransformerConfig''': True,
        '''TapasConfig''': True,
        '''TransfoXLConfig''': True,
        '''UniSpeechConfig''': True,
        '''UniSpeechSatConfig''': True,
        '''WavLMConfig''': True,
        '''WhisperConfig''': True,
        # TODO: @Arthur (for `alignment_head` and `alignment_layer`)
        '''JukeboxPriorConfig''': True,
        # TODO: @Younes (for `is_decoder`)
        '''Pix2StructTextConfig''': True,
    }
)


def 			UpperCamelCase(  __UpperCamelCase							:		List[str]     ,__UpperCamelCase							:		Dict     ,__UpperCamelCase							:		Union[str, Any]     ,__UpperCamelCase							:		Any ):
		lowerCAmelCase_			:     Optional[int]									= False
		for attribute in attributes:
				for modeling_source in source_strings:
						# check if we can find `config.xxx`, `getattr(config, "xxx", ...)` or `getattr(self.config, "xxx", ...)`
						if (
						    f"""config.{attribute}""" in modeling_source
						    or f"""getattr(config, \"{attribute}\"""" in modeling_source
						    or f"""getattr(self.config, \"{attribute}\"""" in modeling_source
						):
								lowerCAmelCase_			:     Optional[int]									= True
						# Deal with multi-line cases
						elif (
						    re.search(
						        Rf"""getattr[ \t\v\n\r\f]*\([ \t\v\n\r\f]*(self\.)?config,[ \t\v\n\r\f]*\"{attribute}\""""     ,__UpperCamelCase     ,)
						    is not None
						):
								lowerCAmelCase_			:     Any									= True
						# `SequenceSummary` is called with `SequenceSummary(config)`
						elif attribute in [
						    "summary_type",
						    "summary_use_proj",
						    "summary_activation",
						    "summary_last_dropout",
						    "summary_proj_to_labels",
						    "summary_first_dropout",
						]:
								if "SequenceSummary" in modeling_source:
										lowerCAmelCase_			:     Union[str, Any]									= True
						if attribute_used:
								break
				if attribute_used:
						break

    # common and important attributes, even if they do not always appear in the modeling files
		lowerCAmelCase_			:     int									= [
		    '''bos_index''',
		    '''eos_index''',
		    '''pad_index''',
		    '''unk_index''',
		    '''mask_index''',
		    '''image_size''',
		    '''use_cache''',
		    '''out_features''',
		    '''out_indices''',
		]
		lowerCAmelCase_			:     Optional[Any]									= ['''encoder_no_repeat_ngram_size''']

		# Special cases to be allowed
		lowerCAmelCase_			:     Union[str, Any]									= True
		if not attribute_used:
				lowerCAmelCase_			:     List[str]									= False
				for attribute in attributes:
						# Allow if the default value in the configuration class is different from the one in `PretrainedConfig`
						if attribute in ["is_encoder_decoder"] and default_value is True:
								lowerCAmelCase_			:     List[str]									= True
						elif attribute in ["tie_word_embeddings"] and default_value is False:
								lowerCAmelCase_			:     List[str]									= True

						# Allow cases without checking the default value in the configuration class
						elif attribute in attributes_to_allow + attributes_used_in_generation:
								lowerCAmelCase_			:     str									= True
						elif attribute.endswith('''_token_id''' ):
								lowerCAmelCase_			:     str									= True

						# configuration class specific cases
						if not case_allowed:
								lowerCAmelCase_			:     int									= SPECIAL_CASES_TO_ALLOW.get(config_class.__name__     ,[] )
								lowerCAmelCase_			:     List[Any]									= allowed_cases is True or attribute in allowed_cases

		return attribute_used or case_allowed


def 			UpperCamelCase(  __UpperCamelCase							:		Tuple ):
		lowerCAmelCase_			:     Tuple									= dict(inspect.signature(config_class.__init__ ).parameters )
		lowerCAmelCase_			:     List[Any]									= [x for x in list(signature.keys() ) if x not in ['''self''', '''kwargs''']]
		lowerCAmelCase_			:     Any									= [signature[param].default for param in parameter_names]

		# If `attribute_map` exists, an attribute can have different names to be used in the modeling files, and as long
		# as one variant is used, the test should pass
		lowerCAmelCase_			:     Optional[int]									= {}
		if len(config_class.attribute_map ) > 0:
				lowerCAmelCase_			:     int									= {v: k for k, v in config_class.attribute_map.items()}

		# Get the path to modeling source files
		lowerCAmelCase_			:     Optional[int]									= inspect.getsourcefile(__UpperCamelCase )
		lowerCAmelCase_			:     Any									= os.path.dirname(__UpperCamelCase )
		# Let's check against all frameworks: as long as one framework uses an attribute, we are good.
		lowerCAmelCase_			:     Tuple									= [os.path.join(__UpperCamelCase     ,__UpperCamelCase ) for fn in os.listdir(__UpperCamelCase ) if fn.startswith('''modeling_''' )]

		# Get the source code strings
		lowerCAmelCase_			:     List[Any]									= []
		for path in modeling_paths:
				if os.path.isfile(__UpperCamelCase ):
						with open(__UpperCamelCase ) as fp:
								modeling_sources.append(fp.read() )

		lowerCAmelCase_			:     Dict									= []
		for config_param, default_value in zip(__UpperCamelCase     ,__UpperCamelCase ):
				# `attributes` here is all the variant names for `config_param`
				lowerCAmelCase_			:     Tuple									= [config_param]
				# some configuration classes have non-empty `attribute_map`, and both names could be used in the
				# corresponding modeling files. As long as one of them appears, it is fine.
				if config_param in reversed_attribute_map:
						attributes.append(reversed_attribute_map[config_param] )

				if not check_attribute_being_used(__UpperCamelCase     ,__UpperCamelCase     ,__UpperCamelCase     ,__UpperCamelCase ):
						unused_attributes.append(attributes[0] )

		return sorted(__UpperCamelCase )


def 			UpperCamelCase(  ):
		lowerCAmelCase_			:     Tuple									= {}
		for _config_class in list(CONFIG_MAPPING.values() ):
				# Skip deprecated models
				if "models.deprecated" in _config_class.__module__:
						continue
				# Some config classes are not in `CONFIG_MAPPING` (e.g. `CLIPVisionConfig`, `Blip2VisionConfig`, etc.)
				lowerCAmelCase_			:     Union[str, Any]									= [
				    cls
				    for name, cls in inspect.getmembers(
				        inspect.getmodule(_config_class )     ,lambda __UpperCamelCase : inspect.isclass(__UpperCamelCase )
				        and issubclass(__UpperCamelCase     ,__UpperCamelCase )
				        and inspect.getmodule(__UpperCamelCase ) == inspect.getmodule(_config_class )     ,)
				]
				for config_class in config_classes_in_module:
						lowerCAmelCase_			:     str									= check_config_attributes_being_used(__UpperCamelCase )
						if len(__UpperCamelCase ) > 0:
								lowerCAmelCase_			:     List[str]									= unused_attributes

		if len(__UpperCamelCase ) > 0:
				lowerCAmelCase_			:     Optional[Any]									= '''The following configuration classes contain unused attributes in the corresponding modeling files:\n'''
				for name, attributes in configs_with_unused_attributes.items():
						error += f"""{name}: {attributes}\n"""

				raise ValueError(__UpperCamelCase )


if __name__ == "__main__":
						check_config_attributes()









import inspect
import warnings
from typing import Any, Dict, Optional, Union

from packaging import version


def        _UpperCamelCase							(      *lowercase__    ,       lowercase__ = None    ,       lowercase__=True    ,       lowercase__=2      ):
						from .. import __version__

						__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		take_from
						__SCREAMING_SNAKE_CASE						:     List[str]					=		()
						if not isinstance(args[0]    ,       lowercase__      ):
												__SCREAMING_SNAKE_CASE						:     List[Any]					=		(args,)

						for attribute, version_name, message in args:
												if version.parse(version.parse(lowercase__      ).base_version      ) >= version.parse(lowercase__      ):
																		raise ValueError(
																		    F'''The deprecation tuple {(attribute, version_name, message)} should be removed since diffusers\''''
																		    F''' version {__version__} is >= {version_name}'''      )

												__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		None
												if isinstance(lowercase__    ,       lowercase__      ) and attribute in deprecated_kwargs:
																		values += (deprecated_kwargs.pop(lowercase__      ),)
																		__SCREAMING_SNAKE_CASE						:     List[Any]					=		F'''The `{attribute}` argument is deprecated and will be removed in version {version_name}.'''
												elif hasattr(lowercase__    ,       lowercase__      ):
																		values += (getattr(lowercase__    ,       lowercase__      ),)
																		__SCREAMING_SNAKE_CASE						:     List[str]					=		F'''The `{attribute}` attribute is deprecated and will be removed in version {version_name}.'''
												elif deprecated_kwargs is None:
																		__SCREAMING_SNAKE_CASE						:     str					=		F'''`{attribute}` is deprecated and will be removed in version {version_name}.'''

												if warning is not None:
																		__SCREAMING_SNAKE_CASE						:     Any					=		warning + ''' ''' if standard_warn else ''''''
																		warnings.warn(warning + message    ,       lowercase__    ,       stacklevel=lowercase__      )

						if isinstance(lowercase__    ,       lowercase__      ) and len(lowercase__      ) > 0:
												__SCREAMING_SNAKE_CASE						:     Union[str, Any]					=		inspect.getouterframes(inspect.currentframe()      )[1]
												__SCREAMING_SNAKE_CASE						:     Dict					=		call_frame.filename
												__SCREAMING_SNAKE_CASE						:     Optional[Any]					=		call_frame.lineno
												__SCREAMING_SNAKE_CASE						:     int					=		call_frame.function
												__SCREAMING_SNAKE_CASE			,			__SCREAMING_SNAKE_CASE						:     int					=		next(iter(deprecated_kwargs.items()      )      )
												raise TypeError(F'''{function} in {filename} line {line_number-1} got an unexpected keyword argument `{key}`'''      )

						if len(lowercase__      ) == 0:
												return
						elif len(lowercase__      ) == 1:
												return values[0]
						return values
