



import inspect
import tempfile
import unittest

from huggingface_hub import hf_hub_download

from transformers import is_torch_available
from transformers.testing_utils import is_flaky, require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


A__								=						1e-4

if is_torch_available():
				import torch

				from transformers import AutoformerConfig, AutoformerForPrediction, AutoformerModel
				from transformers.models.autoformer.modeling_autoformer import AutoformerDecoder, AutoformerEncoder


@require_torch
class       a							:



		def __init__(     self     :str   ,__lowercase     :Any   ,__lowercase     :str=1_6   ,__lowercase     :List[Any]=1_3   ,__lowercase     :Tuple=7   ,__lowercase     :Any=1_4   ,__lowercase     :str=1_0   ,__lowercase     :List[str]=1_9   ,__lowercase     :List[str]=5   ,__lowercase     :Optional[int]=4   ,__lowercase     :Optional[Any]=True   ,__lowercase     :Any=1_6   ,__lowercase     :Dict=2   ,__lowercase     :int=4   ,__lowercase     :str=4   ,__lowercase     :int="gelu"   ,__lowercase     :Optional[Any]=0.1   ,__lowercase     :Dict=0.1   ,__lowercase     :str=[1, 2, 3, 4, 5]   ,__lowercase     :List[str]=2_5   ,__lowercase     :int=5   ,):
						snake_case__	:      Optional[Any]     		=	d_model
						snake_case__	:      Any     		=	parent
						snake_case__	:      Dict     		=	batch_size
						snake_case__	:      Any     		=	prediction_length
						snake_case__	:      Optional[Any]     		=	context_length
						snake_case__	:      Any     		=	cardinality
						snake_case__	:      Dict     		=	num_time_features
						snake_case__	:      Optional[int]     		=	lags_sequence
						snake_case__	:      Optional[Any]     		=	embedding_dimension
						snake_case__	:      Union[str, Any]     		=	is_training
						snake_case__	:      str     		=	hidden_size
						snake_case__	:      str     		=	num_hidden_layers
						snake_case__	:      Union[str, Any]     		=	num_attention_heads
						snake_case__	:      str     		=	intermediate_size
						snake_case__	:      Optional[int]     		=	hidden_act
						snake_case__	:      Dict     		=	hidden_dropout_prob
						snake_case__	:      Tuple     		=	attention_probs_dropout_prob

						snake_case__	:      Tuple     		=	context_length
						snake_case__	:      Any     		=	prediction_length + label_length
						snake_case__	:      int     		=	label_length

						snake_case__	:      Dict     		=	moving_average
						snake_case__	:      str     		=	autocorrelation_factor



		def 	__lowerCamelCase			(     self     :List[Any]  ):
						return AutoformerConfig(
						    d_model=self.d_model   ,encoder_layers=self.num_hidden_layers   ,decoder_layers=self.num_hidden_layers   ,encoder_attention_heads=self.num_attention_heads   ,decoder_attention_heads=self.num_attention_heads   ,encoder_ffn_dim=self.intermediate_size   ,decoder_ffn_dim=self.intermediate_size   ,dropout=self.hidden_dropout_prob   ,attention_dropout=self.attention_probs_dropout_prob   ,prediction_length=self.prediction_length   ,context_length=self.context_length   ,label_length=self.label_length   ,lags_sequence=self.lags_sequence   ,num_time_features=self.num_time_features   ,num_static_categorical_features=1   ,cardinality=[self.cardinality]   ,embedding_dimension=[self.embedding_dimension]   ,moving_average=self.moving_average   ,)



		def 	__lowerCamelCase			(     self     :str   ,__lowercase     :Union[str, Any]  ):
						snake_case__	:      List[Any]     		=	config.context_length + max(config.lags_sequence  )

						snake_case__	:      Union[str, Any]     		=	ids_tensor([self.batch_size, 1]   ,config.cardinality[0]  )
						snake_case__	:      List[Any]     		=	floats_tensor([self.batch_size, _past_length, config.num_time_features]  )
						snake_case__	:      Optional[int]     		=	floats_tensor([self.batch_size, _past_length]  )
						snake_case__	:      Optional[Any]     		=	floats_tensor([self.batch_size, _past_length]  ) > 0.5

						# decoder inputs
						snake_case__	:      Union[str, Any]     		=	floats_tensor([self.batch_size, config.prediction_length, config.num_time_features]  )
						snake_case__	:      str     		=	floats_tensor([self.batch_size, config.prediction_length]  )

						snake_case__	:      Union[str, Any]     		=	{
						    '''past_values''': past_values,
						    '''static_categorical_features''': static_categorical_features,
						    '''past_time_features''': past_time_features,
						    '''past_observed_mask''': past_observed_mask,
						    '''future_time_features''': future_time_features,
						    '''future_values''': future_values,
						}
						return inputs_dict



		def 	__lowerCamelCase			(     self     :Optional[Any]  ):
						snake_case__	:      Dict     		=	self.get_config()
						snake_case__	:      int     		=	self.prepare_autoformer_inputs_dict(__lowercase  )
						return config, inputs_dict



		def 	__lowerCamelCase			(     self     :Optional[Any]  ):
						snake_case__		, snake_case__	:      str     		=	self.prepare_config_and_inputs()
						return config, inputs_dict






		def 	__lowerCamelCase			(     self     :int   ,__lowercase     :Optional[Any]   ,__lowercase     :Union[str, Any]  ):
						snake_case__	:      Tuple     		=	AutoformerModel(config=__lowercase  ).to(__lowercase  ).eval()
						snake_case__	:      Optional[Any]     		=	model(**__lowercase  )

						snake_case__	:      List[str]     		=	outputs.encoder_last_hidden_state
						snake_case__	:      int     		=	outputs.last_hidden_state

						with tempfile.TemporaryDirectory() as tmpdirname:
										snake_case__	:      Dict     		=	model.get_encoder()
										encoder.save_pretrained(__lowercase  )
										snake_case__	:      List[Any]     		=	AutoformerEncoder.from_pretrained(__lowercase  ).to(__lowercase  )

						snake_case__		, snake_case__		, snake_case__		, snake_case__		, snake_case__	:      List[Any]     		=	model.create_network_inputs(**__lowercase  )
						snake_case__		, snake_case__	:      Union[str, Any]     		=	model.decomposition_layer(transformer_inputs[:, : config.context_length, ...]  )

						snake_case__	:      List[str]     		=	torch.cat(
						    (transformer_inputs[:, : config.context_length, ...], feature[:, : config.context_length, ...])   ,dim=-1   ,)
						snake_case__	:      Union[str, Any]     		=	encoder(inputs_embeds=__lowercase  )[0]
						self.parent.assertTrue((encoder_last_hidden_state_a - encoder_last_hidden_state).abs().max().item() < 1e-3  )

						snake_case__	:      List[str]     		=	(
						    torch.mean(transformer_inputs[:, : config.context_length, ...]   ,dim=1  )
						    .unsqueeze(1  )
						    .repeat(1   ,config.prediction_length   ,1  )
						)
						snake_case__	:      Dict     		=	torch.zeros(
						    [transformer_inputs.shape[0], config.prediction_length, transformer_inputs.shape[2]]   ,device=enc_input.device   ,)

						snake_case__	:      Union[str, Any]     		=	torch.cat(
						    (
						        torch.cat((seasonal_input[:, -config.label_length :, ...], zeros)   ,dim=1  ),
						        feature[:, config.context_length - config.label_length :, ...],
						    )   ,dim=-1   ,)
						snake_case__	:      List[str]     		=	torch.cat(
						    (
						        torch.cat((trend_input[:, -config.label_length :, ...], mean)   ,dim=1  ),
						        feature[:, config.context_length - config.label_length :, ...],
						    )   ,dim=-1   ,)

						with tempfile.TemporaryDirectory() as tmpdirname:
										snake_case__	:      Optional[Any]     		=	model.get_decoder()
										decoder.save_pretrained(__lowercase  )
										snake_case__	:      List[str]     		=	AutoformerDecoder.from_pretrained(__lowercase  ).to(__lowercase  )

						snake_case__	:      List[Any]     		=	decoder(
						    trend=__lowercase   ,inputs_embeds=__lowercase   ,encoder_hidden_states=__lowercase   ,)[0]

						self.parent.assertTrue((last_hidden_state_a - last_hidden_state).abs().max().item() < 1e-3  )


