

'''simple docstring'''

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 							_snake_case :
   def __init__( self			:      Any     ,SCREAMING_SNAKE_CASE__			:      Any     ,SCREAMING_SNAKE_CASE__			:      List[str]=16     ,SCREAMING_SNAKE_CASE__			:      Optional[int]=13     ,SCREAMING_SNAKE_CASE__			:      List[Any]=7     ,SCREAMING_SNAKE_CASE__			:      Union[str, Any]=14     ,SCREAMING_SNAKE_CASE__			:      List[Any]=10     ,SCREAMING_SNAKE_CASE__			:      Optional[Any]=19     ,SCREAMING_SNAKE_CASE__			:      Any=5     ,SCREAMING_SNAKE_CASE__			:      Optional[Any]=4     ,SCREAMING_SNAKE_CASE__			:      int=True     ,SCREAMING_SNAKE_CASE__			:      Any=16     ,SCREAMING_SNAKE_CASE__			:      Optional[int]=2     ,SCREAMING_SNAKE_CASE__			:      Any=4     ,SCREAMING_SNAKE_CASE__			:      Union[str, Any]=4     ,SCREAMING_SNAKE_CASE__			:      str="gelu"     ,SCREAMING_SNAKE_CASE__			:      List[str]=0.1     ,SCREAMING_SNAKE_CASE__			:      Optional[Any]=0.1     ,SCREAMING_SNAKE_CASE__			:      List[str]=[1, 2, 3, 4, 5]     ,SCREAMING_SNAKE_CASE__			:      int=25     ,SCREAMING_SNAKE_CASE__			:      Optional[Any]=5     ,):
     SCREAMING_SNAKE_CASE:Dict						      =					d_model
     SCREAMING_SNAKE_CASE:Optional[int]						      =					parent
     SCREAMING_SNAKE_CASE:List[str]						      =					batch_size
     SCREAMING_SNAKE_CASE:Optional[Any]						      =					prediction_length
     SCREAMING_SNAKE_CASE:List[Any]						      =					context_length
     SCREAMING_SNAKE_CASE:Optional[Any]						      =					cardinality
     SCREAMING_SNAKE_CASE:int						      =					num_time_features
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					lags_sequence
     SCREAMING_SNAKE_CASE:str						      =					embedding_dimension
     SCREAMING_SNAKE_CASE:int						      =					is_training
     SCREAMING_SNAKE_CASE:Optional[int]						      =					hidden_size
     SCREAMING_SNAKE_CASE:Any						      =					num_hidden_layers
     SCREAMING_SNAKE_CASE:Dict						      =					num_attention_heads
     SCREAMING_SNAKE_CASE:Optional[Any]						      =					intermediate_size
     SCREAMING_SNAKE_CASE:Tuple						      =					hidden_act
     SCREAMING_SNAKE_CASE:Optional[int]						      =					hidden_dropout_prob
     SCREAMING_SNAKE_CASE:Optional[int]						      =					attention_probs_dropout_prob

     SCREAMING_SNAKE_CASE:Any						      =					context_length
     SCREAMING_SNAKE_CASE:Dict						      =					prediction_length + label_length
     SCREAMING_SNAKE_CASE:Optional[Any]						      =					label_length

     SCREAMING_SNAKE_CASE:Tuple						      =					moving_average
     SCREAMING_SNAKE_CASE:Tuple						      =					autocorrelation_factor
   def     __UpperCamelCase						( self			:      Optional[int]							):
     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     __UpperCamelCase						( self			:      Tuple     ,SCREAMING_SNAKE_CASE__			:      List[Any]							):
     SCREAMING_SNAKE_CASE:str						      =					config.context_length + max(config.lags_sequence							)

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

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

     SCREAMING_SNAKE_CASE:Tuple						      =					{
         "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     __UpperCamelCase						( self			:      List[Any]							):
     SCREAMING_SNAKE_CASE:Any						      =					self.get_config()
     SCREAMING_SNAKE_CASE:int						      =					self.prepare_autoformer_inputs_dict(__lowerCAmelCase							)
     return config, inputs_dict
   def     __UpperCamelCase						( self			:      Union[str, Any]							):
     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:Tuple						      =					self.prepare_config_and_inputs()
     return config, inputs_dict







   def     __UpperCamelCase						( self			:      str     ,SCREAMING_SNAKE_CASE__			:      List[str]     ,SCREAMING_SNAKE_CASE__			:      List[str]							):
     SCREAMING_SNAKE_CASE:Tuple						      =					AutoformerModel(config=__lowerCAmelCase							).to(__lowerCAmelCase							).eval()
     SCREAMING_SNAKE_CASE:Optional[int]						      =					model(**__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE:Optional[int]						      =					outputs.encoder_last_hidden_state
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					outputs.last_hidden_state

     with tempfile.TemporaryDirectory() as tmpdirname:
       SCREAMING_SNAKE_CASE:Tuple						      =					model.get_encoder()
       encoder.save_pretrained(__lowerCAmelCase							)
       SCREAMING_SNAKE_CASE:List[str]						      =					AutoformerEncoder.from_pretrained(__lowerCAmelCase							).to(__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:List[str]						      =					model.create_network_inputs(**__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:Tuple						      =					model.decomposition_layer(transformer_inputs[:, : config.context_length, ...]							)

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

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

     SCREAMING_SNAKE_CASE:Optional[Any]						      =					torch.cat(
         (
             torch.cat((seasonal_input[:, -config.label_length :, ...], zeros)     ,dim=1							),
             feature[:, config.context_length - config.label_length :, ...],
         )     ,dim=-1     ,)
     SCREAMING_SNAKE_CASE:Optional[int]						      =					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:
       SCREAMING_SNAKE_CASE:int						      =					model.get_decoder()
       decoder.save_pretrained(__lowerCAmelCase							)
       SCREAMING_SNAKE_CASE:List[str]						      =					AutoformerDecoder.from_pretrained(__lowerCAmelCase							).to(__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE:int						      =					decoder(
         trend=__lowerCAmelCase     ,inputs_embeds=__lowerCAmelCase     ,encoder_hidden_states=__lowerCAmelCase     ,)[0]

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





@require_torch
class 							_snake_case (       _a	,  _a	,  unittest.TestCase						):
   _A       :     Optional[Any]       =					(AutoformerModel, AutoformerForPrediction) if is_torch_available() else ()
   _A       :     Union[str, Any]       =					(AutoformerForPrediction,) if is_torch_available() else ()
   _A       :     Union[str, Any]       =					{'''feature-extraction''': AutoformerModel} if is_torch_available() else {}
   _A       :     List[Any]       =					False
   _A       :     int       =					False
   _A       :     Optional[Any]       =					False
   _A       :     int       =					False
   _A       :     List[Any]       =					False
   _A       :     Union[str, Any]       =					False
   def     __UpperCamelCase						( self			:      int							):
     SCREAMING_SNAKE_CASE:Tuple						      =					AutoformerModelTester(self							)
     SCREAMING_SNAKE_CASE:List[str]						      =					ConfigTester(self     ,config_class=__lowerCAmelCase     ,has_text_modality=__lowerCAmelCase							)
   def     __UpperCamelCase						( self			:      int							):
     self.config_tester.run_common_tests()
   def     __UpperCamelCase						( self			:      Optional[int]							):
     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:Optional[int]						      =					self.model_tester.prepare_config_and_inputs()
     for model_class in self.all_model_classes:
       SCREAMING_SNAKE_CASE:str						      =					model_class(__lowerCAmelCase							)

       with tempfile.TemporaryDirectory() as tmpdirname:
         model.save_pretrained(__lowerCAmelCase							)
         SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:List[str]						      =					model_class.from_pretrained(__lowerCAmelCase     ,output_loading_info=__lowerCAmelCase							)
       self.assertEqual(info["missing_keys"]     ,[]							)
   def     __UpperCamelCase						( self			:      Optional[Any]							):
     SCREAMING_SNAKE_CASE:Optional[int]						      =					self.model_tester.prepare_config_and_inputs_for_common()
     self.model_tester.check_encoder_decoder_model_standalone(*__lowerCAmelCase							)
   @unittest.skip(reason="Model has no tokens embeddings"							)
   def     __UpperCamelCase						( self			:      List[Any]							):
     pass
   def     __UpperCamelCase						( self			:      List[str]							):
     SCREAMING_SNAKE_CASE:Any						      =					inspect.signature(getattr(__lowerCAmelCase     ,"forward"							)							)
     # The main input is the name of the argument after `self`
     SCREAMING_SNAKE_CASE:str						      =					list(model_signature.parameters.keys()							)[1]
     self.assertEqual(AutoformerModel.main_input_name     ,__lowerCAmelCase							)
   def     __UpperCamelCase						( self			:      Dict							):
     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:Tuple						      =					self.model_tester.prepare_config_and_inputs_for_common()

     for model_class in self.all_model_classes:
       SCREAMING_SNAKE_CASE:str						      =					model_class(__lowerCAmelCase							)
       SCREAMING_SNAKE_CASE:Optional[Any]						      =					inspect.signature(model.forward							)
       # signature.parameters is an OrderedDict => so arg_names order is deterministic
       SCREAMING_SNAKE_CASE:Tuple						      =					[*signature.parameters.keys()]

       SCREAMING_SNAKE_CASE:List[Any]						      =					[
           "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(__lowerCAmelCase							)]     ,__lowerCAmelCase							)
   def     __UpperCamelCase						( self			:      str							):
     SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE:Optional[int]						      =					self.model_tester.prepare_config_and_inputs_for_common()
     SCREAMING_SNAKE_CASE:List[str]						      =					True

     SCREAMING_SNAKE_CASE:Tuple						      =					getattr(self.model_tester     ,"seq_length"     ,__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Optional[int]						      =					getattr(self.model_tester     ,"decoder_seq_length"     ,__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					getattr(self.model_tester     ,"encoder_seq_length"     ,__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Optional[int]						      =					getattr(self.model_tester     ,"d_model"     ,__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					getattr(self.model_tester     ,"num_attention_heads"     ,__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:str						      =					d_model // num_attention_heads

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

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

       self.assertListEqual(
           list(attentions[0].shape[-3:]							)     ,[self.model_tester.num_attention_heads, encoder_seq_length, dim]     ,)
       SCREAMING_SNAKE_CASE:List[str]						      =					len(__lowerCAmelCase							)

       SCREAMING_SNAKE_CASE:Optional[Any]						      =					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(__lowerCAmelCase     ,__lowerCAmelCase							)

       # decoder attentions
       SCREAMING_SNAKE_CASE:Union[str, Any]						      =					outputs.decoder_attentions
       self.assertIsInstance(__lowerCAmelCase     ,(list, tuple)							)
       self.assertEqual(len(__lowerCAmelCase							)     ,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
       SCREAMING_SNAKE_CASE:List[str]						      =					outputs.cross_attentions
       self.assertIsInstance(__lowerCAmelCase     ,(list, tuple)							)
       self.assertEqual(len(__lowerCAmelCase							)     ,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
     SCREAMING_SNAKE_CASE:List[Any]						      =					True
     SCREAMING_SNAKE_CASE:Optional[int]						      =					True
     SCREAMING_SNAKE_CASE:int						      =					model_class(__lowerCAmelCase							)
     model.to(__lowerCAmelCase							)
     model.eval()
     with torch.no_grad():
       SCREAMING_SNAKE_CASE:List[Any]						      =					model(**self._prepare_for_class(__lowerCAmelCase     ,__lowerCAmelCase							)							)

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

     SCREAMING_SNAKE_CASE:Dict						      =					outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions

     self.assertEqual(len(__lowerCAmelCase							)     ,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     __UpperCamelCase						( self			:      Tuple							):
     super().test_retain_grad_hidden_states_attentions()





def    A_  ( snake_case="train-batch.pt" ):
  SCREAMING_SNAKE_CASE:Dict						      =					hf_hub_download(repo_id="hf-internal-testing/tourism-monthly-batch"      ,       filename=__snake_case      ,       repo_type="dataset" )
  SCREAMING_SNAKE_CASE:Dict						      =					torch.load(__snake_case      ,       map_location=__snake_case )
  return batch





@require_torch
@slow
class 							_snake_case (       unittest.TestCase						):
   def     __UpperCamelCase						( self			:      Union[str, Any]							):
     SCREAMING_SNAKE_CASE:int						      =					AutoformerModel.from_pretrained("huggingface/autoformer-tourism-monthly"							).to(__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Dict						      =					prepare_batch()

     with torch.no_grad():
       SCREAMING_SNAKE_CASE: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]

     SCREAMING_SNAKE_CASE:Optional[int]						      =					torch.Size(
         (64, model.config.prediction_length + model.config.label_length, model.config.feature_size)							)
     self.assertEqual(output.shape     ,__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE:Tuple						      =					torch.tensor(
         [[0.3_593, -1.3_398, 0.6_330], [0.2_279, 1.5_396, -0.1_792], [0.0_450, 1.3_225, -0.2_335]]     ,device=__lowerCAmelCase							)
     self.assertTrue(torch.allclose(output[0, :3, :3]     ,__lowerCAmelCase     ,atol=__lowerCAmelCase							)							)
   def     __UpperCamelCase						( self			:      List[str]							):
     SCREAMING_SNAKE_CASE:List[str]						      =					AutoformerForPrediction.from_pretrained("huggingface/autoformer-tourism-monthly"							).to(__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Tuple						      =					prepare_batch("val-batch.pt"							)
     with torch.no_grad():
       SCREAMING_SNAKE_CASE:Any						      =					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
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					torch.Size((64, model.config.context_length, model.config.d_model)							)
     self.assertEqual(output.shape     ,__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE:List[str]						      =					torch.tensor(
         [[-0.0_734, -0.9_036, 0.8_358], [4.7_186, 2.4_113, 1.9_581], [1.7_953, 2.3_558, 1.2_970]]     ,device=__lowerCAmelCase							)
     self.assertTrue(torch.allclose(output[0, :3, :3]     ,__lowerCAmelCase     ,atol=__lowerCAmelCase							)							)







   def     __UpperCamelCase						( self			:      Dict							):
     SCREAMING_SNAKE_CASE:Dict						      =					AutoformerForPrediction.from_pretrained("huggingface/autoformer-tourism-monthly"							).to(__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Optional[int]						      =					prepare_batch("val-batch.pt"							)
     with torch.no_grad():
       SCREAMING_SNAKE_CASE:Dict						      =					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"]     ,)
     SCREAMING_SNAKE_CASE:Any						      =					torch.Size((64, model.config.num_parallel_samples, model.config.prediction_length)							)
     self.assertEqual(outputs.sequences.shape     ,__lowerCAmelCase							)

     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					torch.tensor([3_130.6_763, 4_056.5_293, 7_053.0_786]     ,device=__lowerCAmelCase							)
     SCREAMING_SNAKE_CASE:Dict						      =					outputs.sequences.mean(dim=1							)
     self.assertTrue(torch.allclose(mean_prediction[0, -3:]     ,__lowerCAmelCase     ,rtol=1e-1							)							)









'''simple docstring'''

from importlib import import_module

from .logging import get_logger


A_       						=							get_logger(__name__)





class 							_snake_case :
   def __init__( self			:      Dict     ,SCREAMING_SNAKE_CASE__			:      Any     ,SCREAMING_SNAKE_CASE__			:      Dict=None							):
     SCREAMING_SNAKE_CASE:Any						      =					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__							)							)
     SCREAMING_SNAKE_CASE:Any						      =					module._original_module if isinstance(SCREAMING_SNAKE_CASE__     ,_PatchedModuleObj							) else module





class 							_snake_case :
   _A       :     Any       =					[]
   def __init__( self			:      Any     ,SCREAMING_SNAKE_CASE__			:      List[str]     ,SCREAMING_SNAKE_CASE__			:      str     ,SCREAMING_SNAKE_CASE__			:      str     ,SCREAMING_SNAKE_CASE__			:      Optional[Any]=None							):
     SCREAMING_SNAKE_CASE:Any						      =					obj
     SCREAMING_SNAKE_CASE:Any						      =					target
     SCREAMING_SNAKE_CASE:Union[str, Any]						      =					new
     SCREAMING_SNAKE_CASE:Any						      =					target.split("."							)[0]
     SCREAMING_SNAKE_CASE:str						      =					{}
     SCREAMING_SNAKE_CASE:List[Any]						      =					attrs or []
   def __enter__( self			:      Tuple							):
     *SCREAMING_SNAKE_CASE      ,    SCREAMING_SNAKE_CASE: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:
         SCREAMING_SNAKE_CASE: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__():
         SCREAMING_SNAKE_CASE:str						      =					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)
         ):
           SCREAMING_SNAKE_CASE:Union[str, Any]						      =					obj_attr
           # patch at top level
           setattr(self.obj     ,SCREAMING_SNAKE_CASE__     ,_PatchedModuleObj(SCREAMING_SNAKE_CASE__     ,attrs=self.attrs							)							)
           SCREAMING_SNAKE_CASE:int						      =					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							)							)
             SCREAMING_SNAKE_CASE:Dict						      =					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:
         SCREAMING_SNAKE_CASE: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:
           SCREAMING_SNAKE_CASE:Union[str, Any]						      =					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"
       SCREAMING_SNAKE_CASE:int						      =					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			:      List[Any]     ,*SCREAMING_SNAKE_CASE__			:      Union[str, Any]							):
     for attr in list(self.original							):
       setattr(self.obj     ,SCREAMING_SNAKE_CASE__     ,self.original.pop(SCREAMING_SNAKE_CASE__							)							)
   def     __UpperCamelCase						( self			:      Optional[int]							):
     self.__enter__()
     self._active_patches.append(self							)







   def     __UpperCamelCase						( 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__()






