

import inspect
import os
from argparse import ArgumentParser, Namespace
from importlib import import_module

import huggingface_hub
import numpy as np
from packaging import version

from .. import (
    FEATURE_EXTRACTOR_MAPPING,
    IMAGE_PROCESSOR_MAPPING,
    PROCESSOR_MAPPING,
    TOKENIZER_MAPPING,
    AutoConfig,
    AutoFeatureExtractor,
    AutoImageProcessor,
    AutoProcessor,
    AutoTokenizer,
    is_datasets_available,
    is_tf_available,
    is_torch_available,
)
from ..utils import TF2_WEIGHTS_INDEX_NAME, TF2_WEIGHTS_NAME, logging
from . import BaseTransformersCLICommand


if is_tf_available():
  import tensorflow as tf

  tf.config.experimental.enable_tensor_float_aa_execution(False)

if is_torch_available():
  import torch

if is_datasets_available():
  from datasets import load_dataset


UpperCAmelCase__	:       Optional[Any]			      =      5E-5  # larger error tolerance than in our internal tests, to avoid flaky user-facing errors






def    __lowercase (       _A     )       ->  Union[str, Any]:
      return PTtoTFCommand(
          args.model_name  ,      args.local_dir  ,      args.max_error  ,      args.new_weights  ,      args.no_pr  ,      args.push  ,      args.extra_commit_description  ,      args.override_model_class  ,      )