@require_torch
class       a							(			__lowerCamelCase  ,							__lowerCamelCase  ,							unittest.TestCase				):
		__lowerCAmelCase	:    Optional[int]											=					(AutoformerModel, AutoformerForPrediction) if is_torch_available() else ()
		__lowerCAmelCase	:    List[Any]											=					(AutoformerForPrediction,) if is_torch_available() else ()
		__lowerCAmelCase	:    str											=					{"""feature-extraction""": AutoformerModel} if is_torch_available() else {}
		__lowerCAmelCase	:    Dict											=					False
		__lowerCAmelCase	:    List[str]											=					False
		__lowerCAmelCase	:    Optional[int]											=					False
		__lowerCAmelCase	:    Tuple											=					False
		__lowerCAmelCase	:    Dict											=					False
		__lowerCAmelCase	:    Tuple											=					False



		def 	__lowerCamelCase			(     self     :Optional[Any]  ):
						snake_case__	:      Any     		=	AutoformerModelTester(self  )
						snake_case__	:      Dict     		=	ConfigTester(self   ,config_class=__lowercase   ,has_text_modality=__lowercase  )



		def 	__lowerCamelCase			(     self     :Optional[int]  ):
						self.config_tester.run_common_tests()



		def 	__lowerCamelCase			(     self     :Any  ):
						snake_case__		, snake_case__	:      Union[str, Any]     		=	self.model_tester.prepare_config_and_inputs()
						for model_class in self.all_model_classes:
										snake_case__	:      Tuple     		=	model_class(__lowercase  )

										with tempfile.TemporaryDirectory() as tmpdirname:
														model.save_pretrained(__lowercase  )
														snake_case__		, snake_case__	:      Dict     		=	model_class.from_pretrained(__lowercase   ,output_loading_info=__lowercase  )
										self.assertEqual(info['''missing_keys''']   ,[]  )



		def 	__lowerCamelCase			(     self     :int  ):
						snake_case__	:      List[Any]     		=	self.model_tester.prepare_config_and_inputs_for_common()
						self.model_tester.check_encoder_decoder_model_standalone(*__lowercase  )



		@unittest.skip(reason='''Model has no tokens embeddings'''  )
		def 	__lowerCamelCase			(     self     :List[Any]  ):
						pass



		def 	__lowerCamelCase			(     self     :str  ):
						snake_case__	:      List[str]     		=	inspect.signature(getattr(__lowercase   ,'''forward'''  )  )
						# The main input is the name of the argument after `self`
						snake_case__	:      int     		=	list(model_signature.parameters.keys()  )[1]
						self.assertEqual(AutoformerModel.main_input_name   ,__lowercase  )



		def 	__lowerCamelCase			(     self     :Union[str, Any]  ):
						snake_case__		, snake_case__	:      int     		=	self.model_tester.prepare_config_and_inputs_for_common()

						for model_class in self.all_model_classes:
										snake_case__	:      Optional[int]     		=	model_class(__lowercase  )
										snake_case__	:      Any     		=	inspect.signature(model.forward  )
										# signature.parameters is an OrderedDict => so arg_names order is deterministic
										snake_case__	:      List[Any]     		=	[*signature.parameters.keys()]

										snake_case__	:      Tuple     		=	[
										    '''past_values''',
										    '''past_time_features''',
										    '''past_observed_mask''',
										    '''static_categorical_features''',
										    '''static_real_features''',
										    '''future_values''',
										    '''future_time_features''',
										]

										if model.__class__.__name__ in ["AutoformerForPrediction"]:
														expected_arg_names.append('''future_observed_mask'''  )

										expected_arg_names.extend(
										    [
										        '''decoder_attention_mask''',
										        '''head_mask''',
										        '''decoder_head_mask''',
										        '''cross_attn_head_mask''',
										        '''encoder_outputs''',
										        '''past_key_values''',
										        '''output_hidden_states''',
										        '''output_attentions''',
										        '''use_cache''',
										        '''return_dict''',
										    ]  )

										self.assertListEqual(arg_names[: len(__lowercase  )]   ,__lowercase  )



		def 	__lowerCamelCase			(     self     :Tuple  ):
						snake_case__		, snake_case__	:      Optional[Any]     		=	self.model_tester.prepare_config_and_inputs_for_common()
						snake_case__	:      List[Any]     		=	True

						snake_case__	:      Dict     		=	getattr(self.model_tester   ,'''seq_length'''   ,__lowercase  )
						snake_case__	:      List[Any]     		=	getattr(self.model_tester   ,'''decoder_seq_length'''   ,__lowercase  )
						snake_case__	:      Any     		=	getattr(self.model_tester   ,'''encoder_seq_length'''   ,__lowercase  )
						snake_case__	:      List[str]     		=	getattr(self.model_tester   ,'''d_model'''   ,__lowercase  )
						snake_case__	:      str     		=	getattr(self.model_tester   ,'''num_attention_heads'''   ,__lowercase  )
						snake_case__	:      int     		=	d_model // num_attention_heads

						for model_class in self.all_model_classes:
										snake_case__	:      str     		=	True
										snake_case__	:      str     		=	False
										snake_case__	:      Tuple     		=	True
										snake_case__	:      int     		=	model_class(__lowercase  )
										model.to(__lowercase  )
										model.eval()
										with torch.no_grad():
														snake_case__	:      Optional[Any]     		=	model(**self._prepare_for_class(__lowercase   ,__lowercase  )  )
										snake_case__	:      Dict     		=	outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
										self.assertEqual(len(__lowercase  )   ,self.model_tester.num_hidden_layers  )

										# check that output_attentions also work using config
										del inputs_dict["output_attentions"]
										snake_case__	:      List[str]     		=	True
										snake_case__	:      Dict     		=	model_class(__lowercase  )
										model.to(__lowercase  )
										model.eval()
										with torch.no_grad():
														snake_case__	:      Union[str, Any]     		=	model(**self._prepare_for_class(__lowercase   ,__lowercase  )  )
										snake_case__	:      Optional[int]     		=	outputs.encoder_attentions
										self.assertEqual(len(__lowercase  )   ,self.model_tester.num_hidden_layers  )

										self.assertListEqual(
										    list(attentions[0].shape[-3:]  )   ,[self.model_tester.num_attention_heads, encoder_seq_length, dim]   ,)
										snake_case__	:      Any     		=	len(__lowercase  )

										snake_case__	:      int     		=	7

										if "last_hidden_state" in outputs:
														correct_outlen += 1

										if "trend" in outputs:
														correct_outlen += 1

										if "past_key_values" in outputs:
														correct_outlen += 1  # past_key_values have been returned

										if "loss" in outputs:
														correct_outlen += 1

										if "params" in outputs:
														correct_outlen += 1

										self.assertEqual(__lowercase   ,__lowercase  )

										# decoder attentions
										snake_case__	:      Any     		=	outputs.decoder_attentions
										self.assertIsInstance(__lowercase   ,(list, tuple)  )
										self.assertEqual(len(__lowercase  )   ,self.model_tester.num_hidden_layers  )
										self.assertListEqual(
										    list(decoder_attentions[0].shape[-3:]  )   ,[self.model_tester.num_attention_heads, decoder_seq_length, dim]   ,)

										# cross attentions
										snake_case__	:      Union[str, Any]     		=	outputs.cross_attentions
										self.assertIsInstance(__lowercase   ,(list, tuple)  )
										self.assertEqual(len(__lowercase  )   ,self.model_tester.num_hidden_layers  )
										self.assertListEqual(
										    list(cross_attentions[0].shape[-3:]  )   ,[self.model_tester.num_attention_heads, decoder_seq_length, dim]   ,)

						# Check attention is always last and order is fine
						snake_case__	:      Any     		=	True
						snake_case__	:      Any     		=	True
						snake_case__	:      List[Any]     		=	model_class(__lowercase  )
						model.to(__lowercase  )
						model.eval()
						with torch.no_grad():
										snake_case__	:      int     		=	model(**self._prepare_for_class(__lowercase   ,__lowercase  )  )

						self.assertEqual(out_len + 2   ,len(__lowercase  )  )

						snake_case__	:      List[Any]     		=	outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions

						self.assertEqual(len(__lowercase  )   ,self.model_tester.num_hidden_layers  )
						self.assertListEqual(
						    list(self_attentions[0].shape[-3:]  )   ,[self.model_tester.num_attention_heads, encoder_seq_length, dim]   ,)






		@is_flaky()
		def 	__lowerCamelCase			(     self     :Union[str, Any]  ):
						super().test_retain_grad_hidden_states_attentions()



