class_docstr: Base class for all TVTensors.
  
  You probably don't want to use this class unless you're defining your own
  custom TVTensors. See
  :ref:`sphx_glr_auto_examples_transforms_plot_custom_tv_tensors.py` for details.
class_docstr_tok: ["Base","class","for","all","TVTensors",".","You","probably","do","n't","want","to","use","this","class","unless","you","'re","defining","your","own","custom","TVTensors",".","See",":","ref",":","`","sphx_glr_auto_examples_transforms_plot_custom_tv_tensors.py","`","for","details","."]
docstr: For general information about how the __torch_function__ protocol works,
  see https://pytorch.org/docs/stable/notes/extending.html#extending-torch
  
  TL;DR: Every time a PyTorch operator is called, it goes through the inputs and looks for the
  ``__torch_function__`` method. If one is found, it is invoked with the operator as ``func`` as well as the
  ``args`` and ``kwargs`` of the original call.
  
  Why do we override this? Because the base implementation in torch.Tensor would preserve the TVTensor type
  of the output. In our case, we want to return pure tensors instead (with a few exceptions). Refer to the
  "TVTensors FAQ" gallery example for a rationale of this behaviour (TL;DR: perf + no silver bullet).
  
  Our implementation below is very similar to the base implementation in ``torch.Tensor`` - go check it out.
docstr_tok: ["For","general","information","about","how","the","__torch_function__","protocol","works",",","see","https",":","\/\/pytorch.org\/docs\/stable\/notes\/extending.html","#","extending-torch","TL",";","DR",":","Every","time","a","PyTorch","operator","is","called",",","it","goes","through","the","inputs","and","looks","for","the","``","__torch_function__","``","method",".","If","one","is","found",",","it","is","invoked","with","the","operator","as","``","func","``","as","well","as","the","``","args","``","and","``","kwargs","``","of","the","original","call",".","Why","do","we","override","this","?","Because","the","base","implementation","in","torch.Tensor","would","preserve","the","TVTensor","type","of","the","output",".","In","our","case",",","we","want","to","return","pure","tensors","instead","(","with","a","few","exceptions",")",".","Refer","to","the","''","TVTensors","FAQ","''","gallery","example","for","a","rationale","of","this","behaviour","(","TL",";","DR",":","perf","+","no","silver","bullet",")",".","Our","implementation","below","is","very","similar","to","the","base","implementation","in","``","torch.Tensor","``","-","go","check","it","out","."]
code: def __torch_function__(
      cls,
      func: Callable[..., torch.Tensor],
      types: Tuple[Type[torch.Tensor], ...],
      args: Sequence[Any] = (),
      kwargs: Optional[Mapping[str, Any]] = None,
  ) -> torch.Tensor:
      """For general information about how the __torch_function__ protocol works,
      see https://pytorch.org/docs/stable/notes/extending.html#extending-torch
  
      TL;DR: Every time a PyTorch operator is called, it goes through the inputs and looks for the
      ``__torch_function__`` method. If one is found, it is invoked with the operator as ``func`` as well as the
      ``args`` and ``kwargs`` of the original call.
  
      Why do we override this? Because the base implementation in torch.Tensor would preserve the TVTensor type
      of the output. In our case, we want to return pure tensors instead (with a few exceptions). Refer to the
      "TVTensors FAQ" gallery example for a rationale of this behaviour (TL;DR: perf + no silver bullet).
  
      Our implementation below is very similar to the base implementation in ``torch.Tensor`` - go check it out.
      """
      if not all(issubclass(cls, t) for t in types):
          return NotImplemented
  
      # Like in the base Tensor.__torch_function__ implementation, it's easier to always use
      # DisableTorchFunctionSubclass and then manually re-wrap the output if necessary
      with DisableTorchFunctionSubclass():
          output = func(*args, **kwargs or dict())
  
      must_return_subclass = _must_return_subclass()
      if must_return_subclass or (
          func in _FORCE_TORCHFUNCTION_SUBCLASS
          and isinstance(args[0], cls)
      ):
          # If you're wondering why we need the `isinstance(args[0], cls)` check, remove it and see what fails
          # in test_to_tv_tensor_reference().
          # The __torch_function__ protocol will invoke the __torch_function__ method on *all* types involved in
          # the computation by walking the MRO upwards. For example,
          # `out = a_pure_tensor.to(an_image)` will invoke `Image.__torch_function__` with
          # `args = (a_pure_tensor, an_image)` first. Without this guard, `out` would
          # be wrapped into an `Image`.
          return cls._wrap_output(output, args, kwargs)
  
      if not must_return_subclass and isinstance(output, cls):
          # DisableTorchFunctionSubclass is ignored by inplace ops like `.add_(...)`,
          # so for those, the output is still a TVTensor. Thus, we need to manually unwrap.
          return output.as_subclass(torch.Tensor)
  
      return output
  
file_path: vision/torchvision/tv_tensors/_tv_tensor.py
imports: from __future__ import annotations
  from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Tuple, Type, TypeVar, Union
  import torch
  from torch._C import DisableTorchFunctionSubclass
  from torch.types import _device, _dtype, _size
  from torchvision.tv_tensors._torch_function_helpers import _FORCE_TORCHFUNCTION_SUBCLASS, _must_return_subclass
label_desc: Use image node_id 3 for calling the TVTensor obj's underlying member method code with example usage: obj.__torch_function__(cls, func, types, args, kwargs) and returns: output, NotImplemented, cls, output