class     a__    (				UpperCAmelCase    ):







  """simple docstring"""




  @staticmethod
  def 	_lowercase (     UpperCAmelCase__      :	ArgumentParser						)   ->Union[str, Any]:
        """simple docstring"""







        SCREAMING_SNAKE_CASE	: str					       =				parser.add_parser(
            """pt-to-tf"""			,			help=(
                """CLI tool to run convert a transformers model from a PyTorch checkpoint to a TensorFlow checkpoint."""
                """ Can also be used to validate existing weights without opening PRs, with --no-pr."""
            )			,			)
        train_parser.add_argument(
            """--model-name"""			,			type=UpperCAmelCase__			,			required=UpperCAmelCase__			,			help="""The model name, including owner/organization, as seen on the hub."""			,			)
        train_parser.add_argument(
            """--local-dir"""			,			type=UpperCAmelCase__			,			default=""""""			,			help="""Optional local directory of the model repository. Defaults to /tmp/{model_name}"""			,			)
        train_parser.add_argument(
            """--max-error"""			,			type=UpperCAmelCase__			,			default=UpperCAmelCase__			,			help=(
                f"Maximum error tolerance. Defaults to {MAX_ERROR}. This flag should be avoided, use at your own risk."
            )			,			)
        train_parser.add_argument(
            """--new-weights"""			,			action="""store_true"""			,			help="""Optional flag to create new TensorFlow weights, even if they already exist."""			,			)
        train_parser.add_argument(
            """--no-pr"""			,			action="""store_true"""			,			help="""Optional flag to NOT open a PR with converted weights."""						)
        train_parser.add_argument(
            """--push"""			,			action="""store_true"""			,			help="""Optional flag to push the weights directly to `main` (requires permissions)"""			,			)
        train_parser.add_argument(
            """--extra-commit-description"""			,			type=UpperCAmelCase__			,			default=""""""			,			help="""Optional additional commit description to use when opening a PR (e.g. to tag the owner)."""			,			)
        train_parser.add_argument(
            """--override-model-class"""			,			type=UpperCAmelCase__			,			default=UpperCAmelCase__			,			help="""If you think you know better than the auto-detector, you can specify the model class here. """
            """Can be either an AutoModel class or a specific model class like BertForSequenceClassification."""			,			)
        train_parser.set_defaults(func=UpperCAmelCase__						)


  @staticmethod
  def 	_lowercase (     UpperCAmelCase__      :	List[Any]			,			UpperCAmelCase__      :	List[Any]						)   ->Union[str, Any]:
        """simple docstring"""







        SCREAMING_SNAKE_CASE	: int					       =				set(pt_outputs.keys()						)
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				set(tf_outputs.keys()						)
        if pt_out_attrs != tf_out_attrs:
              raise ValueError(
                  f"The model outputs have different attributes, aborting. (Pytorch: {pt_out_attrs}, TensorFlow:"
                  f" {tf_out_attrs})"						)

        # 2. For each output attribute, computes the difference
        def _find_pt_tf_differences(UpperCAmelCase__      :	Dict			,			UpperCAmelCase__      :	Tuple			,			UpperCAmelCase__      :	Optional[Any]			,			UpperCAmelCase__      :	List[str]=""						):
              # If the current attribute is a tensor, it is a leaf and we make the comparison. Otherwise, we will dig in
              # recursivelly, keeping the name of the attribute.
              if isinstance(UpperCAmelCase__			,			torch.Tensor						):
                    SCREAMING_SNAKE_CASE	: Optional[Any]					       =				np.max(np.abs(pt_out.numpy() - tf_out.numpy()						)						)
                    SCREAMING_SNAKE_CASE	: Dict					       =				tensor_difference
              else:
                    SCREAMING_SNAKE_CASE	: List[str]					       =				attr_name
                    for i, pt_item in enumerate(UpperCAmelCase__						):
                          # If it is a named attribute, we keep the name. Otherwise, just its index.
                          if isinstance(UpperCAmelCase__			,			UpperCAmelCase__						):
                                SCREAMING_SNAKE_CASE	: List[Any]					       =				root_name + pt_item
                                SCREAMING_SNAKE_CASE	: Tuple					       =				tf_out[pt_item]
                                SCREAMING_SNAKE_CASE	: Optional[Any]					       =				pt_out[pt_item]
                          else:
                                SCREAMING_SNAKE_CASE	: str					       =				root_name + f"[{i}]"
                                SCREAMING_SNAKE_CASE	: Optional[int]					       =				tf_out[i]
                          SCREAMING_SNAKE_CASE	: str					       =				_find_pt_tf_differences(UpperCAmelCase__			,			UpperCAmelCase__			,			UpperCAmelCase__			,			UpperCAmelCase__						)

              return differences

        return _find_pt_tf_differences(UpperCAmelCase__			,			UpperCAmelCase__			,			{}						)


  def __init__(     self      :	int			,			UpperCAmelCase__      :	str			,			UpperCAmelCase__      :	str			,			UpperCAmelCase__      :	float			,			UpperCAmelCase__      :	bool			,			UpperCAmelCase__      :	bool			,			UpperCAmelCase__      :	bool			,			UpperCAmelCase__      :	str			,			UpperCAmelCase__      :	str			,			*UpperCAmelCase__      :	List[str]			,			)   ->List[Any]:
        """simple docstring"""







        SCREAMING_SNAKE_CASE	: str					       =				logging.get_logger("""transformers-cli/pt_to_tf"""						)
        SCREAMING_SNAKE_CASE	: str					       =				model_name
        SCREAMING_SNAKE_CASE	: Tuple					       =				local_dir if local_dir else os.path.join("""/tmp"""			,			UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: Optional[Any]					       =				max_error
        SCREAMING_SNAKE_CASE	: List[Any]					       =				new_weights
        SCREAMING_SNAKE_CASE	: Dict					       =				no_pr
        SCREAMING_SNAKE_CASE	: Tuple					       =				push
        SCREAMING_SNAKE_CASE	: List[str]					       =				extra_commit_description
        SCREAMING_SNAKE_CASE	: List[str]					       =				override_model_class


  def 	_lowercase (     self      :	List[Any]			,			UpperCAmelCase__      :	List[str]			,			UpperCAmelCase__      :	Optional[int]			,			UpperCAmelCase__      :	Tuple						)   ->List[Any]:
        """simple docstring"""







        def _get_audio_input():
              SCREAMING_SNAKE_CASE	: Any					       =				load_dataset("""hf-internal-testing/librispeech_asr_dummy"""			,			"""clean"""			,			split="""validation"""						)
              SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				ds.sort("""id"""						).select(range(2						)						)[:2]["""audio"""]
              SCREAMING_SNAKE_CASE	: Optional[Any]					       =				[x["""array"""] for x in speech_samples]
              return raw_samples

        SCREAMING_SNAKE_CASE	: List[str]					       =				type(pt_model.config						)
        if model_config_class in PROCESSOR_MAPPING:
              SCREAMING_SNAKE_CASE	: Optional[Any]					       =				AutoProcessor.from_pretrained(self._local_dir						)
              if model_config_class in TOKENIZER_MAPPING and processor.tokenizer.pad_token is None:
                    SCREAMING_SNAKE_CASE	: int					       =				processor.tokenizer.eos_token
        elif model_config_class in IMAGE_PROCESSOR_MAPPING:
              SCREAMING_SNAKE_CASE	: str					       =				AutoImageProcessor.from_pretrained(self._local_dir						)
        elif model_config_class in FEATURE_EXTRACTOR_MAPPING:
              SCREAMING_SNAKE_CASE	: List[str]					       =				AutoFeatureExtractor.from_pretrained(self._local_dir						)
        elif model_config_class in TOKENIZER_MAPPING:
              SCREAMING_SNAKE_CASE	: Tuple					       =				AutoTokenizer.from_pretrained(self._local_dir						)
              if processor.pad_token is None:
                    SCREAMING_SNAKE_CASE	: List[str]					       =				processor.eos_token
        else:
              raise ValueError(f"Unknown data processing type (model config type: {model_config_class})"						)

        SCREAMING_SNAKE_CASE	: str					       =				set(inspect.signature(pt_model.forward						).parameters.keys()						)
        SCREAMING_SNAKE_CASE	: Optional[Any]					       =				{}
        if "input_ids" in model_forward_signature:
              processor_inputs.update(
                  {
                      """text""": ["""Hi there!""", """I am a batch with more than one row and different input lengths."""],
                      """padding""": True,
                      """truncation""": True,
                  }						)
        if "pixel_values" in model_forward_signature:
              SCREAMING_SNAKE_CASE	: str					       =				load_dataset("""cifar10"""			,			"""plain_text"""			,			split="""test"""						)[:2]["""img"""]
              processor_inputs.update({"""images""": sample_images}						)
        if "input_features" in model_forward_signature:
              SCREAMING_SNAKE_CASE	: List[Any]					       =				inspect.signature(processor.feature_extractor						).parameters
              # Pad to the largest input length by default but take feature extractor default
              # padding value if it exists e.g. "max_length" and is not False or None
              if "padding" in feature_extractor_signature:
                    SCREAMING_SNAKE_CASE	: List[Any]					       =				feature_extractor_signature["""padding"""].default
                    if default_strategy is not False and default_strategy is not None:
                          SCREAMING_SNAKE_CASE	: List[Any]					       =				default_strategy
                    else:
                          SCREAMING_SNAKE_CASE	: int					       =				True
              else:
                    SCREAMING_SNAKE_CASE	: int					       =				True
              processor_inputs.update({"""audio""": _get_audio_input(), """padding""": padding_strategy}						)
        if "input_values" in model_forward_signature:  # Wav2Vec2 audio input
              processor_inputs.update({"""audio""": _get_audio_input(), """padding""": True}						)
        SCREAMING_SNAKE_CASE	: int					       =				processor(**UpperCAmelCase__			,			return_tensors="""pt"""						)
        SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				processor(**UpperCAmelCase__			,			return_tensors="""tf"""						)

        # Extra input requirements, in addition to the input modality
        if (
            config.is_encoder_decoder
            or (hasattr(UpperCAmelCase__			,			"""encoder"""						) and hasattr(UpperCAmelCase__			,			"""decoder"""						))
            or "decoder_input_ids" in tf_dummy_inputs
        ):
              SCREAMING_SNAKE_CASE	: List[str]					       =				np.asarray([[1], [1]]			,			dtype=UpperCAmelCase__						) * (pt_model.config.decoder_start_token_id or 0)
              pt_input.update({"""decoder_input_ids""": torch.tensor(UpperCAmelCase__						)}						)
              tf_input.update({"""decoder_input_ids""": tf.convert_to_tensor(UpperCAmelCase__						)}						)

        return pt_input, tf_input




  def 	_lowercase (     self      :	Dict						)   ->Optional[int]:
        """simple docstring"""







        if version.parse(huggingface_hub.__version__						) < version.parse("""0.9.0"""						):
              raise ImportError(
                  """The huggingface_hub version must be >= 0.9.0 to use this command. Please update your huggingface_hub"""
                  """ installation."""						)
        else:
              from huggingface_hub import Repository, create_commit
              from huggingface_hub._commit_api import CommitOperationAdd

        # Fetch remote data
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				Repository(local_dir=self._local_dir			,			clone_from=self._model_name						)

        # Load config and get the appropriate architecture -- the latter is needed to convert the head's weights
        SCREAMING_SNAKE_CASE	: Optional[Any]					       =				AutoConfig.from_pretrained(self._local_dir						)
        SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				config.architectures
        if self._override_model_class is not None:
              if self._override_model_class.startswith("""TF"""						):
                    SCREAMING_SNAKE_CASE	: str					       =				[self._override_model_class[2:]]
              else:
                    SCREAMING_SNAKE_CASE	: Dict					       =				[self._override_model_class]
              try:
                    SCREAMING_SNAKE_CASE	: int					       =				getattr(import_module("""transformers"""						)			,			architectures[0]						)
              except AttributeError:
                    raise ValueError(f"Model class {self._override_model_class} not found in transformers."						)
              try:
                    SCREAMING_SNAKE_CASE	: List[str]					       =				getattr(import_module("""transformers"""						)			,			"""TF""" + architectures[0]						)
              except AttributeError:
                    raise ValueError(f"TF model class TF{self._override_model_class} not found in transformers."						)
        elif architectures is None:  # No architecture defined -- use auto classes
              SCREAMING_SNAKE_CASE	: str					       =				getattr(import_module("""transformers"""						)			,			"""AutoModel"""						)
              SCREAMING_SNAKE_CASE	: str					       =				getattr(import_module("""transformers"""						)			,			"""TFAutoModel"""						)
              self._logger.warning("""No detected architecture, using AutoModel/TFAutoModel"""						)
        else:  # Architecture defined -- use it
              if len(UpperCAmelCase__						) > 1:
                    raise ValueError(f"More than one architecture was found, aborting. (architectures = {architectures})"						)
              self._logger.warning(f"Detected architecture: {architectures[0]}"						)
              SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				getattr(import_module("""transformers"""						)			,			architectures[0]						)
              try:
                    SCREAMING_SNAKE_CASE	: int					       =				getattr(import_module("""transformers"""						)			,			"""TF""" + architectures[0]						)
              except AttributeError:
                    raise AttributeError(f"The TensorFlow equivalent of {architectures[0]} doesn't exist in transformers."						)

        # Check the TF dummy inputs to see what keys we need in the forward pass
        SCREAMING_SNAKE_CASE	: List[str]					       =				tf_class.from_config(UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				tf_from_pt_model.dummy_inputs

        del tf_from_pt_model  # Try to keep only one model in memory at a time

        # Load the model and get some basic inputs
        SCREAMING_SNAKE_CASE	: Optional[Any]					       =				pt_class.from_pretrained(self._local_dir						)
        pt_model.eval()

        SCREAMING_SNAKE_CASE	: List[Any]					       =				self.get_inputs(UpperCAmelCase__			,			UpperCAmelCase__			,			UpperCAmelCase__						)

        with torch.no_grad():
              SCREAMING_SNAKE_CASE	: List[Any]					       =				pt_model(**UpperCAmelCase__			,			output_hidden_states=UpperCAmelCase__						)
        del pt_model  # will no longer be used, and may have a large memory footprint

        SCREAMING_SNAKE_CASE	: Tuple					       =				tf_class.from_pretrained(self._local_dir			,			from_pt=UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: List[str]					       =				tf_from_pt_model(**UpperCAmelCase__			,			output_hidden_states=UpperCAmelCase__			,			training=UpperCAmelCase__						)

        # Confirms that cross loading PT weights into TF worked.
        SCREAMING_SNAKE_CASE	: List[str]					       =				self.find_pt_tf_differences(UpperCAmelCase__			,			UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				{k: v for k, v in crossload_differences.items() if """hidden""" not in k}
        SCREAMING_SNAKE_CASE	: Dict					       =				{k: v for k, v in crossload_differences.items() if """hidden""" in k}
        if len(UpperCAmelCase__						) == 0 and architectures is not None:
              raise ValueError(
                  f"Something went wrong -- the config file has architectures ({architectures}), but no model head"
                  """ output was found. All outputs start with 'hidden'"""						)
        SCREAMING_SNAKE_CASE	: Any					       =				max(output_differences.values()						) if output_differences else 0.0
        SCREAMING_SNAKE_CASE	: Dict					       =				max(hidden_differences.values()						)
        if max_crossload_output_diff > self._max_error or max_crossload_hidden_diff > self._max_error:
              raise ValueError(
                  """The cross-loaded TensorFlow model has different outputs, something went wrong!\n"""
                  + f"\nList of maximum output differences above the threshold ({self._max_error}):\n"
                  + """\n""".join([f"{k}: {v:.3e}" for k, v in output_differences.items() if v > self._max_error]						)
                  + f"\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"
                  + """\n""".join([f"{k}: {v:.3e}" for k, v in hidden_differences.items() if v > self._max_error]						)						)

        # Save the weights in a TF format (if needed) and confirms that the results are still good
        SCREAMING_SNAKE_CASE	: int					       =				os.path.join(self._local_dir			,			UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: Tuple					       =				os.path.join(self._local_dir			,			UpperCAmelCase__						)
        if (not os.path.exists(UpperCAmelCase__						) and not os.path.exists(UpperCAmelCase__						)) or self._new_weights:
              tf_from_pt_model.save_pretrained(self._local_dir						)
        del tf_from_pt_model  # will no longer be used, and may have a large memory footprint

        SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				tf_class.from_pretrained(self._local_dir						)
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				tf_model(**UpperCAmelCase__			,			output_hidden_states=UpperCAmelCase__						)

        SCREAMING_SNAKE_CASE	: List[Any]					       =				self.find_pt_tf_differences(UpperCAmelCase__			,			UpperCAmelCase__						)
        SCREAMING_SNAKE_CASE	: int					       =				{k: v for k, v in conversion_differences.items() if """hidden""" not in k}
        SCREAMING_SNAKE_CASE	: Optional[int]					       =				{k: v for k, v in conversion_differences.items() if """hidden""" in k}
        if len(UpperCAmelCase__						) == 0 and architectures is not None:
              raise ValueError(
                  f"Something went wrong -- the config file has architectures ({architectures}), but no model head"
                  """ output was found. All outputs start with 'hidden'"""						)
        SCREAMING_SNAKE_CASE	: int					       =				max(output_differences.values()						) if output_differences else 0.0
        SCREAMING_SNAKE_CASE	: List[str]					       =				max(hidden_differences.values()						)
        if max_conversion_output_diff > self._max_error or max_conversion_hidden_diff > self._max_error:
              raise ValueError(
                  """The converted TensorFlow model has different outputs, something went wrong!\n"""
                  + f"\nList of maximum output differences above the threshold ({self._max_error}):\n"
                  + """\n""".join([f"{k}: {v:.3e}" for k, v in output_differences.items() if v > self._max_error]						)
                  + f"\n\nList of maximum hidden layer differences above the threshold ({self._max_error}):\n"
                  + """\n""".join([f"{k}: {v:.3e}" for k, v in hidden_differences.items() if v > self._max_error]						)						)

        SCREAMING_SNAKE_CASE	: Optional[Any]					       =				"""Update TF weights""" if self._new_weights else """Add TF weights"""
        if self._push:
              repo.git_add(auto_lfs_track=UpperCAmelCase__						)
              repo.git_commit(UpperCAmelCase__						)
              repo.git_push(blocking=UpperCAmelCase__						)  # this prints a progress bar with the upload
              self._logger.warning(f"TF weights pushed into {self._model_name}"						)
        elif not self._no_pr:
              self._logger.warning("""Uploading the weights into a new PR..."""						)
              SCREAMING_SNAKE_CASE	: Union[str, Any]					       =				(
                  """Model converted by the [`transformers`' `pt_to_tf`"""
                  """ CLI](https://github.com/huggingface/transformers/blob/main/src/transformers/commands/pt_to_tf.py). """
                  """All converted model outputs and hidden layers were validated against its PyTorch counterpart.\n\n"""
                  f"Maximum crossload output difference={max_crossload_output_diff:.3e}; "
                  f"Maximum crossload hidden layer difference={max_crossload_hidden_diff:.3e};\n"
                  f"Maximum conversion output difference={max_conversion_output_diff:.3e}; "
                  f"Maximum conversion hidden layer difference={max_conversion_hidden_diff:.3e};\n"
              )
              if self._max_error > MAX_ERROR:
                    commit_descrition += (
                        f"\n\nCAUTION: The maximum admissible error was manually increased to {self._max_error}!"
                    )
              if self._extra_commit_description:
                    commit_descrition += "\n\n" + self._extra_commit_description

              # sharded model -> adds all related files (index and .h5 shards)
              if os.path.exists(UpperCAmelCase__						):
                    SCREAMING_SNAKE_CASE	: Dict					       =				[
                        CommitOperationAdd(path_in_repo=UpperCAmelCase__			,			path_or_fileobj=UpperCAmelCase__						)
                    ]
                    for shard_path in tf.io.gfile.glob(self._local_dir + """/tf_model-*.h5"""						):
                          operations += [
                              CommitOperationAdd(path_in_repo=os.path.basename(UpperCAmelCase__						)			,			path_or_fileobj=UpperCAmelCase__						)
                          ]
              else:
                    SCREAMING_SNAKE_CASE	: List[Any]					       =				[CommitOperationAdd(path_in_repo=UpperCAmelCase__			,			path_or_fileobj=UpperCAmelCase__						)]

              SCREAMING_SNAKE_CASE	: Any					       =				create_commit(
                  repo_id=self._model_name			,			operations=UpperCAmelCase__			,			commit_message=UpperCAmelCase__			,			commit_description=UpperCAmelCase__			,			repo_type="""model"""			,			create_pr=UpperCAmelCase__			,			).pr_url
              self._logger.warning(f"PR open in {hub_pr_url}"						)







from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_sentencepiece_available,
    is_speech_available,
    is_torch_available,
)


UpperCAmelCase__	:       int			      =      {
    """configuration_speech_to_text_2""": ["""SPEECH_TO_TEXT_2_PRETRAINED_CONFIG_ARCHIVE_MAP""", """Speech2Text2Config"""],
    """processing_speech_to_text_2""": ["""Speech2Text2Processor"""],
    """tokenization_speech_to_text_2""": ["""Speech2Text2Tokenizer"""],
}


try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  UpperCAmelCase__	:       int			      =      [
      """SPEECH_TO_TEXT_2_PRETRAINED_MODEL_ARCHIVE_LIST""",
      """Speech2Text2ForCausalLM""",
      """Speech2Text2PreTrainedModel""",
  ]


if TYPE_CHECKING:
  from .configuration_speech_to_text_a import SPEECH_TO_TEXT_2_PRETRAINED_CONFIG_ARCHIVE_MAP, SpeechaTextaConfig
  from .processing_speech_to_text_a import SpeechaTextaProcessor
  from .tokenization_speech_to_text_a import SpeechaTextaTokenizer

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_speech_to_text_a import (
        SPEECH_TO_TEXT_2_PRETRAINED_MODEL_ARCHIVE_LIST,
        SpeechaTextaForCausalLM,
        SpeechaTextaPreTrainedModel,
    )

else:
  import sys

  UpperCAmelCase__	:       int			      =      _LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)