def 			_lowerCAmelCase       (					__lowerCAmelCase="train-batch.pt"      )   ->					int:


				"""simple docstring"""

				snake_case__	:      Dict     		=	hf_hub_download(repo_id='''hf-internal-testing/tourism-monthly-batch'''  ,  filename=__lowerCAmelCase  ,  repo_type='''dataset'''      )
				snake_case__	:      Tuple     		=	torch.load(__lowerCAmelCase  ,  map_location=__lowerCAmelCase      )
				return batch





@require_torch
@slow
class       a							(			unittest.TestCase				):



		def 	__lowerCamelCase			(     self     :str  ):
						snake_case__	:      Optional[Any]     		=	AutoformerModel.from_pretrained('''huggingface/autoformer-tourism-monthly'''  ).to(__lowercase  )
						snake_case__	:      List[Any]     		=	prepare_batch()

						with torch.no_grad():
										snake_case__	:      Optional[int]     		=	model(
										    past_values=batch['''past_values''']   ,past_time_features=batch['''past_time_features''']   ,past_observed_mask=batch['''past_observed_mask''']   ,static_categorical_features=batch['''static_categorical_features''']   ,future_values=batch['''future_values''']   ,future_time_features=batch['''future_time_features''']   ,)[0]

						snake_case__	:      Any     		=	torch.Size(
						    (6_4, model.config.prediction_length + model.config.label_length, model.config.feature_size)  )
						self.assertEqual(output.shape   ,__lowercase  )

						snake_case__	:      int     		=	torch.tensor(
						    [[0.3593, -1.3398, 0.6330], [0.2279, 1.5396, -0.1792], [0.0450, 1.3225, -0.2335]]   ,device=__lowercase  )
						self.assertTrue(torch.allclose(output[0, :3, :3]   ,__lowercase   ,atol=__lowercase  )  )



		def 	__lowerCamelCase			(     self     :Dict  ):
						snake_case__	:      List[str]     		=	AutoformerForPrediction.from_pretrained('''huggingface/autoformer-tourism-monthly'''  ).to(__lowercase  )
						snake_case__	:      Tuple     		=	prepare_batch('''val-batch.pt'''  )
						with torch.no_grad():
										snake_case__	:      Optional[int]     		=	model(
										    past_values=batch['''past_values''']   ,past_time_features=batch['''past_time_features''']   ,past_observed_mask=batch['''past_observed_mask''']   ,static_categorical_features=batch['''static_categorical_features''']   ,).encoder_last_hidden_state
						snake_case__	:      Dict     		=	torch.Size((6_4, model.config.context_length, model.config.d_model)  )
						self.assertEqual(output.shape   ,__lowercase  )

						snake_case__	:      str     		=	torch.tensor(
						    [[-0.0734, -0.9036, 0.8358], [4.7186, 2.4113, 1.9581], [1.7953, 2.3558, 1.2970]]   ,device=__lowercase  )
						self.assertTrue(torch.allclose(output[0, :3, :3]   ,__lowercase   ,atol=__lowercase  )  )






		def 	__lowerCamelCase			(     self     :Optional[Any]  ):
						snake_case__	:      Any     		=	AutoformerForPrediction.from_pretrained('''huggingface/autoformer-tourism-monthly'''  ).to(__lowercase  )
						snake_case__	:      Union[str, Any]     		=	prepare_batch('''val-batch.pt'''  )
						with torch.no_grad():
										snake_case__	:      Optional[Any]     		=	model.generate(
										    static_categorical_features=batch['''static_categorical_features''']   ,past_time_features=batch['''past_time_features''']   ,past_values=batch['''past_values''']   ,future_time_features=batch['''future_time_features''']   ,past_observed_mask=batch['''past_observed_mask''']   ,)
						snake_case__	:      Any     		=	torch.Size((6_4, model.config.num_parallel_samples, model.config.prediction_length)  )
						self.assertEqual(outputs.sequences.shape   ,__lowercase  )

						snake_case__	:      List[Any]     		=	torch.tensor([3130.6763, 4056.5293, 7053.0786]   ,device=__lowercase  )
						snake_case__	:      Dict     		=	outputs.sequences.mean(dim=1  )
						self.assertTrue(torch.allclose(mean_prediction[0, -3:]   ,__lowercase   ,rtol=1e-1  )  )






from importlib import import_module

from .logging import get_logger


A__								=						get_logger(__name__)


class       a							:



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


class       a							:
		__lowerCAmelCase	:    Any											=					[]



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



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



		def __exit__(     self     :Tuple   ,*__lowercase     :Optional[int]  ):
						for attr in list(self.original  ):
										setattr(self.obj   ,__lowercase   ,self.original.pop(__lowercase  )  )



		def 	__lowerCamelCase			(     self     :Tuple  ):
						self.__enter__()
						self._active_patches.append(self  )






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

						return self.__exit__()

