diff --git a/test/common_extended_utils.py b/test/common_extended_utils.py index a34e15629bb..adb794f5db6 100644 --- a/test/common_extended_utils.py +++ b/test/common_extended_utils.py @@ -1,7 +1,7 @@ import os from collections import defaultdict from numbers import Number -from typing import Any, List +from typing import Any import torch from torch.utils._python_dispatch import TorchDispatchMode @@ -30,7 +30,7 @@ def prod(x): return res -def matmul_flop(inputs: List[Any], outputs: List[Any]) -> Number: +def matmul_flop(inputs: list[Any], outputs: list[Any]) -> Number: """ Count flops for matmul. """ @@ -43,7 +43,7 @@ def matmul_flop(inputs: List[Any], outputs: List[Any]) -> Number: return flop -def addmm_flop(inputs: List[Any], outputs: List[Any]) -> Number: +def addmm_flop(inputs: list[Any], outputs: list[Any]) -> Number: """ Count flops for fully connected layers. """ @@ -60,7 +60,7 @@ def addmm_flop(inputs: List[Any], outputs: List[Any]) -> Number: return flops -def bmm_flop(inputs: List[Any], outputs: List[Any]) -> Number: +def bmm_flop(inputs: list[Any], outputs: list[Any]) -> Number: """ Count flops for the bmm operation. """ @@ -75,9 +75,9 @@ def bmm_flop(inputs: List[Any], outputs: List[Any]) -> Number: def conv_flop_count( - x_shape: List[int], - w_shape: List[int], - out_shape: List[int], + x_shape: list[int], + w_shape: list[int], + out_shape: list[int], transposed: bool = False, ) -> Number: """ @@ -99,7 +99,7 @@ def conv_flop_count( return flop -def conv_flop(inputs: List[Any], outputs: List[Any]): +def conv_flop(inputs: list[Any], outputs: list[Any]): """ Count flops for convolution. """ @@ -110,7 +110,7 @@ def conv_flop(inputs: List[Any], outputs: List[Any]): return conv_flop_count(x_shape, w_shape, out_shape, transposed=transposed) -def quant_conv_flop(inputs: List[Any], outputs: List[Any]): +def quant_conv_flop(inputs: list[Any], outputs: list[Any]): """ Count flops for quantized convolution. """ @@ -124,8 +124,8 @@ def transpose_shape(shape): return [shape[1], shape[0]] + list(shape[2:]) -def conv_backward_flop(inputs: List[Any], outputs: List[Any]): - grad_out_shape, x_shape, w_shape = [get_shape(i) for i in inputs[:3]] +def conv_backward_flop(inputs: list[Any], outputs: list[Any]): + grad_out_shape, x_shape, w_shape = (get_shape(i) for i in inputs[:3]) output_mask = inputs[-1] fwd_transposed = inputs[7] flop_count = 0 @@ -140,7 +140,7 @@ def conv_backward_flop(inputs: List[Any], outputs: List[Any]): return flop_count -def scaled_dot_product_flash_attention_flop(inputs: List[Any], outputs: List[Any]): +def scaled_dot_product_flash_attention_flop(inputs: list[Any], outputs: list[Any]): # FIXME: this needs to count the flops of this kernel # https://github.com/pytorch/pytorch/blob/207b06d099def9d9476176a1842e88636c1f714f/aten/src/ATen/native/cpu/FlashAttentionKernel.cpp#L52-L267 return 0 diff --git a/test/common_utils.py b/test/common_utils.py index 9acbd9f9ab8..b3a26dfd441 100644 --- a/test/common_utils.py +++ b/test/common_utils.py @@ -285,7 +285,7 @@ def __init__( **other_parameters, ): if all(isinstance(input, PIL.Image.Image) for input in [actual, expected]): - actual, expected = [to_image(input) for input in [actual, expected]] + actual, expected = (to_image(input) for input in [actual, expected]) super().__init__(actual, expected, **other_parameters) self.mae = mae @@ -418,7 +418,7 @@ def sample_position(values, max_value): dtype = dtype or torch.float32 - h, w = [torch.randint(1, s, (num_boxes,)) for s in canvas_size] + h, w = (torch.randint(1, s, (num_boxes,)) for s in canvas_size) y = sample_position(h, canvas_size[0]) x = sample_position(w, canvas_size[1]) r = -360 * torch.rand((num_boxes,)) + 180 diff --git a/test/datasets_utils.py b/test/datasets_utils.py index 6a552a96923..cbfb26b6c6b 100644 --- a/test/datasets_utils.py +++ b/test/datasets_utils.py @@ -15,7 +15,8 @@ import unittest.mock import zipfile from collections import defaultdict -from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Tuple, Union +from collections.abc import Iterator, Sequence +from typing import Any, Callable, Optional, Union import numpy as np @@ -63,6 +64,7 @@ class LazyImporter: provide modules listed in MODULES as attributes. They are only imported when accessed. """ + MODULES = ( "av", "lmdb", @@ -280,7 +282,7 @@ def test_baz(self): "download_and_extract_archive", } - def dataset_args(self, tmpdir: str, config: Dict[str, Any]) -> Sequence[Any]: + def dataset_args(self, tmpdir: str, config: dict[str, Any]) -> Sequence[Any]: """Define positional arguments passed to the dataset. .. note:: @@ -299,7 +301,7 @@ def dataset_args(self, tmpdir: str, config: Dict[str, Any]) -> Sequence[Any]: """ return (tmpdir,) - def inject_fake_data(self, tmpdir: str, config: Dict[str, Any]) -> Union[int, Dict[str, Any]]: + def inject_fake_data(self, tmpdir: str, config: dict[str, Any]) -> Union[int, dict[str, Any]]: """Inject fake data for dataset into a temporary directory. During the creation of the dataset the download and extract logic is disabled. Thus, the fake data injected @@ -323,11 +325,11 @@ def inject_fake_data(self, tmpdir: str, config: Dict[str, Any]) -> Union[int, Di @contextlib.contextmanager def create_dataset( self, - config: Optional[Dict[str, Any]] = None, + config: Optional[dict[str, Any]] = None, inject_fake_data: bool = True, patch_checks: Optional[bool] = None, **kwargs: Any, - ) -> Iterator[Tuple[torchvision.datasets.VisionDataset, Dict[str, Any]]]: + ) -> Iterator[tuple[torchvision.datasets.VisionDataset, dict[str, Any]]]: r"""Create the dataset in a temporary directory. The configuration passed to the dataset is populated to contain at least all parameters with default values. @@ -616,11 +618,11 @@ class ImageDatasetTestCase(DatasetTestCase): @contextlib.contextmanager def create_dataset( self, - config: Optional[Dict[str, Any]] = None, + config: Optional[dict[str, Any]] = None, inject_fake_data: bool = True, patch_checks: Optional[bool] = None, **kwargs: Any, - ) -> Iterator[Tuple[torchvision.datasets.VisionDataset, Dict[str, Any]]]: + ) -> Iterator[tuple[torchvision.datasets.VisionDataset, dict[str, Any]]]: with super().create_dataset( config=config, inject_fake_data=inject_fake_data, @@ -799,7 +801,7 @@ def create_image_folder( num_examples: int, size: Optional[Union[Sequence[int], int, Callable[[int], Union[Sequence[int], int]]]] = None, **kwargs: Any, -) -> List[pathlib.Path]: +) -> list[pathlib.Path]: """Create a folder of random images. Args: @@ -821,7 +823,7 @@ def create_image_folder( """ if size is None: - def size(idx: int) -> Tuple[int, int, int]: + def size(idx: int) -> tuple[int, int, int]: num_channels = 3 height, width = torch.randint(3, 11, size=(2,), dtype=torch.int).tolist() return (num_channels, height, width) @@ -913,7 +915,7 @@ def create_video_folder( size: Optional[Union[Sequence[int], int, Callable[[int], Union[Sequence[int], int]]]] = None, fps=25, **kwargs, -) -> List[pathlib.Path]: +) -> list[pathlib.Path]: """Create a folder of random videos. Args: diff --git a/test/test_backbone_utils.py b/test/test_backbone_utils.py index c64e27f14ac..8f6fc5d9278 100644 --- a/test/test_backbone_utils.py +++ b/test/test_backbone_utils.py @@ -1,7 +1,7 @@ import random +from collections.abc import Mapping, Sequence from copy import deepcopy from itertools import chain -from typing import Mapping, Sequence import pytest import torch diff --git a/test/test_datasets.py b/test/test_datasets.py index 84f243388aa..22c14cbc08d 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -14,7 +14,7 @@ import unittest import xml.etree.ElementTree as ET import zipfile -from typing import Callable, Tuple, Union +from typing import Callable, Union import datasets_utils import numpy as np @@ -3108,13 +3108,13 @@ class FallingThingsStereoTestCase(datasets_utils.ImageDatasetTestCase): FEATURE_TYPES = (PIL.Image.Image, PIL.Image.Image, (np.ndarray, type(None))) @staticmethod - def _make_dummy_depth_map(root: str, name: str, size: Tuple[int, int]): + def _make_dummy_depth_map(root: str, name: str, size: tuple[int, int]): file = pathlib.Path(root) / name image = np.ones((size[0], size[1]), dtype=np.uint8) PIL.Image.fromarray(image).save(file) @staticmethod - def _make_scene_folder(root: str, scene_name: str, size: Tuple[int, int]) -> None: + def _make_scene_folder(root: str, scene_name: str, size: tuple[int, int]) -> None: root = pathlib.Path(root) / scene_name os.makedirs(root, exist_ok=True) # jpg images @@ -3185,7 +3185,7 @@ class SceneFlowStereoTestCase(datasets_utils.ImageDatasetTestCase): @staticmethod def _create_pfm_folder( - root: str, name: str, file_name_fn: Callable[..., str], num_examples: int, size: Tuple[int, int] + root: str, name: str, file_name_fn: Callable[..., str], num_examples: int, size: tuple[int, int] ) -> None: root = pathlib.Path(root) / name os.makedirs(root, exist_ok=True) @@ -3268,7 +3268,7 @@ class InStereo2k(datasets_utils.ImageDatasetTestCase): ADDITIONAL_CONFIGS = combinations_grid(split=("train", "test")) @staticmethod - def _make_scene_folder(root: str, name: str, size: Tuple[int, int]): + def _make_scene_folder(root: str, name: str, size: tuple[int, int]): root = pathlib.Path(root) / name os.makedirs(root, exist_ok=True) diff --git a/test/test_extended_models.py b/test/test_extended_models.py index 0c918c0afd1..a9072826724 100644 --- a/test/test_extended_models.py +++ b/test/test_extended_models.py @@ -116,7 +116,7 @@ def get_models_from_module(module): ) def test_list_models(module): a = set(get_models_from_module(module)) - b = set(x.replace("quantized_", "") for x in models.list_models(module)) + b = {x.replace("quantized_", "") for x in models.list_models(module)} assert len(b) > 0 assert a == b @@ -135,7 +135,7 @@ def test_list_models(module): ["*resnet*", "*alexnet*"], ["*resnet*", "*alexnet*", "*not-existing-model-for-test?"], ("*resnet*", "*alexnet*"), - set(["*resnet*", "*alexnet*"]), + {"*resnet*", "*alexnet*"}, ], ) @pytest.mark.parametrize( @@ -151,7 +151,7 @@ def test_list_models(module): ["resnet34", "*not-existing-model-for-test?"], ["resnet34", "*resnet1*"], ("resnet34", "*resnet1*"), - set(["resnet34", "*resnet1*"]), + {"resnet34", "*resnet1*"}, ], ) def test_list_models_filters(include_filters, exclude_filters): @@ -167,7 +167,7 @@ def test_list_models_filters(include_filters, exclude_filters): expected = set() for include_f in include_filters: include_f = include_f.strip("*?") - expected = expected | set(x for x in classification_models if include_f in x) + expected = expected | {x for x in classification_models if include_f in x} else: expected = classification_models @@ -175,7 +175,7 @@ def test_list_models_filters(include_filters, exclude_filters): for exclude_f in exclude_filters: exclude_f = exclude_f.strip("*?") if exclude_f != "": - a_exclude = set(x for x in classification_models if exclude_f in x) + a_exclude = {x for x in classification_models if exclude_f in x} expected = expected - a_exclude assert expected == actual @@ -289,11 +289,11 @@ def test_schema_meta_validation(model_fn): bad_names = [] for w in weights_enum: actual_fields = set(w.meta.keys()) - actual_fields |= set( + actual_fields |= { ("_metrics", dataset, metric_key) for dataset in w.meta.get("_metrics", {}).keys() for metric_key in w.meta.get("_metrics", {}).get(dataset, {}).keys() - ) + } missing_fields = expected_fields - actual_fields unsupported_fields = set(w.meta.keys()) - permitted_fields if missing_fields or unsupported_fields: diff --git a/test/test_functional_tensor.py b/test/test_functional_tensor.py index b5352f18f21..7d491372b77 100644 --- a/test/test_functional_tensor.py +++ b/test/test_functional_tensor.py @@ -2,8 +2,8 @@ import itertools import math import os +from collections.abc import Sequence from functools import partial -from typing import Sequence import numpy as np import PIL.Image diff --git a/test/test_image.py b/test/test_image.py index 812c3741f92..d7c7bb542bb 100644 --- a/test/test_image.py +++ b/test/test_image.py @@ -398,7 +398,7 @@ def test_read_1_bit_png_consistency(shape, mode, tmpdir): def test_read_interlaced_png(): imgs = list(get_images(INTERLACED_PNG, ".png")) with Image.open(imgs[0]) as im1, Image.open(imgs[1]) as im2: - assert not (im1.info.get("interlace") is im2.info.get("interlace")) + assert im1.info.get("interlace") is not im2.info.get("interlace") img1 = read_image(imgs[0]) img2 = read_image(imgs[1]) assert_equal(img1, img2) @@ -1040,7 +1040,7 @@ def test_decode_avif_heic_against_pil(decode_fun, mode, pil_mode, filename): from torchvision.utils import make_grid g = make_grid([img, from_pil]) - F.to_pil_image(g).save((f"/home/nicolashug/out_images/{filename.name}.{pil_mode}.png")) + F.to_pil_image(g).save(f"/home/nicolashug/out_images/{filename.name}.{pil_mode}.png") is_decode_heic = getattr(decode_fun, "__name__", getattr(decode_fun, "name", None)) == "decode_heic" if mode == ImageReadMode.RGB and not is_decode_heic: diff --git a/test/test_onnx.py b/test/test_onnx.py index 0350c817ff8..c9d91454d7c 100644 --- a/test/test_onnx.py +++ b/test/test_onnx.py @@ -1,6 +1,6 @@ import io from collections import OrderedDict -from typing import List, Optional, Tuple +from typing import Optional import pytest import torch @@ -404,7 +404,7 @@ def forward(self_module, images, features): }, ) - def get_image(self, rel_path: str, size: Tuple[int, int]) -> torch.Tensor: + def get_image(self, rel_path: str, size: tuple[int, int]) -> torch.Tensor: import os from PIL import Image @@ -416,7 +416,7 @@ def get_image(self, rel_path: str, size: Tuple[int, int]) -> torch.Tensor: return F.convert_image_dtype(F.pil_to_tensor(image)) - def get_test_images(self) -> Tuple[List[torch.Tensor], List[torch.Tensor]]: + def get_test_images(self) -> tuple[list[torch.Tensor], list[torch.Tensor]]: return ( [self.get_image("encode_jpeg/grace_hopper_517x606.jpg", (100, 320))], [self.get_image("fakedata/logos/rgb_pytorch.png", (250, 380))], diff --git a/test/test_ops.py b/test/test_ops.py index 75940b7e509..3f0d8312c01 100644 --- a/test/test_ops.py +++ b/test/test_ops.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from functools import lru_cache from itertools import product -from typing import Callable, List, Tuple +from typing import Callable import numpy as np import pytest @@ -100,7 +100,7 @@ def __init__(self, pool: nn.Module): super().__init__() self.pool = pool - def forward(self, imgs: Tensor, boxes: List[Tensor]) -> Tensor: + def forward(self, imgs: Tensor, boxes: list[Tensor]) -> Tensor: return self.pool(imgs, boxes) @@ -1485,7 +1485,7 @@ def _run_test(target_fn: Callable, actual_box1, actual_box2, dtypes, atol, expec torch.testing.assert_close(out, expected_box, rtol=0.0, check_dtype=False, atol=atol) @staticmethod - def _run_jit_test(target_fn: Callable, actual_box: List): + def _run_jit_test(target_fn: Callable, actual_box: list): box_tensor = torch.tensor(actual_box, dtype=torch.float) expected = target_fn(box_tensor, box_tensor) scripted_fn = torch.jit.script(target_fn) diff --git a/test/test_transforms_v2.py b/test/test_transforms_v2.py index 157d4faaaea..94d90b9e2f6 100644 --- a/test/test_transforms_v2.py +++ b/test/test_transforms_v2.py @@ -1167,9 +1167,11 @@ def test_kernel_image(self, param, value, dtype, device): make_image(dtype=dtype, device=device), **{param: value}, check_scripted_vs_eager=not (param in {"shear", "fill"} and isinstance(value, (int, float))), - check_cuda_vs_cpu=dict(atol=1, rtol=0) - if dtype is torch.uint8 and param == "interpolation" and value is transforms.InterpolationMode.BILINEAR - else True, + check_cuda_vs_cpu=( + dict(atol=1, rtol=0) + if dtype is torch.uint8 and param == "interpolation" and value is transforms.InterpolationMode.BILINEAR + else True + ), ) @param_value_parametrization( @@ -1298,7 +1300,7 @@ def _compute_affine_matrix(self, *, angle, translate, scale, shear, center): rot = math.radians(angle) cx, cy = center tx, ty = translate - sx, sy = [math.radians(s) for s in ([shear, 0.0] if isinstance(shear, (int, float)) else shear)] + sx, sy = (math.radians(s) for s in ([shear, 0.0] if isinstance(shear, (int, float)) else shear)) c_matrix = np.array([[1, 0, cx], [0, 1, cy], [0, 0, 1]]) t_matrix = np.array([[1, 0, tx], [0, 1, ty], [0, 0, 1]]) @@ -4497,7 +4499,7 @@ def test_transform(self, make_input): def _reference_normalize_image(self, image, *, mean, std): image = image.numpy() - mean, std = [np.array(stat, dtype=image.dtype).reshape((-1, 1, 1)) for stat in [mean, std]] + mean, std = (np.array(stat, dtype=image.dtype).reshape((-1, 1, 1)) for stat in [mean, std]) return tv_tensors.Image((image - mean) / std) @pytest.mark.parametrize(("mean", "std"), MEANS_STDS) diff --git a/torchvision/_utils.py b/torchvision/_utils.py index b739ef0966e..aee2676df45 100644 --- a/torchvision/_utils.py +++ b/torchvision/_utils.py @@ -1,5 +1,6 @@ import enum -from typing import Sequence, Type, TypeVar +from collections.abc import Sequence +from typing import TypeVar T = TypeVar("T", bound=enum.Enum) @@ -7,7 +8,7 @@ class StrEnumMeta(enum.EnumMeta): auto = enum.auto - def from_str(self: Type[T], member: str) -> T: # type: ignore[misc] + def from_str(self: type[T], member: str) -> T: # type: ignore[misc] try: return self[member] except KeyError: diff --git a/torchvision/datasets/_optical_flow.py b/torchvision/datasets/_optical_flow.py index 9ee4c4df52f..52884dbc183 100644 --- a/torchvision/datasets/_optical_flow.py +++ b/torchvision/datasets/_optical_flow.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from glob import glob from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np import torch @@ -14,8 +14,8 @@ from .utils import _read_pfm, verify_str_arg from .vision import VisionDataset -T1 = Tuple[Image.Image, Image.Image, Optional[np.ndarray], Optional[np.ndarray]] -T2 = Tuple[Image.Image, Image.Image, Optional[np.ndarray]] +T1 = tuple[Image.Image, Image.Image, Optional[np.ndarray], Optional[np.ndarray]] +T2 = tuple[Image.Image, Image.Image, Optional[np.ndarray]] __all__ = ( @@ -43,8 +43,8 @@ def __init__( super().__init__(root=root) self.transforms = transforms - self._flow_list: List[str] = [] - self._image_list: List[List[str]] = [] + self._flow_list: list[str] = [] + self._image_list: list[list[str]] = [] self._loader = loader def _read_img(self, file_name: str) -> Union[Image.Image, torch.Tensor]: @@ -242,7 +242,7 @@ def __getitem__(self, index: int) -> Union[T1, T2]: """ return super().__getitem__(index) - def _read_flow(self, file_name: str) -> Tuple[np.ndarray, np.ndarray]: + def _read_flow(self, file_name: str) -> tuple[np.ndarray, np.ndarray]: return _read_16bits_png_with_flow_and_valid_mask(file_name) @@ -473,7 +473,7 @@ def __init__( "Could not find the HD1K images. Please make sure the directory structure is correct." ) - def _read_flow(self, file_name: str) -> Tuple[np.ndarray, np.ndarray]: + def _read_flow(self, file_name: str) -> tuple[np.ndarray, np.ndarray]: return _read_16bits_png_with_flow_and_valid_mask(file_name) def __getitem__(self, index: int) -> Union[T1, T2]: @@ -509,7 +509,7 @@ def _read_flo(file_name: str) -> np.ndarray: return data.reshape(h, w, 2).transpose(2, 0, 1) -def _read_16bits_png_with_flow_and_valid_mask(file_name: str) -> Tuple[np.ndarray, np.ndarray]: +def _read_16bits_png_with_flow_and_valid_mask(file_name: str) -> tuple[np.ndarray, np.ndarray]: flow_and_valid = decode_png(read_file(file_name)).to(torch.float32) flow, valid_flow_mask = flow_and_valid[:2, :, :], flow_and_valid[2, :, :] diff --git a/torchvision/datasets/_stereo_matching.py b/torchvision/datasets/_stereo_matching.py index 09961211cc2..bc2236e97b8 100644 --- a/torchvision/datasets/_stereo_matching.py +++ b/torchvision/datasets/_stereo_matching.py @@ -6,7 +6,7 @@ from abc import ABC, abstractmethod from glob import glob from pathlib import Path -from typing import Callable, cast, List, Optional, Tuple, Union +from typing import Callable, cast, Optional, Union import numpy as np from PIL import Image @@ -14,8 +14,8 @@ from .utils import _read_pfm, download_and_extract_archive, verify_str_arg from .vision import VisionDataset -T1 = Tuple[Image.Image, Image.Image, Optional[np.ndarray], np.ndarray] -T2 = Tuple[Image.Image, Image.Image, Optional[np.ndarray]] +T1 = tuple[Image.Image, Image.Image, Optional[np.ndarray], np.ndarray] +T2 = tuple[Image.Image, Image.Image, Optional[np.ndarray]] __all__ = () @@ -65,11 +65,11 @@ def _scan_pairs( self, paths_left_pattern: str, paths_right_pattern: Optional[str] = None, - ) -> List[Tuple[str, Optional[str]]]: + ) -> list[tuple[str, Optional[str]]]: left_paths = list(sorted(glob(paths_left_pattern))) - right_paths: List[Union[None, str]] + right_paths: list[Union[None, str]] if paths_right_pattern: right_paths = list(sorted(glob(paths_right_pattern))) else: @@ -92,7 +92,7 @@ def _scan_pairs( return paths @abstractmethod - def _read_disparity(self, file_path: str) -> Tuple[Optional[np.ndarray], Optional[np.ndarray]]: + def _read_disparity(self, file_path: str) -> tuple[Optional[np.ndarray], Optional[np.ndarray]]: # function that returns a disparity map and an occlusion map pass @@ -178,7 +178,7 @@ def __init__(self, root: Union[str, Path], transforms: Optional[Callable] = None disparities = self._scan_pairs(left_disparity_pattern, right_disparity_pattern) self._disparities = disparities - def _read_disparity(self, file_path: str) -> Tuple[np.ndarray, None]: + def _read_disparity(self, file_path: str) -> tuple[np.ndarray, None]: disparity_map = _read_pfm_file(file_path) disparity_map = np.abs(disparity_map) # ensure that the disparity is positive valid_mask = None @@ -257,7 +257,7 @@ def __init__(self, root: Union[str, Path], split: str = "train", transforms: Opt else: self._disparities = list((None, None) for _ in self._images) - def _read_disparity(self, file_path: str) -> Tuple[Optional[np.ndarray], None]: + def _read_disparity(self, file_path: str) -> tuple[Optional[np.ndarray], None]: # test split has no disparity maps if file_path is None: return None, None @@ -345,7 +345,7 @@ def __init__(self, root: Union[str, Path], split: str = "train", transforms: Opt else: self._disparities = list((None, None) for _ in self._images) - def _read_disparity(self, file_path: str) -> Tuple[Optional[np.ndarray], None]: + def _read_disparity(self, file_path: str) -> tuple[Optional[np.ndarray], None]: # test split has no disparity maps if file_path is None: return None, None @@ -549,7 +549,7 @@ def _read_img(self, file_path: Union[str, Path]) -> Image.Image: When ``use_ambient_views`` is True, the dataset will return at random one of ``[im1.png, im1E.png, im1L.png]`` as the right image. """ - ambient_file_paths: List[Union[str, Path]] # make mypy happy + ambient_file_paths: list[Union[str, Path]] # make mypy happy if not isinstance(file_path, Path): file_path = Path(file_path) @@ -565,7 +565,7 @@ def _read_img(self, file_path: Union[str, Path]) -> Image.Image: file_path = random.choice(ambient_file_paths) # type: ignore return super()._read_img(file_path) - def _read_disparity(self, file_path: str) -> Union[Tuple[None, None], Tuple[np.ndarray, np.ndarray]]: + def _read_disparity(self, file_path: str) -> Union[tuple[None, None], tuple[np.ndarray, np.ndarray]]: # test split has not disparity maps if file_path is None: return None, None @@ -694,7 +694,7 @@ def __init__( disparities = self._scan_pairs(left_disparity_pattern, right_disparity_pattern) self._disparities += disparities - def _read_disparity(self, file_path: str) -> Tuple[np.ndarray, None]: + def _read_disparity(self, file_path: str) -> tuple[np.ndarray, None]: disparity_map = np.asarray(Image.open(file_path), dtype=np.float32) # unsqueeze the disparity map into (C, H, W) format disparity_map = disparity_map[None, :, :] / 32.0 @@ -788,13 +788,13 @@ def __init__(self, root: Union[str, Path], variant: str = "single", transforms: right_disparity_pattern = str(root / s / split_prefix[s] / "*.right.depth.png") self._disparities += self._scan_pairs(left_disparity_pattern, right_disparity_pattern) - def _read_disparity(self, file_path: str) -> Tuple[np.ndarray, None]: + def _read_disparity(self, file_path: str) -> tuple[np.ndarray, None]: # (H, W) image depth = np.asarray(Image.open(file_path)) # as per https://research.nvidia.com/sites/default/files/pubs/2018-06_Falling-Things/readme_0.txt # in order to extract disparity from depth maps camera_settings_path = Path(file_path).parent / "_camera_settings.json" - with open(camera_settings_path, "r") as f: + with open(camera_settings_path) as f: # inverse of depth-from-disparity equation: depth = (baseline * focal) / (disparity * pixel_constant) intrinsics = json.load(f) focal = intrinsics["camera_settings"][0]["intrinsic_settings"]["fx"] @@ -911,7 +911,7 @@ def __init__( right_disparity_pattern = str(root / "disparity" / prefix_directories[variant] / "right" / "*.pfm") self._disparities += self._scan_pairs(left_disparity_pattern, right_disparity_pattern) - def _read_disparity(self, file_path: str) -> Tuple[np.ndarray, None]: + def _read_disparity(self, file_path: str) -> tuple[np.ndarray, None]: disparity_map = _read_pfm_file(file_path) disparity_map = np.abs(disparity_map) # ensure that the disparity is positive valid_mask = None @@ -999,7 +999,7 @@ def __init__(self, root: Union[str, Path], pass_name: str = "final", transforms: disparity_pattern = str(root / "training" / "disparities" / "*" / "*.png") self._disparities += self._scan_pairs(disparity_pattern, None) - def _get_occlussion_mask_paths(self, file_path: str) -> Tuple[str, str]: + def _get_occlussion_mask_paths(self, file_path: str) -> tuple[str, str]: # helper function to get the occlusion mask paths # a path will look like .../.../.../training/disparities/scene1/img1.png # we want to get something like .../.../.../training/occlusions/scene1/img1.png @@ -1020,7 +1020,7 @@ def _get_occlussion_mask_paths(self, file_path: str) -> Tuple[str, str]: return occlusion_path, outofframe_path - def _read_disparity(self, file_path: str) -> Union[Tuple[None, None], Tuple[np.ndarray, np.ndarray]]: + def _read_disparity(self, file_path: str) -> Union[tuple[None, None], tuple[np.ndarray, np.ndarray]]: if file_path is None: return None, None @@ -1101,7 +1101,7 @@ def __init__(self, root: Union[str, Path], split: str = "train", transforms: Opt right_disparity_pattern = str(root / "*" / "right_disp.png") self._disparities = self._scan_pairs(left_disparity_pattern, right_disparity_pattern) - def _read_disparity(self, file_path: str) -> Tuple[np.ndarray, None]: + def _read_disparity(self, file_path: str) -> tuple[np.ndarray, None]: disparity_map = np.asarray(Image.open(file_path), dtype=np.float32) # unsqueeze disparity to (C, H, W) disparity_map = disparity_map[None, :, :] / 1024.0 @@ -1195,7 +1195,7 @@ def __init__(self, root: Union[str, Path], split: str = "train", transforms: Opt disparity_pattern = str(root / anot_dir / "*" / "disp0GT.pfm") self._disparities = self._scan_pairs(disparity_pattern, None) - def _read_disparity(self, file_path: str) -> Union[Tuple[None, None], Tuple[np.ndarray, np.ndarray]]: + def _read_disparity(self, file_path: str) -> Union[tuple[None, None], tuple[np.ndarray, np.ndarray]]: # test split has no disparity maps if file_path is None: return None, None diff --git a/torchvision/datasets/caltech.py b/torchvision/datasets/caltech.py index b152c425c77..adcb49ff1c2 100644 --- a/torchvision/datasets/caltech.py +++ b/torchvision/datasets/caltech.py @@ -1,7 +1,7 @@ import os import os.path from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -40,7 +40,7 @@ class Caltech101(VisionDataset): def __init__( self, root: Union[str, Path], - target_type: Union[List[str], str] = "category", + target_type: Union[list[str], str] = "category", transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, download: bool = False, @@ -71,14 +71,14 @@ def __init__( } self.annotation_categories = list(map(lambda x: name_map[x] if x in name_map else x, self.categories)) - self.index: List[int] = [] + self.index: list[int] = [] self.y = [] - for (i, c) in enumerate(self.categories): + for i, c in enumerate(self.categories): n = len(os.listdir(os.path.join(self.root, "101_ObjectCategories", c))) self.index.extend(range(1, n + 1)) self.y.extend(n * [i]) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -181,9 +181,9 @@ def __init__( raise RuntimeError("Dataset not found or corrupted. You can use download=True to download it") self.categories = sorted(os.listdir(os.path.join(self.root, "256_ObjectCategories"))) - self.index: List[int] = [] + self.index: list[int] = [] self.y = [] - for (i, c) in enumerate(self.categories): + for i, c in enumerate(self.categories): n = len( [ item @@ -194,7 +194,7 @@ def __init__( self.index.extend(range(1, n + 1)) self.y.extend(n * [i]) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/celeba.py b/torchvision/datasets/celeba.py index 01fb619e778..469af6ed3b7 100644 --- a/torchvision/datasets/celeba.py +++ b/torchvision/datasets/celeba.py @@ -2,7 +2,7 @@ import os from collections import namedtuple from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import PIL import torch @@ -66,7 +66,7 @@ def __init__( self, root: Union[str, Path], split: str = "train", - target_type: Union[List[str], str] = "attr", + target_type: Union[list[str], str] = "attr", transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, download: bool = False, @@ -141,7 +141,7 @@ def _load_csv( return CSV(headers, indices, torch.tensor(data_int)) def _check_integrity(self) -> bool: - for (_, md5, filename) in self.file_list: + for _, md5, filename in self.file_list: fpath = os.path.join(self.root, self.base_folder, filename) _, ext = os.path.splitext(filename) # Allow original archive to be deleted (zip and 7z) @@ -156,12 +156,12 @@ def download(self) -> None: if self._check_integrity(): return - for (file_id, md5, filename) in self.file_list: + for file_id, md5, filename in self.file_list: download_file_from_google_drive(file_id, os.path.join(self.root, self.base_folder), filename, md5) extract_archive(os.path.join(self.root, self.base_folder, "img_align_celeba.zip")) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: X = PIL.Image.open(os.path.join(self.root, self.base_folder, "img_align_celeba", self.filename[index])) target: Any = [] diff --git a/torchvision/datasets/cifar.py b/torchvision/datasets/cifar.py index 0f425d76c57..45893a44995 100644 --- a/torchvision/datasets/cifar.py +++ b/torchvision/datasets/cifar.py @@ -1,7 +1,7 @@ import os.path import pickle from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np from PIL import Image @@ -101,7 +101,7 @@ def _load_meta(self) -> None: self.classes = data[self.meta["key"]] self.class_to_idx = {_class: i for i, _class in enumerate(self.classes)} - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/cityscapes.py b/torchvision/datasets/cityscapes.py index 97a47c07beb..a124439932f 100644 --- a/torchvision/datasets/cityscapes.py +++ b/torchvision/datasets/cityscapes.py @@ -2,7 +2,7 @@ import os from collections import namedtuple from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -107,7 +107,7 @@ def __init__( root: Union[str, Path], split: str = "train", mode: str = "fine", - target_type: Union[List[str], str] = "instance", + target_type: Union[list[str], str] = "instance", transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, transforms: Optional[Callable] = None, @@ -172,7 +172,7 @@ def __init__( self.images.append(os.path.join(img_dir, file_name)) self.targets.append(target_types) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -206,7 +206,7 @@ def extra_repr(self) -> str: lines = ["Split: {split}", "Mode: {mode}", "Type: {target_type}"] return "\n".join(lines).format(**self.__dict__) - def _load_json(self, path: str) -> Dict[str, Any]: + def _load_json(self, path: str) -> dict[str, Any]: with open(path) as file: data = json.load(file) return data diff --git a/torchvision/datasets/clevr.py b/torchvision/datasets/clevr.py index 6ce73fcb184..2bf24bc3c80 100644 --- a/torchvision/datasets/clevr.py +++ b/torchvision/datasets/clevr.py @@ -1,6 +1,6 @@ import json import pathlib -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from urllib.parse import urlparse from .folder import default_loader @@ -54,7 +54,7 @@ def __init__( self._image_files = sorted(self._data_folder.joinpath("images", self._split).glob("*")) - self._labels: List[Optional[int]] + self._labels: list[Optional[int]] if self._split != "test": with open(self._data_folder / "scenes" / f"CLEVR_{self._split}_scenes.json") as file: content = json.load(file) @@ -66,7 +66,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file = self._image_files[idx] label = self._labels[idx] diff --git a/torchvision/datasets/coco.py b/torchvision/datasets/coco.py index 64543036640..8f3b5d2dfe4 100644 --- a/torchvision/datasets/coco.py +++ b/torchvision/datasets/coco.py @@ -1,6 +1,6 @@ import os.path from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -42,10 +42,10 @@ def _load_image(self, id: int) -> Image.Image: path = self.coco.loadImgs(id)[0]["file_name"] return Image.open(os.path.join(self.root, path)).convert("RGB") - def _load_target(self, id: int) -> List[Any]: + def _load_target(self, id: int) -> list[Any]: return self.coco.loadAnns(self.coco.getAnnIds(id)) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: if not isinstance(index, int): raise ValueError(f"Index must be of type integer, got {type(index)} instead.") @@ -107,5 +107,5 @@ class CocoCaptions(CocoDetection): """ - def _load_target(self, id: int) -> List[str]: + def _load_target(self, id: int) -> list[str]: return [ann["caption"] for ann in super()._load_target(id)] diff --git a/torchvision/datasets/dtd.py b/torchvision/datasets/dtd.py index 17a8bdb694e..8fb347955d4 100644 --- a/torchvision/datasets/dtd.py +++ b/torchvision/datasets/dtd.py @@ -1,6 +1,6 @@ import os import pathlib -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -81,7 +81,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._image_files[idx], self._labels[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/fakedata.py b/torchvision/datasets/fakedata.py index af26a8579e5..4f2343100a6 100644 --- a/torchvision/datasets/fakedata.py +++ b/torchvision/datasets/fakedata.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Optional, Tuple +from typing import Any, Callable, Optional import torch @@ -25,7 +25,7 @@ class FakeData(VisionDataset): def __init__( self, size: int = 1000, - image_size: Tuple[int, int, int] = (3, 224, 224), + image_size: tuple[int, int, int] = (3, 224, 224), num_classes: int = 10, transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, @@ -37,7 +37,7 @@ def __init__( self.image_size = image_size self.random_offset = random_offset - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/fer2013.py b/torchvision/datasets/fer2013.py index 3afda07846b..f33afbeebc8 100644 --- a/torchvision/datasets/fer2013.py +++ b/torchvision/datasets/fer2013.py @@ -1,6 +1,6 @@ import csv import pathlib -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import torch from PIL import Image @@ -92,7 +92,7 @@ def get_label(row): else: return None - with open(data_file, "r", newline="") as file: + with open(data_file, newline="") as file: rows = (row for row in csv.DictReader(file)) if use_fer_file or use_icml_file: @@ -104,7 +104,7 @@ def get_label(row): def __len__(self) -> int: return len(self._samples) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_tensor, target = self._samples[idx] image = Image.fromarray(image_tensor.numpy()) diff --git a/torchvision/datasets/fgvc_aircraft.py b/torchvision/datasets/fgvc_aircraft.py index c0f2e147614..a3f2277b233 100644 --- a/torchvision/datasets/fgvc_aircraft.py +++ b/torchvision/datasets/fgvc_aircraft.py @@ -2,7 +2,7 @@ import os from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable from .folder import default_loader @@ -45,11 +45,11 @@ class FGVCAircraft(VisionDataset): def __init__( self, - root: Union[str, Path], + root: str | Path, split: str = "trainval", annotation_level: str = "variant", - transform: Optional[Callable] = None, - target_transform: Optional[Callable] = None, + transform: Callable | None = None, + target_transform: Callable | None = None, download: bool = False, loader: Callable[[str], Any] = default_loader, ) -> None: @@ -75,7 +75,7 @@ def __init__( "manufacturer": "manufacturers.txt", }[self._annotation_level], ) - with open(annotation_file, "r") as f: + with open(annotation_file) as f: self.classes = [line.strip() for line in f] self.class_to_idx = dict(zip(self.classes, range(len(self.classes)))) @@ -86,7 +86,7 @@ def __init__( self._image_files = [] self._labels = [] - with open(labels_file, "r") as f: + with open(labels_file) as f: for line in f: image_name, label_name = line.strip().split(" ", 1) self._image_files.append(os.path.join(image_data_folder, f"{image_name}.jpg")) @@ -96,7 +96,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._image_files[idx], self._labels[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/flickr.py b/torchvision/datasets/flickr.py index c80978368dd..84f1dc0e170 100644 --- a/torchvision/datasets/flickr.py +++ b/torchvision/datasets/flickr.py @@ -3,7 +3,7 @@ from collections import defaultdict from html.parser import HTMLParser from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader from .vision import VisionDataset @@ -18,14 +18,14 @@ def __init__(self, root: Union[str, Path]) -> None: self.root = root # Data structure to store captions - self.annotations: Dict[str, List[str]] = {} + self.annotations: dict[str, list[str]] = {} # State variables self.in_table = False self.current_tag: Optional[str] = None self.current_img: Optional[str] = None - def handle_starttag(self, tag: str, attrs: List[Tuple[str, Optional[str]]]) -> None: + def handle_starttag(self, tag: str, attrs: list[tuple[str, Optional[str]]]) -> None: self.current_tag = tag if tag == "table": @@ -87,7 +87,7 @@ def __init__( self.ids = list(sorted(self.annotations.keys())) self.loader = loader - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -149,7 +149,7 @@ def __init__( self.ids = list(sorted(self.annotations.keys())) self.loader = loader - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/flowers102.py b/torchvision/datasets/flowers102.py index b8cf01dd01b..80bca71e967 100644 --- a/torchvision/datasets/flowers102.py +++ b/torchvision/datasets/flowers102.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -82,7 +82,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._image_files[idx], self._labels[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/folder.py b/torchvision/datasets/folder.py index 65e168791e4..387439c0433 100644 --- a/torchvision/datasets/folder.py +++ b/torchvision/datasets/folder.py @@ -1,14 +1,14 @@ import os import os.path from pathlib import Path -from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, cast, Optional, Union from PIL import Image from .vision import VisionDataset -def has_file_allowed_extension(filename: str, extensions: Union[str, Tuple[str, ...]]) -> bool: +def has_file_allowed_extension(filename: str, extensions: Union[str, tuple[str, ...]]) -> bool: """Checks if a file is an allowed extension. Args: @@ -33,7 +33,7 @@ def is_image_file(filename: str) -> bool: return has_file_allowed_extension(filename, IMG_EXTENSIONS) -def find_classes(directory: Union[str, Path]) -> Tuple[List[str], Dict[str, int]]: +def find_classes(directory: Union[str, Path]) -> tuple[list[str], dict[str, int]]: """Finds the class folders in a dataset. See :class:`DatasetFolder` for details. @@ -48,11 +48,11 @@ def find_classes(directory: Union[str, Path]) -> Tuple[List[str], Dict[str, int] def make_dataset( directory: Union[str, Path], - class_to_idx: Optional[Dict[str, int]] = None, - extensions: Optional[Union[str, Tuple[str, ...]]] = None, + class_to_idx: Optional[dict[str, int]] = None, + extensions: Optional[Union[str, tuple[str, ...]]] = None, is_valid_file: Optional[Callable[[str], bool]] = None, allow_empty: bool = False, -) -> List[Tuple[str, int]]: +) -> list[tuple[str, int]]: """Generates a list of samples of a form (path_to_sample, class). See :class:`DatasetFolder` for details. @@ -139,7 +139,7 @@ def __init__( self, root: Union[str, Path], loader: Callable[[str], Any], - extensions: Optional[Tuple[str, ...]] = None, + extensions: Optional[tuple[str, ...]] = None, transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, is_valid_file: Optional[Callable[[str], bool]] = None, @@ -166,11 +166,11 @@ def __init__( @staticmethod def make_dataset( directory: Union[str, Path], - class_to_idx: Dict[str, int], - extensions: Optional[Tuple[str, ...]] = None, + class_to_idx: dict[str, int], + extensions: Optional[tuple[str, ...]] = None, is_valid_file: Optional[Callable[[str], bool]] = None, allow_empty: bool = False, - ) -> List[Tuple[str, int]]: + ) -> list[tuple[str, int]]: """Generates a list of samples of a form (path_to_sample, class). This can be overridden to e.g. read files from a compressed zip file instead of from the disk. @@ -204,7 +204,7 @@ def make_dataset( directory, class_to_idx, extensions=extensions, is_valid_file=is_valid_file, allow_empty=allow_empty ) - def find_classes(self, directory: Union[str, Path]) -> Tuple[List[str], Dict[str, int]]: + def find_classes(self, directory: Union[str, Path]) -> tuple[list[str], dict[str, int]]: """Find the class folders in a dataset structured as follows:: directory/ @@ -233,7 +233,7 @@ def find_classes(self, directory: Union[str, Path]) -> Tuple[List[str], Dict[str """ return find_classes(directory) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/food101.py b/torchvision/datasets/food101.py index 107e60e7d33..fee23680b05 100644 --- a/torchvision/datasets/food101.py +++ b/torchvision/datasets/food101.py @@ -1,6 +1,6 @@ import json from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -74,7 +74,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._image_files[idx], self._labels[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/gtsrb.py b/torchvision/datasets/gtsrb.py index a3d012c70b2..e6b60116c40 100644 --- a/torchvision/datasets/gtsrb.py +++ b/torchvision/datasets/gtsrb.py @@ -1,6 +1,6 @@ import csv import pathlib -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import PIL @@ -62,7 +62,7 @@ def __init__( def __len__(self) -> int: return len(self._samples) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: path, target = self._samples[index] sample = PIL.Image.open(path).convert("RGB") diff --git a/torchvision/datasets/hmdb51.py b/torchvision/datasets/hmdb51.py index 8377e40d57c..b9b84771cac 100644 --- a/torchvision/datasets/hmdb51.py +++ b/torchvision/datasets/hmdb51.py @@ -1,7 +1,7 @@ import glob import os from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from torch import Tensor @@ -68,7 +68,7 @@ def __init__( fold: int = 1, train: bool = True, transform: Optional[Callable] = None, - _precomputed_metadata: Optional[Dict[str, Any]] = None, + _precomputed_metadata: Optional[dict[str, Any]] = None, num_workers: int = 1, _video_width: int = 0, _video_height: int = 0, @@ -113,10 +113,10 @@ def __init__( self.transform = transform @property - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: return self.full_video_clips.metadata - def _select_fold(self, video_list: List[str], annotations_dir: str, fold: int, train: bool) -> List[int]: + def _select_fold(self, video_list: list[str], annotations_dir: str, fold: int, train: bool) -> list[int]: target_tag = self.TRAIN_TAG if train else self.TEST_TAG split_pattern_name = f"*test_split{fold}.txt" split_pattern_path = os.path.join(annotations_dir, split_pattern_name) @@ -141,7 +141,7 @@ def _select_fold(self, video_list: List[str], annotations_dir: str, fold: int, t def __len__(self) -> int: return self.video_clips.num_clips() - def __getitem__(self, idx: int) -> Tuple[Tensor, Tensor, int]: + def __getitem__(self, idx: int) -> tuple[Tensor, Tensor, int]: video, audio, _, video_idx = self.video_clips.get_clip(idx) sample_index = self.indices[video_idx] _, class_index = self.samples[sample_index] diff --git a/torchvision/datasets/imagenet.py b/torchvision/datasets/imagenet.py index 89492eec635..1808dc4f85b 100644 --- a/torchvision/datasets/imagenet.py +++ b/torchvision/datasets/imagenet.py @@ -1,9 +1,10 @@ import os import shutil import tempfile +from collections.abc import Iterator from contextlib import contextmanager from pathlib import Path -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union +from typing import Any, Optional, Union import torch @@ -81,7 +82,7 @@ def extra_repr(self) -> str: return "Split: {split}".format(**self.__dict__) -def load_meta_file(root: Union[str, Path], file: Optional[str] = None) -> Tuple[Dict[str, str], List[str]]: +def load_meta_file(root: Union[str, Path], file: Optional[str] = None) -> tuple[dict[str, str], list[str]]: if file is None: file = META_FILE file = os.path.join(root, file) @@ -116,7 +117,7 @@ def parse_devkit_archive(root: Union[str, Path], file: Optional[str] = None) -> """ import scipy.io as sio - def parse_meta_mat(devkit_root: str) -> Tuple[Dict[int, str], Dict[str, Tuple[str, ...]]]: + def parse_meta_mat(devkit_root: str) -> tuple[dict[int, str], dict[str, tuple[str, ...]]]: metafile = os.path.join(devkit_root, "data", "meta.mat") meta = sio.loadmat(metafile, squeeze_me=True)["synsets"] nums_children = list(zip(*meta))[4] @@ -127,7 +128,7 @@ def parse_meta_mat(devkit_root: str) -> Tuple[Dict[int, str], Dict[str, Tuple[st wnid_to_classes = {wnid: clss for wnid, clss in zip(wnids, classes)} return idx_to_wnid, wnid_to_classes - def parse_val_groundtruth_txt(devkit_root: str) -> List[int]: + def parse_val_groundtruth_txt(devkit_root: str) -> list[int]: file = os.path.join(devkit_root, "data", "ILSVRC2012_validation_ground_truth.txt") with open(file) as txtfh: val_idcs = txtfh.readlines() @@ -186,7 +187,7 @@ def parse_train_archive(root: Union[str, Path], file: Optional[str] = None, fold def parse_val_archive( - root: Union[str, Path], file: Optional[str] = None, wnids: Optional[List[str]] = None, folder: str = "val" + root: Union[str, Path], file: Optional[str] = None, wnids: Optional[list[str]] = None, folder: str = "val" ) -> None: """Parse the validation images archive of the ImageNet2012 classification dataset and prepare it for usage with the ImageNet dataset. diff --git a/torchvision/datasets/imagenette.py b/torchvision/datasets/imagenette.py index 7dac9243e08..16bac9bfadc 100644 --- a/torchvision/datasets/imagenette.py +++ b/torchvision/datasets/imagenette.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader, find_classes, make_dataset from .utils import download_and_extract_archive, verify_str_arg @@ -88,7 +88,7 @@ def _download(self): download_and_extract_archive(self._url, self.root, md5=self._md5) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: path, label = self._samples[idx] image = self.loader(path) diff --git a/torchvision/datasets/inaturalist.py b/torchvision/datasets/inaturalist.py index 973f90fc32b..a47483e158d 100644 --- a/torchvision/datasets/inaturalist.py +++ b/torchvision/datasets/inaturalist.py @@ -1,7 +1,7 @@ import os import os.path from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -71,7 +71,7 @@ def __init__( self, root: Union[str, Path], version: str = "2021_train", - target_type: Union[List[str], str] = "full", + target_type: Union[list[str], str] = "full", transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, download: bool = False, @@ -88,13 +88,13 @@ def __init__( if not self._check_exists(): raise RuntimeError("Dataset not found or corrupted. You can use download=True to download it") - self.all_categories: List[str] = [] + self.all_categories: list[str] = [] # map: category type -> name of category -> index - self.categories_index: Dict[str, Dict[str, int]] = {} + self.categories_index: dict[str, dict[str, int]] = {} # list indexed by category id, containing mapping from category type -> index - self.categories_map: List[Dict[str, int]] = [] + self.categories_map: list[dict[str, int]] = [] if not isinstance(target_type, list): target_type = [target_type] @@ -106,7 +106,7 @@ def __init__( self._init_pre2021() # index of all files: (full category id, filename) - self.index: List[Tuple[int, str]] = [] + self.index: list[tuple[int, str]] = [] for dir_index, dir_name in enumerate(self.all_categories): files = os.listdir(os.path.join(self.root, dir_name)) @@ -174,7 +174,7 @@ def _init_pre2021(self) -> None: if not c: raise RuntimeError(f"Missing category {cindex}") - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/kinetics.py b/torchvision/datasets/kinetics.py index 773d9f68ca9..c568e46a62d 100644 --- a/torchvision/datasets/kinetics.py +++ b/torchvision/datasets/kinetics.py @@ -5,7 +5,7 @@ from multiprocessing import Pool from os import path from pathlib import Path -from typing import Any, Callable, Dict, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from torch import Tensor @@ -97,11 +97,11 @@ def __init__( frame_rate: Optional[int] = None, step_between_clips: int = 1, transform: Optional[Callable] = None, - extensions: Tuple[str, ...] = ("avi", "mp4"), + extensions: tuple[str, ...] = ("avi", "mp4"), download: bool = False, num_download_workers: int = 1, num_workers: int = 1, - _precomputed_metadata: Optional[Dict[str, Any]] = None, + _precomputed_metadata: Optional[dict[str, Any]] = None, _video_width: int = 0, _video_height: int = 0, _video_min_dimension: int = 0, @@ -221,13 +221,13 @@ def _make_ds_structure(self) -> None: ) @property - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: return self.video_clips.metadata def __len__(self) -> int: return self.video_clips.num_clips() - def __getitem__(self, idx: int) -> Tuple[Tensor, Tensor, int]: + def __getitem__(self, idx: int) -> tuple[Tensor, Tensor, int]: video, audio, info, video_idx = self.video_clips.get_clip(idx) label = self.samples[video_idx][1] diff --git a/torchvision/datasets/kitti.py b/torchvision/datasets/kitti.py index 69e603c76f2..d275248d92a 100644 --- a/torchvision/datasets/kitti.py +++ b/torchvision/datasets/kitti.py @@ -1,7 +1,7 @@ import csv import os from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -83,7 +83,7 @@ def __init__( if self.train: self.targets.append(os.path.join(labels_dir, f"{img_file.split('.')[0]}.txt")) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """Get item at a given index. Args: @@ -108,7 +108,7 @@ def __getitem__(self, index: int) -> Tuple[Any, Any]: image, target = self.transforms(image, target) return image, target - def _parse_target(self, index: int) -> List: + def _parse_target(self, index: int) -> list: target = [] with open(self.targets[index]) as inp: content = csv.reader(inp, delimiter=" ") diff --git a/torchvision/datasets/lfw.py b/torchvision/datasets/lfw.py index efc5ee354d1..5e727df59f1 100644 --- a/torchvision/datasets/lfw.py +++ b/torchvision/datasets/lfw.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader from .utils import check_integrity, download_and_extract_archive, download_url, verify_str_arg @@ -48,7 +48,7 @@ def __init__( self.view = verify_str_arg(view.lower(), "view", ["people", "pairs"]) self.split = verify_str_arg(split.lower(), "split", ["10fold", "train", "test"]) self.labels_file = f"{self.view}{self.annot_file[self.split]}.txt" - self.data: List[Any] = [] + self.data: list[Any] = [] if download: self.download() @@ -124,7 +124,7 @@ def __init__( self.class_to_idx = self._get_classes() self.data, self.targets = self._get_people() - def _get_people(self) -> Tuple[List[str], List[int]]: + def _get_people(self) -> tuple[list[str], list[int]]: data, targets = [], [] with open(os.path.join(self.root, self.labels_file)) as f: lines = f.readlines() @@ -142,14 +142,14 @@ def _get_people(self) -> Tuple[List[str], List[int]]: return data, targets - def _get_classes(self) -> Dict[str, int]: + def _get_classes(self) -> dict[str, int]: with open(os.path.join(self.root, self.names)) as f: lines = f.readlines() names = [line.strip().split()[0] for line in lines] class_to_idx = {name: i for i, name in enumerate(names)} return class_to_idx - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -209,7 +209,7 @@ def __init__( self.pair_names, self.data, self.targets = self._get_pairs(self.images_dir) - def _get_pairs(self, images_dir: str) -> Tuple[List[Tuple[str, str]], List[Tuple[str, str]], List[int]]: + def _get_pairs(self, images_dir: str) -> tuple[list[tuple[str, str]], list[tuple[str, str]], list[int]]: pair_names, data, targets = [], [], [] with open(os.path.join(self.root, self.labels_file)) as f: lines = f.readlines() @@ -237,7 +237,7 @@ def _get_pairs(self, images_dir: str) -> Tuple[List[Tuple[str, str]], List[Tuple return pair_names, data, targets - def __getitem__(self, index: int) -> Tuple[Any, Any, int]: + def __getitem__(self, index: int) -> tuple[Any, Any, int]: """ Args: index (int): Index diff --git a/torchvision/datasets/lsun.py b/torchvision/datasets/lsun.py index 61d40eee221..6f6c7a5eb63 100644 --- a/torchvision/datasets/lsun.py +++ b/torchvision/datasets/lsun.py @@ -4,7 +4,7 @@ import string from collections.abc import Iterable from pathlib import Path -from typing import Any, Callable, cast, List, Optional, Tuple, Union +from typing import Any, Callable, cast, Optional, Union from PIL import Image @@ -31,7 +31,7 @@ def __init__( self.keys = [key for key in txn.cursor().iternext(keys=True, values=False)] pickle.dump(self.keys, open(cache_file, "wb")) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: img, target = None, None env = self.env with env.begin(write=False) as txn: @@ -73,7 +73,7 @@ class LSUN(VisionDataset): def __init__( self, root: Union[str, Path], - classes: Union[str, List[str]] = "train", + classes: Union[str, list[str]] = "train", transform: Optional[Callable] = None, target_transform: Optional[Callable] = None, ) -> None: @@ -93,7 +93,7 @@ def __init__( self.length = count - def _verify_classes(self, classes: Union[str, List[str]]) -> List[str]: + def _verify_classes(self, classes: Union[str, list[str]]) -> list[str]: categories = [ "bedroom", "bridge", @@ -136,7 +136,7 @@ def _verify_classes(self, classes: Union[str, List[str]]) -> List[str]: return classes - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/mnist.py b/torchvision/datasets/mnist.py index 74b19352cdb..08df550c8d6 100644 --- a/torchvision/datasets/mnist.py +++ b/torchvision/datasets/mnist.py @@ -6,7 +6,7 @@ import sys import warnings from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from urllib.error import URLError import numpy as np @@ -128,7 +128,7 @@ def _load_data(self): return data, targets - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -162,7 +162,7 @@ def processed_folder(self) -> str: return os.path.join(self.root, self.__class__.__name__, "processed") @property - def class_to_idx(self) -> Dict[str, int]: + def class_to_idx(self) -> dict[str, int]: return {_class: i for i, _class in enumerate(self.classes)} def _check_exists(self) -> bool: @@ -372,7 +372,7 @@ class QMNIST(MNIST): """ subsets = {"train": "train", "test": "test", "test10k": "test", "test50k": "test", "nist": "nist"} - resources: Dict[str, List[Tuple[str, str]]] = { # type: ignore[assignment] + resources: dict[str, list[tuple[str, str]]] = { # type: ignore[assignment] "train": [ ( "https://raw.githubusercontent.com/facebookresearch/qmnist/master/qmnist-train-images-idx3-ubyte.gz", @@ -475,7 +475,7 @@ def download(self) -> None: for url, md5 in split: download_and_extract_archive(url, self.raw_folder, md5=md5) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: # redefined to handle the compat flag img, target = self.data[index], self.targets[index] img = Image.fromarray(img.numpy(), mode="L") diff --git a/torchvision/datasets/omniglot.py b/torchvision/datasets/omniglot.py index f8d182cdb25..22fd59aa9c2 100644 --- a/torchvision/datasets/omniglot.py +++ b/torchvision/datasets/omniglot.py @@ -1,6 +1,6 @@ from os.path import join from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -55,20 +55,20 @@ def __init__( self.target_folder = join(self.root, self._get_target_folder()) self._alphabets = list_dir(self.target_folder) - self._characters: List[str] = sum( + self._characters: list[str] = sum( ([join(a, c) for c in list_dir(join(self.target_folder, a))] for a in self._alphabets), [] ) self._character_images = [ [(image, idx) for image in list_files(join(self.target_folder, character), ".png")] for idx, character in enumerate(self._characters) ] - self._flat_character_images: List[Tuple[str, int]] = sum(self._character_images, []) + self._flat_character_images: list[tuple[str, int]] = sum(self._character_images, []) self.loader = loader def __len__(self) -> int: return len(self._flat_character_images) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/oxford_iiit_pet.py b/torchvision/datasets/oxford_iiit_pet.py index e5d20d315d2..e598920f8fe 100644 --- a/torchvision/datasets/oxford_iiit_pet.py +++ b/torchvision/datasets/oxford_iiit_pet.py @@ -1,7 +1,8 @@ import os import os.path import pathlib -from typing import Any, Callable, Optional, Sequence, Tuple, Union +from collections.abc import Sequence +from typing import Any, Callable, Optional, Union from PIL import Image @@ -95,7 +96,7 @@ def __init__( def __len__(self) -> int: return len(self._images) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image = Image.open(self._images[idx]).convert("RGB") target: Any = [] diff --git a/torchvision/datasets/pcam.py b/torchvision/datasets/pcam.py index 8849e0ea39d..00d10f6a010 100644 --- a/torchvision/datasets/pcam.py +++ b/torchvision/datasets/pcam.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from PIL import Image @@ -103,7 +103,7 @@ def __len__(self) -> int: with self.h5py.File(self._base_folder / images_file) as images_data: return images_data["x"].shape[0] - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: images_file = self._FILES[self._split]["images"][0] with self.h5py.File(self._base_folder / images_file) as images_data: image = Image.fromarray(images_data["x"][idx]).convert("RGB") diff --git a/torchvision/datasets/phototour.py b/torchvision/datasets/phototour.py index 9511f0626b4..5d625b51ece 100644 --- a/torchvision/datasets/phototour.py +++ b/torchvision/datasets/phototour.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np import torch @@ -114,7 +114,7 @@ def __init__( # load the serialized data self.data, self.labels, self.matches = torch.load(self.data_file, weights_only=True) - def __getitem__(self, index: int) -> Union[torch.Tensor, Tuple[Any, Any, torch.Tensor]]: + def __getitem__(self, index: int) -> Union[torch.Tensor, tuple[Any, Any, torch.Tensor]]: """ Args: index (int): Index @@ -187,7 +187,7 @@ def PIL2array(_img: Image.Image) -> np.ndarray: """Convert PIL image type to numpy 2D array""" return np.array(_img.getdata(), dtype=np.uint8).reshape(64, 64) - def find_files(_data_dir: str, _image_ext: str) -> List[str]: + def find_files(_data_dir: str, _image_ext: str) -> list[str]: """Return a list with the file names of the images containing the patches""" files = [] # find those files with the specified extension diff --git a/torchvision/datasets/places365.py b/torchvision/datasets/places365.py index c02fccb4154..51b845de723 100644 --- a/torchvision/datasets/places365.py +++ b/torchvision/datasets/places365.py @@ -1,7 +1,7 @@ import os from os import path from pathlib import Path -from typing import Any, Callable, cast, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, cast, Optional, Union from urllib.parse import urljoin from .folder import default_loader @@ -87,7 +87,7 @@ def __init__( if download: self.download_images() - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: file, target = self.imgs[index] image = self.loader(file) @@ -112,8 +112,8 @@ def images_dir(self) -> str: dir = f"{self.split}_{size}" return path.join(self.root, dir) - def load_categories(self, download: bool = True) -> Tuple[List[str], Dict[str, int]]: - def process(line: str) -> Tuple[str, int]: + def load_categories(self, download: bool = True) -> tuple[list[str], dict[str, int]]: + def process(line: str) -> tuple[str, int]: cls, idx = line.split() return cls, int(idx) @@ -129,8 +129,8 @@ def process(line: str) -> Tuple[str, int]: def load_file_list( self, download: bool = True - ) -> Tuple[List[Tuple[str, Union[int, None]]], List[Union[int, None]]]: - def process(line: str, sep="/") -> Tuple[str, Union[int, None]]: + ) -> tuple[list[tuple[str, Union[int, None]]], list[Union[int, None]]]: + def process(line: str, sep="/") -> tuple[str, Union[int, None]]: image, idx = (line.split() + [None])[:2] image = cast(str, image) idx = int(idx) if idx is not None else None diff --git a/torchvision/datasets/rendered_sst2.py b/torchvision/datasets/rendered_sst2.py index e8543c1e8a3..62ad3bc6d00 100644 --- a/torchvision/datasets/rendered_sst2.py +++ b/torchvision/datasets/rendered_sst2.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader, make_dataset from .utils import download_and_extract_archive, verify_str_arg @@ -62,7 +62,7 @@ def __init__( def __len__(self) -> int: return len(self._samples) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._samples[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/samplers/clip_sampler.py b/torchvision/datasets/samplers/clip_sampler.py index 026c3d75d3b..570bc85eee9 100644 --- a/torchvision/datasets/samplers/clip_sampler.py +++ b/torchvision/datasets/samplers/clip_sampler.py @@ -1,5 +1,6 @@ import math -from typing import cast, Iterator, List, Optional, Sized, Union +from collections.abc import Iterator, Sized +from typing import cast, Optional, Union import torch import torch.distributed as dist @@ -71,7 +72,7 @@ def __iter__(self) -> Iterator[int]: # deterministically shuffle based on epoch g = torch.Generator() g.manual_seed(self.epoch) - indices: Union[torch.Tensor, List[int]] + indices: Union[torch.Tensor, list[int]] if self.shuffle: indices = torch.randperm(len(self.dataset), generator=g).tolist() else: @@ -132,7 +133,7 @@ def __iter__(self) -> Iterator[int]: sampled = torch.linspace(s, s + length - 1, steps=self.num_clips_per_video).floor().to(torch.int64) s += length idxs.append(sampled) - return iter(cast(List[int], torch.cat(idxs).tolist())) + return iter(cast(list[int], torch.cat(idxs).tolist())) def __len__(self) -> int: return sum(self.num_clips_per_video for c in self.video_clips.clips if len(c) > 0) diff --git a/torchvision/datasets/sbd.py b/torchvision/datasets/sbd.py index 4b9ccb75eb9..091e8698197 100644 --- a/torchvision/datasets/sbd.py +++ b/torchvision/datasets/sbd.py @@ -1,7 +1,7 @@ import os import shutil from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np from PIL import Image @@ -109,7 +109,7 @@ def _get_boundaries_target(self, filepath: str) -> np.ndarray: axis=0, ) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: img = Image.open(self.images[index]).convert("RGB") target = self._get_target(self.masks[index]) diff --git a/torchvision/datasets/sbu.py b/torchvision/datasets/sbu.py index fb82cccd380..c0c97503eec 100644 --- a/torchvision/datasets/sbu.py +++ b/torchvision/datasets/sbu.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -63,7 +63,7 @@ def __init__( self.photos.append(photo) self.captions.append(caption) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/semeion.py b/torchvision/datasets/semeion.py index 71485b14dcf..434794577d3 100644 --- a/torchvision/datasets/semeion.py +++ b/torchvision/datasets/semeion.py @@ -1,6 +1,6 @@ import os.path from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np from PIL import Image @@ -24,6 +24,7 @@ class SEMEION(VisionDataset): downloaded again. """ + url = "http://archive.ics.uci.edu/ml/machine-learning-databases/semeion/semeion.data" filename = "semeion.data" md5_checksum = "cb545d371d2ce14ec121470795a77432" @@ -51,7 +52,7 @@ def __init__( self.data = np.reshape(self.data, (-1, 16, 16)) self.labels = np.nonzero(data[:, 256:])[1] - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/stanford_cars.py b/torchvision/datasets/stanford_cars.py index 2f5ecce198b..e73fb1f3141 100644 --- a/torchvision/datasets/stanford_cars.py +++ b/torchvision/datasets/stanford_cars.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -84,7 +84,7 @@ def __init__( def __len__(self) -> int: return len(self._samples) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: """Returns pil_image and class_id for given index""" image_path, target = self._samples[idx] image = self.loader(image_path) diff --git a/torchvision/datasets/stl10.py b/torchvision/datasets/stl10.py index 39c058e497d..6d7212a1b55 100644 --- a/torchvision/datasets/stl10.py +++ b/torchvision/datasets/stl10.py @@ -1,6 +1,6 @@ import os.path from pathlib import Path -from typing import Any, Callable, cast, Optional, Tuple, Union +from typing import Any, Callable, cast, Optional, Union import numpy as np from PIL import Image @@ -100,7 +100,7 @@ def _verify_folds(self, folds: Optional[int]) -> Optional[int]: msg = "Expected type None or int for argument folds, but got type {}." raise ValueError(msg.format(type(folds))) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -129,7 +129,7 @@ def __getitem__(self, index: int) -> Tuple[Any, Any]: def __len__(self) -> int: return self.data.shape[0] - def __loadfile(self, data_file: str, labels_file: Optional[str] = None) -> Tuple[np.ndarray, Optional[np.ndarray]]: + def __loadfile(self, data_file: str, labels_file: Optional[str] = None) -> tuple[np.ndarray, Optional[np.ndarray]]: labels = None if labels_file: path_to_labels = os.path.join(self.root, self.base_folder, labels_file) diff --git a/torchvision/datasets/sun397.py b/torchvision/datasets/sun397.py index 60115d93d4c..a27f86d9579 100644 --- a/torchvision/datasets/sun397.py +++ b/torchvision/datasets/sun397.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from .folder import default_loader @@ -60,7 +60,7 @@ def __init__( def __len__(self) -> int: return len(self._image_files) - def __getitem__(self, idx: int) -> Tuple[Any, Any]: + def __getitem__(self, idx: int) -> tuple[Any, Any]: image_file, label = self._image_files[idx], self._labels[idx] image = self.loader(image_file) diff --git a/torchvision/datasets/svhn.py b/torchvision/datasets/svhn.py index 5d20d7db7e3..b59f78ec050 100644 --- a/torchvision/datasets/svhn.py +++ b/torchvision/datasets/svhn.py @@ -1,6 +1,6 @@ import os.path from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np from PIL import Image @@ -91,7 +91,7 @@ def __init__( np.place(self.labels, self.labels == 10, 0) self.data = np.transpose(self.data, (3, 2, 0, 1)) - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/ucf101.py b/torchvision/datasets/ucf101.py index 935f8ad41c7..85930dbc742 100644 --- a/torchvision/datasets/ucf101.py +++ b/torchvision/datasets/ucf101.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from torch import Tensor @@ -61,7 +61,7 @@ def __init__( fold: int = 1, train: bool = True, transform: Optional[Callable] = None, - _precomputed_metadata: Optional[Dict[str, Any]] = None, + _precomputed_metadata: Optional[dict[str, Any]] = None, num_workers: int = 1, _video_width: int = 0, _video_height: int = 0, @@ -102,10 +102,10 @@ def __init__( self.transform = transform @property - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: return self.full_video_clips.metadata - def _select_fold(self, video_list: List[str], annotation_path: str, fold: int, train: bool) -> List[int]: + def _select_fold(self, video_list: list[str], annotation_path: str, fold: int, train: bool) -> list[int]: name = "train" if train else "test" name = f"{name}list{fold:02d}.txt" f = os.path.join(annotation_path, name) @@ -121,7 +121,7 @@ def _select_fold(self, video_list: List[str], annotation_path: str, fold: int, t def __len__(self) -> int: return self.video_clips.num_clips() - def __getitem__(self, idx: int) -> Tuple[Tensor, Tensor, int]: + def __getitem__(self, idx: int) -> tuple[Tensor, Tensor, int]: video, audio, info, video_idx = self.video_clips.get_clip(idx) label = self.samples[self.indices[video_idx]][1] diff --git a/torchvision/datasets/usps.py b/torchvision/datasets/usps.py index 9c681e79f6c..fa7d56e70b7 100644 --- a/torchvision/datasets/usps.py +++ b/torchvision/datasets/usps.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import numpy as np from PIL import Image @@ -70,7 +70,7 @@ def __init__( self.data = imgs self.targets = targets - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index diff --git a/torchvision/datasets/utils.py b/torchvision/datasets/utils.py index 8bf310896c7..0b6670800d2 100644 --- a/torchvision/datasets/utils.py +++ b/torchvision/datasets/utils.py @@ -6,13 +6,13 @@ import os.path import pathlib import re -import sys import tarfile import urllib import urllib.error import urllib.request import zipfile -from typing import Any, Callable, Dict, IO, Iterable, List, Optional, Tuple, TypeVar, Union +from collections.abc import Iterable +from typing import Any, Callable, IO, Optional, TypeVar, Union from urllib.parse import urlparse import numpy as np @@ -36,10 +36,7 @@ def calculate_md5(fpath: Union[str, pathlib.Path], chunk_size: int = 1024 * 1024 # Setting the `usedforsecurity` flag does not change anything about the functionality, but indicates that we are # not using the MD5 checksum for cryptography. This enables its usage in restricted environments like FIPS. Without # it torchvision.datasets is unusable in these environments since we perform a MD5 check everywhere. - if sys.version_info >= (3, 9): - md5 = hashlib.md5(usedforsecurity=False) - else: - md5 = hashlib.md5() + md5 = hashlib.md5(usedforsecurity=False) with open(fpath, "rb") as f: while chunk := f.read(chunk_size): md5.update(chunk) @@ -140,7 +137,7 @@ def download_url( raise RuntimeError("File not found or corrupted.") -def list_dir(root: Union[str, pathlib.Path], prefix: bool = False) -> List[str]: +def list_dir(root: Union[str, pathlib.Path], prefix: bool = False) -> list[str]: """List all directories at a given root Args: @@ -155,7 +152,7 @@ def list_dir(root: Union[str, pathlib.Path], prefix: bool = False) -> List[str]: return directories -def list_files(root: Union[str, pathlib.Path], suffix: str, prefix: bool = False) -> List[str]: +def list_files(root: Union[str, pathlib.Path], suffix: str, prefix: bool = False) -> list[str]: """List all files ending with a suffix at a given root Args: @@ -216,7 +213,7 @@ def _extract_tar( tar.extractall(to_path) -_ZIP_COMPRESSION_MAP: Dict[str, int] = { +_ZIP_COMPRESSION_MAP: dict[str, int] = { ".bz2": zipfile.ZIP_BZIP2, ".xz": zipfile.ZIP_LZMA, } @@ -231,23 +228,23 @@ def _extract_zip( zip.extractall(to_path) -_ARCHIVE_EXTRACTORS: Dict[str, Callable[[Union[str, pathlib.Path], Union[str, pathlib.Path], Optional[str]], None]] = { +_ARCHIVE_EXTRACTORS: dict[str, Callable[[Union[str, pathlib.Path], Union[str, pathlib.Path], Optional[str]], None]] = { ".tar": _extract_tar, ".zip": _extract_zip, } -_COMPRESSED_FILE_OPENERS: Dict[str, Callable[..., IO]] = { +_COMPRESSED_FILE_OPENERS: dict[str, Callable[..., IO]] = { ".bz2": bz2.open, ".gz": gzip.open, ".xz": lzma.open, } -_FILE_TYPE_ALIASES: Dict[str, Tuple[Optional[str], Optional[str]]] = { +_FILE_TYPE_ALIASES: dict[str, tuple[Optional[str], Optional[str]]] = { ".tbz": (".tar", ".bz2"), ".tbz2": (".tar", ".bz2"), ".tgz": (".tar", ".gz"), } -def _detect_file_type(file: Union[str, pathlib.Path]) -> Tuple[str, Optional[str], Optional[str]]: +def _detect_file_type(file: Union[str, pathlib.Path]) -> tuple[str, Optional[str], Optional[str]]: """Detect the archive type and/or compression of a file. Args: diff --git a/torchvision/datasets/video_utils.py b/torchvision/datasets/video_utils.py index a412bc5841c..d9214beaa68 100644 --- a/torchvision/datasets/video_utils.py +++ b/torchvision/datasets/video_utils.py @@ -2,7 +2,7 @@ import math import warnings from fractions import Fraction -from typing import Any, Callable, cast, Dict, List, Optional, Tuple, TypeVar, Union +from typing import Any, Callable, cast, Optional, TypeVar, Union import torch from torchvision.io import _probe_video_from_file, _read_video_from_file, read_video, read_video_timestamps @@ -53,13 +53,13 @@ class _VideoTimestampsDataset: pickled when forking. """ - def __init__(self, video_paths: List[str]) -> None: + def __init__(self, video_paths: list[str]) -> None: self.video_paths = video_paths def __len__(self) -> int: return len(self.video_paths) - def __getitem__(self, idx: int) -> Tuple[List[int], Optional[float]]: + def __getitem__(self, idx: int) -> tuple[list[int], Optional[float]]: return read_video_timestamps(self.video_paths[idx]) @@ -99,11 +99,11 @@ class VideoClips: def __init__( self, - video_paths: List[str], + video_paths: list[str], clip_length_in_frames: int = 16, frames_between_clips: int = 1, frame_rate: Optional[float] = None, - _precomputed_metadata: Optional[Dict[str, Any]] = None, + _precomputed_metadata: Optional[dict[str, Any]] = None, num_workers: int = 0, _video_width: int = 0, _video_height: int = 0, @@ -136,7 +136,7 @@ def __init__( def _compute_frame_pts(self) -> None: self.video_pts = [] # len = num_videos. Each entry is a tensor of shape (num_frames_in_video,) - self.video_fps: List[float] = [] # len = num_videos + self.video_fps: list[float] = [] # len = num_videos # strategy: use a DataLoader to parallelize read_video_timestamps # so need to create a dummy dataset first @@ -160,7 +160,7 @@ def _compute_frame_pts(self) -> None: self.video_pts.extend(batch_pts) self.video_fps.extend(batch_fps) - def _init_from_metadata(self, metadata: Dict[str, Any]) -> None: + def _init_from_metadata(self, metadata: dict[str, Any]) -> None: self.video_paths = metadata["video_paths"] assert len(self.video_paths) == len(metadata["video_pts"]) self.video_pts = metadata["video_pts"] @@ -168,7 +168,7 @@ def _init_from_metadata(self, metadata: Dict[str, Any]) -> None: self.video_fps = metadata["video_fps"] @property - def metadata(self) -> Dict[str, Any]: + def metadata(self) -> dict[str, Any]: _metadata = { "video_paths": self.video_paths, "video_pts": self.video_pts, @@ -176,7 +176,7 @@ def metadata(self) -> Dict[str, Any]: } return _metadata - def subset(self, indices: List[int]) -> "VideoClips": + def subset(self, indices: list[int]) -> "VideoClips": video_paths = [self.video_paths[i] for i in indices] video_pts = [self.video_pts[i] for i in indices] video_fps = [self.video_fps[i] for i in indices] @@ -204,7 +204,7 @@ def subset(self, indices: List[int]) -> "VideoClips": @staticmethod def compute_clips_for_video( video_pts: torch.Tensor, num_frames: int, step: int, fps: Optional[float], frame_rate: Optional[float] = None - ) -> Tuple[torch.Tensor, Union[List[slice], torch.Tensor]]: + ) -> tuple[torch.Tensor, Union[list[slice], torch.Tensor]]: if fps is None: # if for some reason the video doesn't have fps (because doesn't have a video stream) # set the fps to 1. The value doesn't matter, because video_pts is empty anyway @@ -220,7 +220,7 @@ def compute_clips_for_video( "There aren't enough frames in the current video to get a clip for the given clip length and " "frames between clips. The video (and potentially others) will be skipped." ) - idxs: Union[List[slice], torch.Tensor] + idxs: Union[list[slice], torch.Tensor] if isinstance(_idxs, slice): idxs = [_idxs] * len(clips) else: @@ -262,7 +262,7 @@ def num_clips(self) -> int: """ return self.cumulative_sizes[-1] - def get_clip_location(self, idx: int) -> Tuple[int, int]: + def get_clip_location(self, idx: int) -> tuple[int, int]: """ Converts a flattened representation of the indices into a video_idx, clip_idx representation. @@ -286,7 +286,7 @@ def _resample_video_idx(num_frames: int, original_fps: float, new_fps: float) -> idxs = idxs.floor().to(torch.int64) return idxs - def get_clip(self, idx: int) -> Tuple[torch.Tensor, torch.Tensor, Dict[str, Any], int]: + def get_clip(self, idx: int) -> tuple[torch.Tensor, torch.Tensor, dict[str, Any], int]: """ Gets a subclip from a list of videos. @@ -374,7 +374,7 @@ def get_clip(self, idx: int) -> Tuple[torch.Tensor, torch.Tensor, Dict[str, Any] return video, audio, info, video_idx - def __getstate__(self) -> Dict[str, Any]: + def __getstate__(self) -> dict[str, Any]: video_pts_sizes = [len(v) for v in self.video_pts] # To be back-compatible, we convert data to dtype torch.long as needed # because for empty list, in legacy implementation, torch.as_tensor will @@ -402,7 +402,7 @@ def __getstate__(self) -> Dict[str, Any]: d["_version"] = 2 return d - def __setstate__(self, d: Dict[str, Any]) -> None: + def __setstate__(self, d: dict[str, Any]) -> None: # for backwards-compatibility if "_version" not in d: self.__dict__ = d diff --git a/torchvision/datasets/vision.py b/torchvision/datasets/vision.py index e524c67e263..c43f7814c6c 100644 --- a/torchvision/datasets/vision.py +++ b/torchvision/datasets/vision.py @@ -1,6 +1,6 @@ import os from pathlib import Path -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import torch.utils.data as data @@ -77,7 +77,7 @@ def __repr__(self) -> str: lines = [head] + [" " * self._repr_indent + line for line in body] return "\n".join(lines) - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: + def _format_transform_repr(self, transform: Callable, head: str) -> list[str]: lines = transform.__repr__().splitlines() return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] @@ -90,14 +90,14 @@ def __init__(self, transform: Optional[Callable] = None, target_transform: Optio self.transform = transform self.target_transform = target_transform - def __call__(self, input: Any, target: Any) -> Tuple[Any, Any]: + def __call__(self, input: Any, target: Any) -> tuple[Any, Any]: if self.transform is not None: input = self.transform(input) if self.target_transform is not None: target = self.target_transform(target) return input, target - def _format_transform_repr(self, transform: Callable, head: str) -> List[str]: + def _format_transform_repr(self, transform: Callable, head: str) -> list[str]: lines = transform.__repr__().splitlines() return [f"{head}{lines[0]}"] + ["{}{}".format(" " * len(head), line) for line in lines[1:]] diff --git a/torchvision/datasets/voc.py b/torchvision/datasets/voc.py index 0f0e84c84fa..4d3e502d84e 100644 --- a/torchvision/datasets/voc.py +++ b/torchvision/datasets/voc.py @@ -1,7 +1,7 @@ import collections import os from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union from xml.etree.ElementTree import Element as ET_Element try: @@ -141,10 +141,10 @@ class VOCSegmentation(_VOCBase): _TARGET_FILE_EXT = ".png" @property - def masks(self) -> List[str]: + def masks(self) -> list[str]: return self.targets - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -186,10 +186,10 @@ class VOCDetection(_VOCBase): _TARGET_FILE_EXT = ".xml" @property - def annotations(self) -> List[str]: + def annotations(self) -> list[str]: return self.targets - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -206,11 +206,11 @@ def __getitem__(self, index: int) -> Tuple[Any, Any]: return img, target @staticmethod - def parse_voc_xml(node: ET_Element) -> Dict[str, Any]: - voc_dict: Dict[str, Any] = {} + def parse_voc_xml(node: ET_Element) -> dict[str, Any]: + voc_dict: dict[str, Any] = {} children = list(node) if children: - def_dic: Dict[str, Any] = collections.defaultdict(list) + def_dic: dict[str, Any] = collections.defaultdict(list) for dc in map(VOCDetection.parse_voc_xml, children): for ind, v in dc.items(): def_dic[ind].append(v) diff --git a/torchvision/datasets/widerface.py b/torchvision/datasets/widerface.py index b451ebe25b9..31ab28ebdba 100644 --- a/torchvision/datasets/widerface.py +++ b/torchvision/datasets/widerface.py @@ -2,7 +2,7 @@ from os.path import abspath, expanduser from pathlib import Path -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import torch from PIL import Image @@ -75,13 +75,13 @@ def __init__( if not self._check_integrity(): raise RuntimeError("Dataset not found or corrupted. You can use download=True to download and prepare it") - self.img_info: List[Dict[str, Union[str, Dict[str, torch.Tensor]]]] = [] + self.img_info: list[dict[str, Union[str, dict[str, torch.Tensor]]]] = [] if self.split in ("train", "val"): self.parse_train_val_annotations_file() else: self.parse_test_annotations_file() - def __getitem__(self, index: int) -> Tuple[Any, Any]: + def __getitem__(self, index: int) -> tuple[Any, Any]: """ Args: index (int): Index @@ -173,7 +173,7 @@ def _check_integrity(self) -> bool: # Allow original archive to be deleted (zip). Only need the extracted images all_files = self.FILE_LIST.copy() all_files.append(self.ANNOTATIONS_FILE) - for (_, md5, filename) in all_files: + for _, md5, filename in all_files: file, ext = os.path.splitext(filename) extracted_dir = os.path.join(self.root, file) if not os.path.exists(extracted_dir): @@ -185,7 +185,7 @@ def download(self) -> None: return # download and extract image data - for (file_id, md5, filename) in self.FILE_LIST: + for file_id, md5, filename in self.FILE_LIST: download_file_from_google_drive(file_id, self.root, filename, md5) filepath = os.path.join(self.root, filename) extract_archive(filepath) diff --git a/torchvision/io/_video_opt.py b/torchvision/io/_video_opt.py index 7957ce3899a..5dbf035886f 100644 --- a/torchvision/io/_video_opt.py +++ b/torchvision/io/_video_opt.py @@ -1,7 +1,7 @@ import math import warnings from fractions import Fraction -from typing import Dict, List, Optional, Tuple, Union +from typing import Optional, Union import torch @@ -67,7 +67,7 @@ def __init__(self) -> None: self.audio_sample_rate = 0.0 -def _validate_pts(pts_range: Tuple[int, int]) -> None: +def _validate_pts(pts_range: tuple[int, int]) -> None: if pts_range[0] > pts_range[1] > 0: raise ValueError( @@ -108,7 +108,7 @@ def _fill_info( def _align_audio_frames( - aframes: torch.Tensor, aframe_pts: torch.Tensor, audio_pts_range: Tuple[int, int] + aframes: torch.Tensor, aframe_pts: torch.Tensor, audio_pts_range: tuple[int, int] ) -> torch.Tensor: start, end = aframe_pts[0], aframe_pts[-1] num_samples = aframes.size(0) @@ -130,14 +130,14 @@ def _read_video_from_file( video_height: int = 0, video_min_dimension: int = 0, video_max_dimension: int = 0, - video_pts_range: Tuple[int, int] = (0, -1), + video_pts_range: tuple[int, int] = (0, -1), video_timebase: Fraction = default_timebase, read_audio_stream: bool = True, audio_samples: int = 0, audio_channels: int = 0, - audio_pts_range: Tuple[int, int] = (0, -1), + audio_pts_range: tuple[int, int] = (0, -1), audio_timebase: Fraction = default_timebase, -) -> Tuple[torch.Tensor, torch.Tensor, VideoMetaData]: +) -> tuple[torch.Tensor, torch.Tensor, VideoMetaData]: """ Reads a video from a file, returning both the video frames and the audio frames @@ -219,7 +219,7 @@ def _read_video_from_file( return vframes, aframes, info -def _read_video_timestamps_from_file(filename: str) -> Tuple[List[int], List[int], VideoMetaData]: +def _read_video_timestamps_from_file(filename: str) -> tuple[list[int], list[int], VideoMetaData]: """ Decode all video- and audio frames in the video. Only pts (presentation timestamp) is returned. The actual frame pixel data is not @@ -273,16 +273,16 @@ def _read_video_from_memory( video_height: int = 0, video_min_dimension: int = 0, video_max_dimension: int = 0, - video_pts_range: Tuple[int, int] = (0, -1), + video_pts_range: tuple[int, int] = (0, -1), video_timebase_numerator: int = 0, video_timebase_denominator: int = 1, read_audio_stream: int = 1, audio_samples: int = 0, audio_channels: int = 0, - audio_pts_range: Tuple[int, int] = (0, -1), + audio_pts_range: tuple[int, int] = (0, -1), audio_timebase_numerator: int = 0, audio_timebase_denominator: int = 1, -) -> Tuple[torch.Tensor, torch.Tensor]: +) -> tuple[torch.Tensor, torch.Tensor]: """ Reads a video from memory, returning both the video frames as the audio frames This function is torchscriptable. @@ -377,7 +377,7 @@ def _read_video_from_memory( def _read_video_timestamps_from_memory( video_data: torch.Tensor, -) -> Tuple[List[int], List[int], VideoMetaData]: +) -> tuple[list[int], list[int], VideoMetaData]: """ Decode all frames in the video. Only pts (presentation timestamp) is returned. The actual frame pixel data is not copied. Thus, read_video_timestamps(...) @@ -442,7 +442,7 @@ def _read_video( start_pts: Union[float, Fraction] = 0, end_pts: Optional[Union[float, Fraction]] = None, pts_unit: str = "pts", -) -> Tuple[torch.Tensor, torch.Tensor, Dict[str, float]]: +) -> tuple[torch.Tensor, torch.Tensor, dict[str, float]]: _raise_video_deprecation_warning() if end_pts is None: end_pts = float("inf") @@ -501,7 +501,7 @@ def get_pts(time_base): def _read_video_timestamps( filename: str, pts_unit: str = "pts" -) -> Tuple[Union[List[int], List[Fraction]], Optional[float]]: +) -> tuple[Union[list[int], list[Fraction]], Optional[float]]: _raise_video_deprecation_warning() if pts_unit == "pts": warnings.warn( @@ -509,7 +509,7 @@ def _read_video_timestamps( + "follow-up version. Please use pts_unit 'sec'." ) - pts: Union[List[int], List[Fraction]] + pts: Union[list[int], list[Fraction]] pts, _, info = _read_video_timestamps_from_file(filename) if pts_unit == "sec": diff --git a/torchvision/io/image.py b/torchvision/io/image.py index 9eb99143942..c8d634ad050 100644 --- a/torchvision/io/image.py +++ b/torchvision/io/image.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import List, Union +from typing import Union from warnings import warn import torch @@ -154,11 +154,11 @@ def write_png(input: torch.Tensor, filename: str, compression_level: int = 6): def decode_jpeg( - input: Union[torch.Tensor, List[torch.Tensor]], + input: Union[torch.Tensor, list[torch.Tensor]], mode: ImageReadMode = ImageReadMode.UNCHANGED, device: Union[str, torch.device] = "cpu", apply_exif_orientation: bool = False, -) -> Union[torch.Tensor, List[torch.Tensor]]: +) -> Union[torch.Tensor, list[torch.Tensor]]: """Decode JPEG image(s) into 3D RGB or grayscale Tensor(s), on CPU or CUDA. The values of the output tensor are uint8 between 0 and 255. @@ -225,8 +225,8 @@ def decode_jpeg( def encode_jpeg( - input: Union[torch.Tensor, List[torch.Tensor]], quality: int = 75 -) -> Union[torch.Tensor, List[torch.Tensor]]: + input: Union[torch.Tensor, list[torch.Tensor]], quality: int = 75 +) -> Union[torch.Tensor, list[torch.Tensor]]: """Encode RGB tensor(s) into raw encoded jpeg bytes, on CPU or CUDA. .. note:: diff --git a/torchvision/io/video.py b/torchvision/io/video.py index 5e56848d817..14edcf50aaa 100644 --- a/torchvision/io/video.py +++ b/torchvision/io/video.py @@ -4,7 +4,7 @@ import re import warnings from fractions import Fraction -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Optional, Union import numpy as np import torch @@ -60,11 +60,11 @@ def write_video( video_array: torch.Tensor, fps: float, video_codec: str = "libx264", - options: Optional[Dict[str, Any]] = None, + options: Optional[dict[str, Any]] = None, audio_array: Optional[torch.Tensor] = None, audio_fps: Optional[float] = None, audio_codec: Optional[str] = None, - audio_options: Optional[Dict[str, Any]] = None, + audio_options: Optional[dict[str, Any]] = None, ) -> None: """ [DEPRECATED] Writes a 4d tensor in [T, H, W, C] format in a video file. @@ -182,8 +182,8 @@ def _read_from_stream( end_offset: float, pts_unit: str, stream: "av.stream.Stream", - stream_name: Dict[str, Optional[Union[int, Tuple[int, ...], List[int]]]], -) -> List["av.frame.Frame"]: + stream_name: dict[str, Optional[Union[int, tuple[int, ...], list[int]]]], +) -> list["av.frame.Frame"]: global _CALLED_TIMES, _GC_COLLECTION_INTERVAL _CALLED_TIMES += 1 if _CALLED_TIMES % _GC_COLLECTION_INTERVAL == _GC_COLLECTION_INTERVAL - 1: @@ -257,7 +257,7 @@ def _read_from_stream( def _align_audio_frames( - aframes: torch.Tensor, audio_frames: List["av.frame.Frame"], ref_start: int, ref_end: float + aframes: torch.Tensor, audio_frames: list["av.frame.Frame"], ref_start: int, ref_end: float ) -> torch.Tensor: start, end = audio_frames[0].pts, audio_frames[-1].pts total_aframes = aframes.shape[1] @@ -277,7 +277,7 @@ def read_video( end_pts: Optional[Union[float, Fraction]] = None, pts_unit: str = "pts", output_format: str = "THWC", -) -> Tuple[torch.Tensor, torch.Tensor, Dict[str, Any]]: +) -> tuple[torch.Tensor, torch.Tensor, dict[str, Any]]: """[DEPRECATED] Reads a video from a file, returning both the video frames and the audio frames .. warning:: @@ -401,7 +401,7 @@ def _can_read_timestamps_from_packets(container: "av.container.Container") -> bo return False -def _decode_video_timestamps(container: "av.container.Container") -> List[int]: +def _decode_video_timestamps(container: "av.container.Container") -> list[int]: if _can_read_timestamps_from_packets(container): # fast path return [x.pts for x in container.demux(video=0) if x.pts is not None] @@ -409,7 +409,7 @@ def _decode_video_timestamps(container: "av.container.Container") -> List[int]: return [x.pts for x in container.decode(video=0) if x.pts is not None] -def read_video_timestamps(filename: str, pts_unit: str = "pts") -> Tuple[List[int], Optional[float]]: +def read_video_timestamps(filename: str, pts_unit: str = "pts") -> tuple[list[int], Optional[float]]: """[DEPREACTED] List the video frames timestamps. .. warning:: diff --git a/torchvision/io/video_reader.py b/torchvision/io/video_reader.py index 5096b6ba324..efc58c47905 100644 --- a/torchvision/io/video_reader.py +++ b/torchvision/io/video_reader.py @@ -1,7 +1,8 @@ import io import warnings +from collections.abc import Iterator -from typing import Any, Dict, Iterator +from typing import Any import torch @@ -175,9 +176,9 @@ def __init__( # TODO: add extradata exception else: - raise RuntimeError("Unknown video backend: {}".format(self.backend)) + raise RuntimeError(f"Unknown video backend: {self.backend}") - def __next__(self) -> Dict[str, Any]: + def __next__(self) -> dict[str, Any]: """Decodes and returns the next frame of the current stream. Frames are encoded as a dict with mandatory data and pts fields, where data is a tensor, and pts is a @@ -214,7 +215,7 @@ def __next__(self) -> Dict[str, Any]: return {"data": frame, "pts": pts} - def __iter__(self) -> Iterator[Dict[str, Any]]: + def __iter__(self) -> Iterator[dict[str, Any]]: return self def seek(self, time_s: float, keyframes_only: bool = False) -> "VideoReader": @@ -244,7 +245,7 @@ def seek(self, time_s: float, keyframes_only: bool = False) -> "VideoReader": self._c = self.container.decode(**self.pyav_stream) return self - def get_metadata(self) -> Dict[str, Any]: + def get_metadata(self) -> dict[str, Any]: """Returns video metadata Returns: diff --git a/torchvision/models/_api.py b/torchvision/models/_api.py index c539319df19..358e6f43159 100644 --- a/torchvision/models/_api.py +++ b/torchvision/models/_api.py @@ -2,12 +2,13 @@ import importlib import inspect import sys +from collections.abc import Iterable, Mapping from dataclasses import dataclass from enum import Enum from functools import partial from inspect import signature from types import ModuleType -from typing import Any, Callable, Dict, get_args, Iterable, List, Mapping, Optional, Set, Type, TypeVar, Union +from typing import Any, Callable, get_args, Optional, TypeVar, Union from torch import nn @@ -36,7 +37,7 @@ class Weights: url: str transforms: Callable - meta: Dict[str, Any] + meta: dict[str, Any] def __eq__(self, other: Any) -> bool: # We need this custom implementation for correct deep-copy and deserialization behavior. @@ -141,7 +142,7 @@ def get_weight(name: str) -> WeightsEnum: return weights_enum[value_name] -def get_model_weights(name: Union[Callable, str]) -> Type[WeightsEnum]: +def get_model_weights(name: Union[Callable, str]) -> type[WeightsEnum]: """ Returns the weights enum class associated to the given model. @@ -155,7 +156,7 @@ def get_model_weights(name: Union[Callable, str]) -> Type[WeightsEnum]: return _get_enum_from_fn(model) -def _get_enum_from_fn(fn: Callable) -> Type[WeightsEnum]: +def _get_enum_from_fn(fn: Callable) -> type[WeightsEnum]: """ Internal method that gets the weight enum of a specific model builder method. @@ -207,7 +208,7 @@ def list_models( module: Optional[ModuleType] = None, include: Union[Iterable[str], str, None] = None, exclude: Union[Iterable[str], str, None] = None, -) -> List[str]: +) -> list[str]: """ Returns a list with the names of registered models. @@ -227,7 +228,7 @@ def list_models( k for k, v in BUILTIN_MODELS.items() if module is None or v.__module__.rsplit(".", 1)[0] == module.__name__ } if include: - models: Set[str] = set() + models: set[str] = set() if isinstance(include, str): include = [include] for include_filter in include: diff --git a/torchvision/models/_utils.py b/torchvision/models/_utils.py index d59a6220b91..61b9a069f98 100644 --- a/torchvision/models/_utils.py +++ b/torchvision/models/_utils.py @@ -2,7 +2,7 @@ import inspect import warnings from collections import OrderedDict -from typing import Any, Callable, Dict, Optional, Tuple, TypeVar, Union +from typing import Any, Callable, Optional, TypeVar, Union from torch import nn @@ -44,10 +44,10 @@ class IntermediateLayerGetter(nn.ModuleDict): _version = 2 __annotations__ = { - "return_layers": Dict[str, str], + "return_layers": dict[str, str], } - def __init__(self, model: nn.Module, return_layers: Dict[str, str]) -> None: + def __init__(self, model: nn.Module, return_layers: dict[str, str]) -> None: if not set(return_layers).issubset([name for name, _ in model.named_children()]): raise ValueError("return_layers are not present in model") orig_return_layers = return_layers @@ -149,7 +149,7 @@ def wrapper(*args: Any, **kwargs: Any) -> D: V = TypeVar("V") -def handle_legacy_interface(**weights: Tuple[str, Union[Optional[W], Callable[[Dict[str, Any]], Optional[W]]]]): +def handle_legacy_interface(**weights: tuple[str, Union[Optional[W], Callable[[dict[str, Any]], Optional[W]]]]): """Decorates a model builder with the new interface to make it compatible with the old. In particular this handles two things: @@ -232,7 +232,7 @@ def inner_wrapper(*args: Any, **kwargs: Any) -> M: return outer_wrapper -def _ovewrite_named_param(kwargs: Dict[str, Any], param: str, new_value: V) -> None: +def _ovewrite_named_param(kwargs: dict[str, Any], param: str, new_value: V) -> None: if param in kwargs: if kwargs[param] != new_value: raise ValueError(f"The parameter '{param}' expected value {new_value} but got {kwargs[param]} instead.") diff --git a/torchvision/models/convnext.py b/torchvision/models/convnext.py index 444ef3c219e..3264cb1fd0c 100644 --- a/torchvision/models/convnext.py +++ b/torchvision/models/convnext.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from functools import partial -from typing import Any, Callable, List, Optional, Sequence +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -90,7 +91,7 @@ def __repr__(self) -> str: class ConvNeXt(nn.Module): def __init__( self, - block_setting: List[CNBlockConfig], + block_setting: list[CNBlockConfig], stochastic_depth_prob: float = 0.0, layer_scale: float = 1e-6, num_classes: int = 1000, @@ -112,7 +113,7 @@ def __init__( if norm_layer is None: norm_layer = partial(LayerNorm2d, eps=1e-6) - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] # Stem firstconv_output_channels = block_setting[0].input_channels @@ -133,7 +134,7 @@ def __init__( stage_block_id = 0 for cnf in block_setting: # Bottlenecks - stage: List[nn.Module] = [] + stage: list[nn.Module] = [] for _ in range(cnf.num_layers): # adjust stochastic depth probability based on the depth of the stage block sd_prob = stochastic_depth_prob * stage_block_id / (total_stage_blocks - 1.0) @@ -177,7 +178,7 @@ def forward(self, x: Tensor) -> Tensor: def _convnext( - block_setting: List[CNBlockConfig], + block_setting: list[CNBlockConfig], stochastic_depth_prob: float, weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/densenet.py b/torchvision/models/densenet.py index c4c1bc9525a..06457f7b09e 100644 --- a/torchvision/models/densenet.py +++ b/torchvision/models/densenet.py @@ -1,7 +1,7 @@ import re from collections import OrderedDict from functools import partial -from typing import Any, List, Optional, Tuple +from typing import Any, Optional import torch import torch.nn as nn @@ -44,27 +44,27 @@ def __init__( self.drop_rate = float(drop_rate) self.memory_efficient = memory_efficient - def bn_function(self, inputs: List[Tensor]) -> Tensor: + def bn_function(self, inputs: list[Tensor]) -> Tensor: concated_features = torch.cat(inputs, 1) bottleneck_output = self.conv1(self.relu1(self.norm1(concated_features))) # noqa: T484 return bottleneck_output # todo: rewrite when torchscript supports any - def any_requires_grad(self, input: List[Tensor]) -> bool: + def any_requires_grad(self, input: list[Tensor]) -> bool: for tensor in input: if tensor.requires_grad: return True return False @torch.jit.unused # noqa: T484 - def call_checkpoint_bottleneck(self, input: List[Tensor]) -> Tensor: + def call_checkpoint_bottleneck(self, input: list[Tensor]) -> Tensor: def closure(*inputs): return self.bn_function(inputs) return cp.checkpoint(closure, *input, use_reentrant=False) @torch.jit._overload_method # noqa: F811 - def forward(self, input: List[Tensor]) -> Tensor: # noqa: F811 + def forward(self, input: list[Tensor]) -> Tensor: # noqa: F811 pass @torch.jit._overload_method # noqa: F811 @@ -152,7 +152,7 @@ class DenseNet(nn.Module): def __init__( self, growth_rate: int = 32, - block_config: Tuple[int, int, int, int] = (6, 12, 24, 16), + block_config: tuple[int, int, int, int] = (6, 12, 24, 16), num_init_features: int = 64, bn_size: int = 4, drop_rate: float = 0, @@ -239,7 +239,7 @@ def _load_state_dict(model: nn.Module, weights: WeightsEnum, progress: bool) -> def _densenet( growth_rate: int, - block_config: Tuple[int, int, int, int], + block_config: tuple[int, int, int, int], num_init_features: int, weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/detection/_utils.py b/torchvision/models/detection/_utils.py index 559db858ac3..805c05a92ff 100644 --- a/torchvision/models/detection/_utils.py +++ b/torchvision/models/detection/_utils.py @@ -1,6 +1,6 @@ import math from collections import OrderedDict -from typing import Dict, List, Optional, Tuple +from typing import Optional import torch from torch import nn, Tensor @@ -22,7 +22,7 @@ def __init__(self, batch_size_per_image: int, positive_fraction: float) -> None: self.batch_size_per_image = batch_size_per_image self.positive_fraction = positive_fraction - def __call__(self, matched_idxs: List[Tensor]) -> Tuple[List[Tensor], List[Tensor]]: + def __call__(self, matched_idxs: list[Tensor]) -> tuple[list[Tensor], list[Tensor]]: """ Args: matched_idxs: list of tensors containing -1, 0 or positive values. @@ -126,7 +126,7 @@ class BoxCoder: """ def __init__( - self, weights: Tuple[float, float, float, float], bbox_xform_clip: float = math.log(1000.0 / 16) + self, weights: tuple[float, float, float, float], bbox_xform_clip: float = math.log(1000.0 / 16) ) -> None: """ Args: @@ -136,7 +136,7 @@ def __init__( self.weights = weights self.bbox_xform_clip = bbox_xform_clip - def encode(self, reference_boxes: List[Tensor], proposals: List[Tensor]) -> List[Tensor]: + def encode(self, reference_boxes: list[Tensor], proposals: list[Tensor]) -> list[Tensor]: boxes_per_image = [len(b) for b in reference_boxes] reference_boxes = torch.cat(reference_boxes, dim=0) proposals = torch.cat(proposals, dim=0) @@ -159,7 +159,7 @@ def encode_single(self, reference_boxes: Tensor, proposals: Tensor) -> Tensor: return targets - def decode(self, rel_codes: Tensor, boxes: List[Tensor]) -> Tensor: + def decode(self, rel_codes: Tensor, boxes: list[Tensor]) -> Tensor: torch._assert( isinstance(boxes, (list, tuple)), "This function expects boxes of type list or tuple.", @@ -273,7 +273,6 @@ def encode(self, reference_boxes: Tensor, proposals: Tensor) -> Tensor: return targets def decode(self, rel_codes: Tensor, boxes: Tensor) -> Tensor: - """ From a set of original boxes and encoded relative box offsets, get the decoded boxes. @@ -451,7 +450,7 @@ def overwrite_eps(model: nn.Module, eps: float) -> None: module.eps = eps -def retrieve_out_channels(model: nn.Module, size: Tuple[int, int]) -> List[int]: +def retrieve_out_channels(model: nn.Module, size: tuple[int, int]) -> list[int]: """ This method retrieves the number of output channels of a specific model. @@ -518,7 +517,7 @@ def _box_loss( anchors_per_image: Tensor, matched_gt_boxes_per_image: Tensor, bbox_regression_per_image: Tensor, - cnf: Optional[Dict[str, float]] = None, + cnf: Optional[dict[str, float]] = None, ) -> Tensor: torch._assert(type in ["l1", "smooth_l1", "ciou", "diou", "giou"], f"Unsupported loss: {type}") diff --git a/torchvision/models/detection/anchor_utils.py b/torchvision/models/detection/anchor_utils.py index 253f6502a9b..05aa7664bea 100644 --- a/torchvision/models/detection/anchor_utils.py +++ b/torchvision/models/detection/anchor_utils.py @@ -1,5 +1,5 @@ import math -from typing import List, Optional +from typing import Optional import torch from torch import nn, Tensor @@ -29,7 +29,7 @@ class AnchorGenerator(nn.Module): """ __annotations__ = { - "cell_anchors": List[torch.Tensor], + "cell_anchors": list[torch.Tensor], } def __init__( @@ -57,8 +57,8 @@ def __init__( # This method assumes aspect ratio = height / width for an anchor. def generate_anchors( self, - scales: List[int], - aspect_ratios: List[float], + scales: list[int], + aspect_ratios: list[float], dtype: torch.dtype = torch.float32, device: torch.device = torch.device("cpu"), ) -> Tensor: @@ -76,12 +76,12 @@ def generate_anchors( def set_cell_anchors(self, dtype: torch.dtype, device: torch.device): self.cell_anchors = [cell_anchor.to(dtype=dtype, device=device) for cell_anchor in self.cell_anchors] - def num_anchors_per_location(self) -> List[int]: + def num_anchors_per_location(self) -> list[int]: return [len(s) * len(a) for s, a in zip(self.sizes, self.aspect_ratios)] # For every combination of (a, (g, s), i) in (self.cell_anchors, zip(grid_sizes, strides), 0:2), # output g[i] anchors that are s[i] distance apart in direction i, with the same dimensions as a. - def grid_anchors(self, grid_sizes: List[List[int]], strides: List[List[Tensor]]) -> List[Tensor]: + def grid_anchors(self, grid_sizes: list[list[int]], strides: list[list[Tensor]]) -> list[Tensor]: anchors = [] cell_anchors = self.cell_anchors torch._assert(cell_anchors is not None, "cell_anchors should not be None") @@ -112,7 +112,7 @@ def grid_anchors(self, grid_sizes: List[List[int]], strides: List[List[Tensor]]) return anchors - def forward(self, image_list: ImageList, feature_maps: List[Tensor]) -> List[Tensor]: + def forward(self, image_list: ImageList, feature_maps: list[Tensor]) -> list[Tensor]: grid_sizes = [feature_map.shape[-2:] for feature_map in feature_maps] image_size = image_list.tensors.shape[-2:] dtype, device = feature_maps[0].dtype, feature_maps[0].device @@ -125,7 +125,7 @@ def forward(self, image_list: ImageList, feature_maps: List[Tensor]) -> List[Ten ] self.set_cell_anchors(dtype, device) anchors_over_all_feature_maps = self.grid_anchors(grid_sizes, strides) - anchors: List[List[torch.Tensor]] = [] + anchors: list[list[torch.Tensor]] = [] for _ in range(len(image_list.image_sizes)): anchors_in_image = [anchors_per_feature_map for anchors_per_feature_map in anchors_over_all_feature_maps] anchors.append(anchors_in_image) @@ -153,11 +153,11 @@ class DefaultBoxGenerator(nn.Module): def __init__( self, - aspect_ratios: List[List[int]], + aspect_ratios: list[list[int]], min_ratio: float = 0.15, max_ratio: float = 0.9, - scales: Optional[List[float]] = None, - steps: Optional[List[int]] = None, + scales: Optional[list[float]] = None, + steps: Optional[list[int]] = None, clip: bool = True, ): super().__init__() @@ -183,8 +183,8 @@ def __init__( def _generate_wh_pairs( self, num_outputs: int, dtype: torch.dtype = torch.float32, device: torch.device = torch.device("cpu") - ) -> List[Tensor]: - _wh_pairs: List[Tensor] = [] + ) -> list[Tensor]: + _wh_pairs: list[Tensor] = [] for k in range(num_outputs): # Adding the 2 default width-height pairs for aspect ratio 1 and scale s'k s_k = self.scales[k] @@ -201,13 +201,13 @@ def _generate_wh_pairs( _wh_pairs.append(torch.as_tensor(wh_pairs, dtype=dtype, device=device)) return _wh_pairs - def num_anchors_per_location(self) -> List[int]: + def num_anchors_per_location(self) -> list[int]: # Estimate num of anchors based on aspect ratios: 2 default boxes + 2 * ratios of feaure map. return [2 + 2 * len(r) for r in self.aspect_ratios] # Default Boxes calculation based on page 6 of SSD paper def _grid_default_boxes( - self, grid_sizes: List[List[int]], image_size: List[int], dtype: torch.dtype = torch.float32 + self, grid_sizes: list[list[int]], image_size: list[int], dtype: torch.dtype = torch.float32 ) -> Tensor: default_boxes = [] for k, f_k in enumerate(grid_sizes): @@ -246,7 +246,7 @@ def __repr__(self) -> str: ) return s - def forward(self, image_list: ImageList, feature_maps: List[Tensor]) -> List[Tensor]: + def forward(self, image_list: ImageList, feature_maps: list[Tensor]) -> list[Tensor]: grid_sizes = [feature_map.shape[-2:] for feature_map in feature_maps] image_size = image_list.tensors.shape[-2:] dtype, device = feature_maps[0].dtype, feature_maps[0].device diff --git a/torchvision/models/detection/backbone_utils.py b/torchvision/models/detection/backbone_utils.py index 668e6b31696..f24c121d59a 100644 --- a/torchvision/models/detection/backbone_utils.py +++ b/torchvision/models/detection/backbone_utils.py @@ -1,5 +1,5 @@ import warnings -from typing import Callable, Dict, List, Optional, Union +from typing import Callable, Optional, Union from torch import nn, Tensor from torchvision.ops import misc as misc_nn_ops @@ -33,8 +33,8 @@ class BackboneWithFPN(nn.Module): def __init__( self, backbone: nn.Module, - return_layers: Dict[str, str], - in_channels_list: List[int], + return_layers: dict[str, str], + in_channels_list: list[int], out_channels: int, extra_blocks: Optional[ExtraFPNBlock] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, @@ -53,7 +53,7 @@ def __init__( ) self.out_channels = out_channels - def forward(self, x: Tensor) -> Dict[str, Tensor]: + def forward(self, x: Tensor) -> dict[str, Tensor]: x = self.body(x) x = self.fpn(x) return x @@ -71,7 +71,7 @@ def resnet_fpn_backbone( weights: Optional[WeightsEnum], norm_layer: Callable[..., nn.Module] = misc_nn_ops.FrozenBatchNorm2d, trainable_layers: int = 3, - returned_layers: Optional[List[int]] = None, + returned_layers: Optional[list[int]] = None, extra_blocks: Optional[ExtraFPNBlock] = None, ) -> BackboneWithFPN: """ @@ -118,7 +118,7 @@ def resnet_fpn_backbone( def _resnet_fpn_extractor( backbone: resnet.ResNet, trainable_layers: int, - returned_layers: Optional[List[int]] = None, + returned_layers: Optional[list[int]] = None, extra_blocks: Optional[ExtraFPNBlock] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, ) -> BackboneWithFPN: @@ -189,7 +189,7 @@ def mobilenet_backbone( fpn: bool, norm_layer: Callable[..., nn.Module] = misc_nn_ops.FrozenBatchNorm2d, trainable_layers: int = 2, - returned_layers: Optional[List[int]] = None, + returned_layers: Optional[list[int]] = None, extra_blocks: Optional[ExtraFPNBlock] = None, ) -> nn.Module: backbone = mobilenet.__dict__[backbone_name](weights=weights, norm_layer=norm_layer) @@ -200,7 +200,7 @@ def _mobilenet_extractor( backbone: Union[mobilenet.MobileNetV2, mobilenet.MobileNetV3], fpn: bool, trainable_layers: int, - returned_layers: Optional[List[int]] = None, + returned_layers: Optional[list[int]] = None, extra_blocks: Optional[ExtraFPNBlock] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, ) -> nn.Module: diff --git a/torchvision/models/detection/faster_rcnn.py b/torchvision/models/detection/faster_rcnn.py index 18474ee84f4..c6f7063107b 100644 --- a/torchvision/models/detection/faster_rcnn.py +++ b/torchvision/models/detection/faster_rcnn.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import torch import torch.nn.functional as F @@ -310,9 +310,9 @@ def forward(self, x): class FastRCNNConvFCHead(nn.Sequential): def __init__( self, - input_size: Tuple[int, int, int], - conv_layers: List[int], - fc_layers: List[int], + input_size: tuple[int, int, int], + conv_layers: list[int], + fc_layers: list[int], norm_layer: Optional[Callable[..., nn.Module]] = None, ): """ diff --git a/torchvision/models/detection/fcos.py b/torchvision/models/detection/fcos.py index a86ad2f424c..ccbd2496517 100644 --- a/torchvision/models/detection/fcos.py +++ b/torchvision/models/detection/fcos.py @@ -2,7 +2,7 @@ import warnings from collections import OrderedDict from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -51,11 +51,11 @@ def __init__(self, in_channels: int, num_anchors: int, num_classes: int, num_con def compute_loss( self, - targets: List[Dict[str, Tensor]], - head_outputs: Dict[str, Tensor], - anchors: List[Tensor], - matched_idxs: List[Tensor], - ) -> Dict[str, Tensor]: + targets: list[dict[str, Tensor]], + head_outputs: dict[str, Tensor], + anchors: list[Tensor], + matched_idxs: list[Tensor], + ) -> dict[str, Tensor]: cls_logits = head_outputs["cls_logits"] # [N, HWA, C] bbox_regression = head_outputs["bbox_regression"] # [N, HWA, 4] @@ -124,7 +124,7 @@ def compute_loss( "bbox_ctrness": loss_bbox_ctrness / max(1, num_foreground), } - def forward(self, x: List[Tensor]) -> Dict[str, Tensor]: + def forward(self, x: list[Tensor]) -> dict[str, Tensor]: cls_logits = self.classification_head(x) bbox_regression, bbox_ctrness = self.regression_head(x) return { @@ -180,7 +180,7 @@ def __init__( torch.nn.init.normal_(self.cls_logits.weight, std=0.01) torch.nn.init.constant_(self.cls_logits.bias, -math.log((1 - prior_probability) / prior_probability)) - def forward(self, x: List[Tensor]) -> Tensor: + def forward(self, x: list[Tensor]) -> Tensor: all_cls_logits = [] for features in x: @@ -242,7 +242,7 @@ def __init__( torch.nn.init.normal_(layer.weight, std=0.01) torch.nn.init.zeros_(layer.bias) - def forward(self, x: List[Tensor]) -> Tuple[Tensor, Tensor]: + def forward(self, x: list[Tensor]) -> tuple[Tensor, Tensor]: all_bbox_regression = [] all_bbox_ctrness = [] @@ -369,8 +369,8 @@ def __init__( # transform parameters min_size: int = 800, max_size: int = 1333, - image_mean: Optional[List[float]] = None, - image_std: Optional[List[float]] = None, + image_mean: Optional[list[float]] = None, + image_std: Optional[list[float]] = None, # Anchor parameters anchor_generator: Optional[AnchorGenerator] = None, head: Optional[nn.Module] = None, @@ -430,8 +430,8 @@ def __init__( @torch.jit.unused def eager_outputs( - self, losses: Dict[str, Tensor], detections: List[Dict[str, Tensor]] - ) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]: + self, losses: dict[str, Tensor], detections: list[dict[str, Tensor]] + ) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]]: if self.training: return losses @@ -439,11 +439,11 @@ def eager_outputs( def compute_loss( self, - targets: List[Dict[str, Tensor]], - head_outputs: Dict[str, Tensor], - anchors: List[Tensor], - num_anchors_per_level: List[int], - ) -> Dict[str, Tensor]: + targets: list[dict[str, Tensor]], + head_outputs: dict[str, Tensor], + anchors: list[Tensor], + num_anchors_per_level: list[int], + ) -> dict[str, Tensor]: matched_idxs = [] for anchors_per_image, targets_per_image in zip(anchors, targets): if targets_per_image["boxes"].numel() == 0: @@ -487,15 +487,15 @@ def compute_loss( return self.head.compute_loss(targets, head_outputs, anchors, matched_idxs) def postprocess_detections( - self, head_outputs: Dict[str, List[Tensor]], anchors: List[List[Tensor]], image_shapes: List[Tuple[int, int]] - ) -> List[Dict[str, Tensor]]: + self, head_outputs: dict[str, list[Tensor]], anchors: list[list[Tensor]], image_shapes: list[tuple[int, int]] + ) -> list[dict[str, Tensor]]: class_logits = head_outputs["cls_logits"] box_regression = head_outputs["bbox_regression"] box_ctrness = head_outputs["bbox_ctrness"] num_images = len(image_shapes) - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] for index in range(num_images): box_regression_per_image = [br[index] for br in box_regression] @@ -557,9 +557,9 @@ def postprocess_detections( def forward( self, - images: List[Tensor], - targets: Optional[List[Dict[str, Tensor]]] = None, - ) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]: + images: list[Tensor], + targets: Optional[list[dict[str, Tensor]]] = None, + ) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]]: """ Args: images (list[Tensor]): images to be processed @@ -584,7 +584,7 @@ def forward( f"Expected target boxes to be a tensor of shape [N, 4], got {boxes.shape}.", ) - original_image_sizes: List[Tuple[int, int]] = [] + original_image_sizes: list[tuple[int, int]] = [] for img in images: val = img.shape[-2:] torch._assert( @@ -604,7 +604,7 @@ def forward( if degenerate_boxes.any(): # print the first degenerate box bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0] - degen_bb: List[float] = boxes[bb_idx].tolist() + degen_bb: list[float] = boxes[bb_idx].tolist() torch._assert( False, f"All bounding boxes should have positive height and width. Found invalid box {degen_bb} for target at index {target_idx}.", @@ -626,7 +626,7 @@ def forward( num_anchors_per_level = [x.size(2) * x.size(3) for x in features] losses = {} - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] if self.training: if targets is None: torch._assert(False, "targets should not be none when in training mode") @@ -635,7 +635,7 @@ def forward( losses = self.compute_loss(targets, head_outputs, anchors, num_anchors_per_level) else: # split outputs per level - split_head_outputs: Dict[str, List[Tensor]] = {} + split_head_outputs: dict[str, list[Tensor]] = {} for k in head_outputs: split_head_outputs[k] = list(head_outputs[k].split(num_anchors_per_level, dim=1)) split_anchors = [list(a.split(num_anchors_per_level)) for a in anchors] diff --git a/torchvision/models/detection/generalized_rcnn.py b/torchvision/models/detection/generalized_rcnn.py index b481265077f..f07fa77aae9 100644 --- a/torchvision/models/detection/generalized_rcnn.py +++ b/torchvision/models/detection/generalized_rcnn.py @@ -4,10 +4,10 @@ import warnings from collections import OrderedDict -from typing import Dict, List, Optional, Tuple, Union +from typing import Optional, Union import torch -from torch import nn, Tensor +from torch import nn from ...utils import _log_api_usage_once @@ -25,7 +25,13 @@ class GeneralizedRCNN(nn.Module): the model """ - def __init__(self, backbone: nn.Module, rpn: nn.Module, roi_heads: nn.Module, transform: nn.Module) -> None: + def __init__( + self, + backbone: nn.Module, + rpn: nn.Module, + roi_heads: nn.Module, + transform: nn.Module, + ) -> None: super().__init__() _log_api_usage_once(self) self.transform = transform @@ -36,19 +42,23 @@ def __init__(self, backbone: nn.Module, rpn: nn.Module, roi_heads: nn.Module, tr self._has_warned = False @torch.jit.unused - def eager_outputs(self, losses, detections): - # type: (Dict[str, Tensor], List[Dict[str, Tensor]]) -> Union[Dict[str, Tensor], List[Dict[str, Tensor]]] + def eager_outputs( + self, losses: dict[str, torch.Tensor], detections: list[dict[str, torch.Tensor]] + ) -> Union[dict[str, torch.Tensor], list[dict[str, torch.Tensor]]]: if self.training: return losses return detections - def forward(self, images, targets=None): - # type: (List[Tensor], Optional[List[Dict[str, Tensor]]]) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]] + def forward( + self, + images: list[torch.Tensor], + targets: Optional[list[dict[str, torch.Tensor]]] = None, + ) -> tuple[dict[str, torch.Tensor], list[dict[str, torch.Tensor]]]: """ Args: images (list[Tensor]): images to be processed - targets (list[Dict[str, Tensor]]): ground-truth boxes present in the image (optional) + targets (list[dict[str, tensor]]): ground-truth boxes present in the image (optional) Returns: result (list[BoxList] or dict[Tensor]): the output from the model. @@ -69,9 +79,12 @@ def forward(self, images, targets=None): f"Expected target boxes to be a tensor of shape [N, 4], got {boxes.shape}.", ) else: - torch._assert(False, f"Expected target boxes to be of type Tensor, got {type(boxes)}.") + torch._assert( + False, + f"Expected target boxes to be of type Tensor, got {type(boxes)}.", + ) - original_image_sizes: List[Tuple[int, int]] = [] + original_image_sizes: list[tuple[int, int]] = [] for img in images: val = img.shape[-2:] torch._assert( @@ -91,7 +104,7 @@ def forward(self, images, targets=None): if degenerate_boxes.any(): # print the first degenerate box bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0] - degen_bb: List[float] = boxes[bb_idx].tolist() + degen_bb: list[float] = boxes[bb_idx].tolist() torch._assert( False, "All bounding boxes should have positive height and width." @@ -103,7 +116,9 @@ def forward(self, images, targets=None): features = OrderedDict([("0", features)]) proposals, proposal_losses = self.rpn(images, features, targets) detections, detector_losses = self.roi_heads(features, proposals, images.image_sizes, targets) - detections = self.transform.postprocess(detections, images.image_sizes, original_image_sizes) # type: ignore[operator] + detections = self.transform.postprocess( + detections, images.image_sizes, original_image_sizes + ) # type: ignore[operator] losses = {} losses.update(detector_losses) diff --git a/torchvision/models/detection/image_list.py b/torchvision/models/detection/image_list.py index 583866557e4..08aabe3a486 100644 --- a/torchvision/models/detection/image_list.py +++ b/torchvision/models/detection/image_list.py @@ -1,5 +1,3 @@ -from typing import List, Tuple - import torch from torch import Tensor @@ -16,7 +14,7 @@ class ImageList: image_sizes (list[tuple[int, int]]): List of Tuples each containing size of images. """ - def __init__(self, tensors: Tensor, image_sizes: List[Tuple[int, int]]) -> None: + def __init__(self, tensors: Tensor, image_sizes: list[tuple[int, int]]) -> None: self.tensors = tensors self.image_sizes = image_sizes diff --git a/torchvision/models/detection/keypoint_rcnn.py b/torchvision/models/detection/keypoint_rcnn.py index 5d7ff0ea433..42b9d65562d 100644 --- a/torchvision/models/detection/keypoint_rcnn.py +++ b/torchvision/models/detection/keypoint_rcnn.py @@ -363,9 +363,11 @@ class KeypointRCNN_ResNet50_FPN_Weights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: KeypointRCNN_ResNet50_FPN_Weights.COCO_LEGACY - if kwargs["pretrained"] == "legacy" - else KeypointRCNN_ResNet50_FPN_Weights.COCO_V1, + lambda kwargs: ( + KeypointRCNN_ResNet50_FPN_Weights.COCO_LEGACY + if kwargs["pretrained"] == "legacy" + else KeypointRCNN_ResNet50_FPN_Weights.COCO_V1 + ), ), weights_backbone=("pretrained_backbone", ResNet50_Weights.IMAGENET1K_V1), ) diff --git a/torchvision/models/detection/retinanet.py b/torchvision/models/detection/retinanet.py index a8cc7755014..cd77749d2c1 100644 --- a/torchvision/models/detection/retinanet.py +++ b/torchvision/models/detection/retinanet.py @@ -2,7 +2,7 @@ import warnings from collections import OrderedDict from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -31,7 +31,7 @@ ] -def _sum(x: List[Tensor]) -> Tensor: +def _sum(x: list[Tensor]) -> Tensor: res = x[0] for i in x[1:]: res = res + i @@ -73,14 +73,14 @@ def __init__(self, in_channels, num_anchors, num_classes, norm_layer: Optional[C self.regression_head = RetinaNetRegressionHead(in_channels, num_anchors, norm_layer=norm_layer) def compute_loss(self, targets, head_outputs, anchors, matched_idxs): - # type: (List[Dict[str, Tensor]], Dict[str, Tensor], List[Tensor], List[Tensor]) -> Dict[str, Tensor] + # type: (list[dict[str, Tensor]], dict[str, Tensor], list[Tensor], list[Tensor]) -> dict[str, Tensor] return { "classification": self.classification_head.compute_loss(targets, head_outputs, matched_idxs), "bbox_regression": self.regression_head.compute_loss(targets, head_outputs, anchors, matched_idxs), } def forward(self, x): - # type: (List[Tensor]) -> Dict[str, Tensor] + # type: (list[Tensor]) -> dict[str, Tensor] return {"cls_logits": self.classification_head(x), "bbox_regression": self.regression_head(x)} @@ -156,7 +156,7 @@ def _load_from_state_dict( ) def compute_loss(self, targets, head_outputs, matched_idxs): - # type: (List[Dict[str, Tensor]], Dict[str, Tensor], List[Tensor]) -> Tensor + # type: (list[dict[str, Tensor]], dict[str, Tensor], list[Tensor]) -> Tensor losses = [] cls_logits = head_outputs["cls_logits"] @@ -189,7 +189,7 @@ def compute_loss(self, targets, head_outputs, matched_idxs): return _sum(losses) / len(targets) def forward(self, x): - # type: (List[Tensor]) -> Tensor + # type: (list[Tensor]) -> Tensor all_cls_logits = [] for features in x: @@ -270,7 +270,7 @@ def _load_from_state_dict( ) def compute_loss(self, targets, head_outputs, anchors, matched_idxs): - # type: (List[Dict[str, Tensor]], Dict[str, Tensor], List[Tensor], List[Tensor]) -> Tensor + # type: (list[dict[str, Tensor]], dict[str, Tensor], list[Tensor], list[Tensor]) -> Tensor losses = [] bbox_regression = head_outputs["bbox_regression"] @@ -302,7 +302,7 @@ def compute_loss(self, targets, head_outputs, anchors, matched_idxs): return _sum(losses) / max(1, len(targets)) def forward(self, x): - # type: (List[Tensor]) -> Tensor + # type: (list[Tensor]) -> Tensor all_bbox_regression = [] for features in x: @@ -485,14 +485,14 @@ def __init__( @torch.jit.unused def eager_outputs(self, losses, detections): - # type: (Dict[str, Tensor], List[Dict[str, Tensor]]) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]] + # type: (dict[str, Tensor], list[dict[str, Tensor]]) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]] if self.training: return losses return detections def compute_loss(self, targets, head_outputs, anchors): - # type: (List[Dict[str, Tensor]], Dict[str, Tensor], List[Tensor]) -> Dict[str, Tensor] + # type: (list[dict[str, Tensor]], dict[str, Tensor], list[Tensor]) -> dict[str, Tensor] matched_idxs = [] for anchors_per_image, targets_per_image in zip(anchors, targets): if targets_per_image["boxes"].numel() == 0: @@ -507,13 +507,13 @@ def compute_loss(self, targets, head_outputs, anchors): return self.head.compute_loss(targets, head_outputs, anchors, matched_idxs) def postprocess_detections(self, head_outputs, anchors, image_shapes): - # type: (Dict[str, List[Tensor]], List[List[Tensor]], List[Tuple[int, int]]) -> List[Dict[str, Tensor]] + # type: (dict[str, list[Tensor]], list[list[Tensor]], list[tuple[int, int]]) -> list[dict[str, Tensor]] class_logits = head_outputs["cls_logits"] box_regression = head_outputs["bbox_regression"] num_images = len(image_shapes) - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] for index in range(num_images): box_regression_per_image = [br[index] for br in box_regression] @@ -571,7 +571,7 @@ def postprocess_detections(self, head_outputs, anchors, image_shapes): return detections def forward(self, images, targets=None): - # type: (List[Tensor], Optional[List[Dict[str, Tensor]]]) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]] + # type: (list[Tensor], Optional[list[dict[str, Tensor]]]) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]] """ Args: images (list[Tensor]): images to be processed @@ -597,7 +597,7 @@ def forward(self, images, targets=None): ) # get the original image sizes - original_image_sizes: List[Tuple[int, int]] = [] + original_image_sizes: list[tuple[int, int]] = [] for img in images: val = img.shape[-2:] torch._assert( @@ -618,7 +618,7 @@ def forward(self, images, targets=None): if degenerate_boxes.any(): # print the first degenerate box bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0] - degen_bb: List[float] = boxes[bb_idx].tolist() + degen_bb: list[float] = boxes[bb_idx].tolist() torch._assert( False, "All bounding boxes should have positive height and width." @@ -640,7 +640,7 @@ def forward(self, images, targets=None): anchors = self.anchor_generator(images, features) losses = {} - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] if self.training: if targets is None: torch._assert(False, "targets should not be none when in training mode") @@ -658,7 +658,7 @@ def forward(self, images, targets=None): num_anchors_per_level = [hw * A for hw in num_anchors_per_level] # split outputs per level - split_head_outputs: Dict[str, List[Tensor]] = {} + split_head_outputs: dict[str, list[Tensor]] = {} for k in head_outputs: split_head_outputs[k] = list(head_outputs[k].split(num_anchors_per_level, dim=1)) split_anchors = [list(a.split(num_anchors_per_level)) for a in anchors] diff --git a/torchvision/models/detection/roi_heads.py b/torchvision/models/detection/roi_heads.py index 51b210cb6f3..4e721674537 100644 --- a/torchvision/models/detection/roi_heads.py +++ b/torchvision/models/detection/roi_heads.py @@ -1,16 +1,20 @@ -from typing import Dict, List, Optional, Tuple +from typing import Optional import torch import torch.nn.functional as F import torchvision -from torch import nn, Tensor +from torch import nn from torchvision.ops import boxes as box_ops, roi_align from . import _utils as det_utils -def fastrcnn_loss(class_logits, box_regression, labels, regression_targets): - # type: (Tensor, Tensor, List[Tensor], List[Tensor]) -> Tuple[Tensor, Tensor] +def fastrcnn_loss( + class_logits: torch.Tensor, + box_regression: torch.Tensor, + labels: list[torch.Tensor], + regression_targets: list[torch.Tensor], +) -> tuple[torch.Tensor, torch.Tensor]: """ Computes the loss for Faster R-CNN. @@ -49,8 +53,7 @@ def fastrcnn_loss(class_logits, box_regression, labels, regression_targets): return classification_loss, box_loss -def maskrcnn_inference(x, labels): - # type: (Tensor, List[Tensor]) -> List[Tensor] +def maskrcnn_inference(x: torch.Tensor, labels: list[torch.Tensor]) -> list[torch.Tensor]: """ From the results of the CNN, post process the masks by taking the mask corresponding to the class with max @@ -60,7 +63,7 @@ def maskrcnn_inference(x, labels): Args: x (Tensor): the mask logits labels (list[BoxList]): bounding boxes that are used as - reference, one for ech image + reference, one for each image Returns: results (list[BoxList]): one BoxList for each image, containing @@ -95,7 +98,7 @@ def project_masks_on_boxes(gt_masks, boxes, matched_idxs, M): def maskrcnn_loss(mask_logits, proposals, gt_masks, gt_labels, mask_matched_idxs): - # type: (Tensor, List[Tensor], List[Tensor], List[Tensor], List[Tensor]) -> Tensor + # type: (Tensor, list[Tensor], list[Tensor], list[Tensor], list[Tensor]) -> Tensor """ Args: proposals (list[BoxList]) @@ -127,7 +130,7 @@ def maskrcnn_loss(mask_logits, proposals, gt_masks, gt_labels, mask_matched_idxs def keypoints_to_heatmap(keypoints, rois, heatmap_size): - # type: (Tensor, Tensor, int) -> Tuple[Tensor, Tensor] + # type: (Tensor, Tensor, int) -> tuple[Tensor, Tensor] offset_x = rois[:, 0] offset_y = rois[:, 1] scale_x = heatmap_size / (rois[:, 2] - rois[:, 0]) @@ -296,7 +299,7 @@ def heatmaps_to_keypoints(maps, rois): def keypointrcnn_loss(keypoint_logits, proposals, gt_keypoints, keypoint_matched_idxs): - # type: (Tensor, List[Tensor], List[Tensor], List[Tensor]) -> Tensor + # type: (Tensor, list[Tensor], list[Tensor], list[Tensor]) -> Tensor N, K, H, W = keypoint_logits.shape if H != W: raise ValueError( @@ -327,7 +330,7 @@ def keypointrcnn_loss(keypoint_logits, proposals, gt_keypoints, keypoint_matched def keypointrcnn_inference(x, boxes): - # type: (Tensor, List[Tensor]) -> Tuple[List[Tensor], List[Tensor]] + # type: (Tensor, list[Tensor]) -> tuple[list[Tensor], list[Tensor]] kp_probs = [] kp_scores = [] @@ -390,7 +393,7 @@ def expand_masks_tracing_scale(M, padding): def expand_masks(mask, padding): - # type: (Tensor, int) -> Tuple[Tensor, float] + # type: (Tensor, int) -> tuple[Tensor, float] M = mask.shape[-1] if torch._C._get_tracing_state(): # could not import is_tracing(), not sure why scale = expand_masks_tracing_scale(M, padding) @@ -472,7 +475,7 @@ def _onnx_paste_masks_in_image_loop(masks, boxes, im_h, im_w): def paste_masks_in_image(masks, boxes, img_shape, padding=1): - # type: (Tensor, Tensor, Tuple[int, int], int) -> Tensor + # type: (Tensor, Tensor, tuple[int, int], int) -> Tensor masks, scale = expand_masks(masks, padding=padding) boxes = expand_boxes(boxes, scale).to(dtype=torch.int64) im_h, im_w = img_shape @@ -566,7 +569,7 @@ def has_keypoint(self): return True def assign_targets_to_proposals(self, proposals, gt_boxes, gt_labels): - # type: (List[Tensor], List[Tensor], List[Tensor]) -> Tuple[List[Tensor], List[Tensor]] + # type: (list[Tensor], list[Tensor], list[Tensor]) -> tuple[list[Tensor], list[Tensor]] matched_idxs = [] labels = [] for proposals_in_image, gt_boxes_in_image, gt_labels_in_image in zip(proposals, gt_boxes, gt_labels): @@ -601,7 +604,7 @@ def assign_targets_to_proposals(self, proposals, gt_boxes, gt_labels): return matched_idxs, labels def subsample(self, labels): - # type: (List[Tensor]) -> List[Tensor] + # type: (list[Tensor]) -> list[Tensor] sampled_pos_inds, sampled_neg_inds = self.fg_bg_sampler(labels) sampled_inds = [] for img_idx, (pos_inds_img, neg_inds_img) in enumerate(zip(sampled_pos_inds, sampled_neg_inds)): @@ -610,13 +613,13 @@ def subsample(self, labels): return sampled_inds def add_gt_proposals(self, proposals, gt_boxes): - # type: (List[Tensor], List[Tensor]) -> List[Tensor] + # type: (list[Tensor], list[Tensor]) -> list[Tensor] proposals = [torch.cat((proposal, gt_box)) for proposal, gt_box in zip(proposals, gt_boxes)] return proposals def check_targets(self, targets): - # type: (Optional[List[Dict[str, Tensor]]]) -> None + # type: (Optional[list[dict[str, Tensor]]]) -> None if targets is None: raise ValueError("targets should not be None") if not all(["boxes" in t for t in targets]): @@ -629,10 +632,10 @@ def check_targets(self, targets): def select_training_samples( self, - proposals, # type: List[Tensor] - targets, # type: Optional[List[Dict[str, Tensor]]] + proposals, # type: list[Tensor] + targets, # type: Optional[list[dict[str, Tensor]]] ): - # type: (...) -> Tuple[List[Tensor], List[Tensor], List[Tensor], List[Tensor]] + # type: (...) -> tuple[list[Tensor], list[Tensor], list[Tensor], list[Tensor]] self.check_targets(targets) if targets is None: raise ValueError("targets should not be None") @@ -669,10 +672,10 @@ def postprocess_detections( self, class_logits, # type: Tensor box_regression, # type: Tensor - proposals, # type: List[Tensor] - image_shapes, # type: List[Tuple[int, int]] + proposals, # type: list[Tensor] + image_shapes, # type: list[tuple[int, int]] ): - # type: (...) -> Tuple[List[Tensor], List[Tensor], List[Tensor]] + # type: (...) -> tuple[list[Tensor], list[Tensor], list[Tensor]] device = class_logits.device num_classes = class_logits.shape[-1] @@ -726,12 +729,11 @@ def postprocess_detections( def forward( self, - features, # type: Dict[str, Tensor] - proposals, # type: List[Tensor] - image_shapes, # type: List[Tuple[int, int]] - targets=None, # type: Optional[List[Dict[str, Tensor]]] - ): - # type: (...) -> Tuple[List[Dict[str, Tensor]], Dict[str, Tensor]] + features: dict[str, torch.Tensor], + proposals: list[torch.Tensor], + image_shapes: list[tuple[int, int]], + targets: Optional[list[dict[str, torch.Tensor]]] = None, + ) -> tuple[list[dict[str, torch.Tensor]], dict[str, torch.Tensor]]: """ Args: features (List[Tensor]) @@ -743,7 +745,7 @@ def forward( for t in targets: # TODO: https://github.com/pytorch/pytorch/issues/26731 floating_point_types = (torch.float, torch.double, torch.half) - if not t["boxes"].dtype in floating_point_types: + if t["boxes"].dtype not in floating_point_types: raise TypeError(f"target boxes must of float type, instead got {t['boxes'].dtype}") if not t["labels"].dtype == torch.int64: raise TypeError(f"target labels must of int64 type, instead got {t['labels'].dtype}") @@ -762,7 +764,7 @@ def forward( box_features = self.box_head(box_features) class_logits, box_regression = self.box_predictor(box_features) - result: List[Dict[str, torch.Tensor]] = [] + result: list[dict[str, torch.Tensor]] = [] losses = {} if self.training: if labels is None: diff --git a/torchvision/models/detection/rpn.py b/torchvision/models/detection/rpn.py index f103181e4c6..ef5718922cb 100644 --- a/torchvision/models/detection/rpn.py +++ b/torchvision/models/detection/rpn.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Tuple +from typing import Optional import torch from torch import nn, Tensor @@ -68,7 +68,7 @@ def _load_from_state_dict( error_msgs, ) - def forward(self, x: List[Tensor]) -> Tuple[List[Tensor], List[Tensor]]: + def forward(self, x: list[Tensor]) -> tuple[list[Tensor], list[Tensor]]: logits = [] bbox_reg = [] for feature in x: @@ -85,7 +85,7 @@ def permute_and_flatten(layer: Tensor, N: int, A: int, C: int, H: int, W: int) - return layer -def concat_box_prediction_layers(box_cls: List[Tensor], box_regression: List[Tensor]) -> Tuple[Tensor, Tensor]: +def concat_box_prediction_layers(box_cls: list[Tensor], box_regression: list[Tensor]) -> tuple[Tensor, Tensor]: box_cls_flattened = [] box_regression_flattened = [] # for each feature level, permute the outputs to make them be in the @@ -153,8 +153,8 @@ def __init__( batch_size_per_image: int, positive_fraction: float, # Faster-RCNN Inference - pre_nms_top_n: Dict[str, int], - post_nms_top_n: Dict[str, int], + pre_nms_top_n: dict[str, int], + post_nms_top_n: dict[str, int], nms_thresh: float, score_thresh: float = 0.0, ) -> None: @@ -191,8 +191,8 @@ def post_nms_top_n(self) -> int: return self._post_nms_top_n["testing"] def assign_targets_to_anchors( - self, anchors: List[Tensor], targets: List[Dict[str, Tensor]] - ) -> Tuple[List[Tensor], List[Tensor]]: + self, anchors: list[Tensor], targets: list[dict[str, Tensor]] + ) -> tuple[list[Tensor], list[Tensor]]: labels = [] matched_gt_boxes = [] @@ -228,7 +228,7 @@ def assign_targets_to_anchors( matched_gt_boxes.append(matched_gt_boxes_per_image) return labels, matched_gt_boxes - def _get_top_n_idx(self, objectness: Tensor, num_anchors_per_level: List[int]) -> Tensor: + def _get_top_n_idx(self, objectness: Tensor, num_anchors_per_level: list[int]) -> Tensor: r = [] offset = 0 for ob in objectness.split(num_anchors_per_level, 1): @@ -243,9 +243,9 @@ def filter_proposals( self, proposals: Tensor, objectness: Tensor, - image_shapes: List[Tuple[int, int]], - num_anchors_per_level: List[int], - ) -> Tuple[List[Tensor], List[Tensor]]: + image_shapes: list[tuple[int, int]], + num_anchors_per_level: list[int], + ) -> tuple[list[Tensor], list[Tensor]]: num_images = proposals.shape[0] device = proposals.device @@ -297,8 +297,8 @@ def filter_proposals( return final_boxes, final_scores def compute_loss( - self, objectness: Tensor, pred_bbox_deltas: Tensor, labels: List[Tensor], regression_targets: List[Tensor] - ) -> Tuple[Tensor, Tensor]: + self, objectness: Tensor, pred_bbox_deltas: Tensor, labels: list[Tensor], regression_targets: list[Tensor] + ) -> tuple[Tensor, Tensor]: """ Args: objectness (Tensor) @@ -336,10 +336,9 @@ def compute_loss( def forward( self, images: ImageList, - features: Dict[str, Tensor], - targets: Optional[List[Dict[str, Tensor]]] = None, - ) -> Tuple[List[Tensor], Dict[str, Tensor]]: - + features: dict[str, Tensor], + targets: Optional[list[dict[str, Tensor]]] = None, + ) -> tuple[list[Tensor], dict[str, Tensor]]: """ Args: images (ImageList): images for which we want to compute the predictions diff --git a/torchvision/models/detection/ssd.py b/torchvision/models/detection/ssd.py index 87062d2bc88..8cd43d04c75 100644 --- a/torchvision/models/detection/ssd.py +++ b/torchvision/models/detection/ssd.py @@ -1,6 +1,6 @@ import warnings from collections import OrderedDict -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional import torch import torch.nn.functional as F @@ -56,12 +56,12 @@ def _xavier_init(conv: nn.Module): class SSDHead(nn.Module): - def __init__(self, in_channels: List[int], num_anchors: List[int], num_classes: int): + def __init__(self, in_channels: list[int], num_anchors: list[int], num_classes: int): super().__init__() self.classification_head = SSDClassificationHead(in_channels, num_anchors, num_classes) self.regression_head = SSDRegressionHead(in_channels, num_anchors) - def forward(self, x: List[Tensor]) -> Dict[str, Tensor]: + def forward(self, x: list[Tensor]) -> dict[str, Tensor]: return { "bbox_regression": self.regression_head(x), "cls_logits": self.classification_head(x), @@ -88,7 +88,7 @@ def _get_result_from_module_list(self, x: Tensor, idx: int) -> Tensor: out = module(x) return out - def forward(self, x: List[Tensor]) -> Tensor: + def forward(self, x: list[Tensor]) -> Tensor: all_results = [] for i, features in enumerate(x): @@ -106,7 +106,7 @@ def forward(self, x: List[Tensor]) -> Tensor: class SSDClassificationHead(SSDScoringHead): - def __init__(self, in_channels: List[int], num_anchors: List[int], num_classes: int): + def __init__(self, in_channels: list[int], num_anchors: list[int], num_classes: int): cls_logits = nn.ModuleList() for channels, anchors in zip(in_channels, num_anchors): cls_logits.append(nn.Conv2d(channels, num_classes * anchors, kernel_size=3, padding=1)) @@ -115,7 +115,7 @@ def __init__(self, in_channels: List[int], num_anchors: List[int], num_classes: class SSDRegressionHead(SSDScoringHead): - def __init__(self, in_channels: List[int], num_anchors: List[int]): + def __init__(self, in_channels: list[int], num_anchors: list[int]): bbox_reg = nn.ModuleList() for channels, anchors in zip(in_channels, num_anchors): bbox_reg.append(nn.Conv2d(channels, 4 * anchors, kernel_size=3, padding=1)) @@ -187,10 +187,10 @@ def __init__( self, backbone: nn.Module, anchor_generator: DefaultBoxGenerator, - size: Tuple[int, int], + size: tuple[int, int], num_classes: int, - image_mean: Optional[List[float]] = None, - image_std: Optional[List[float]] = None, + image_mean: Optional[list[float]] = None, + image_std: Optional[list[float]] = None, head: Optional[nn.Module] = None, score_thresh: float = 0.01, nms_thresh: float = 0.45, @@ -245,8 +245,8 @@ def __init__( @torch.jit.unused def eager_outputs( - self, losses: Dict[str, Tensor], detections: List[Dict[str, Tensor]] - ) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]: + self, losses: dict[str, Tensor], detections: list[dict[str, Tensor]] + ) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]]: if self.training: return losses @@ -254,11 +254,11 @@ def eager_outputs( def compute_loss( self, - targets: List[Dict[str, Tensor]], - head_outputs: Dict[str, Tensor], - anchors: List[Tensor], - matched_idxs: List[Tensor], - ) -> Dict[str, Tensor]: + targets: list[dict[str, Tensor]], + head_outputs: dict[str, Tensor], + anchors: list[Tensor], + matched_idxs: list[Tensor], + ) -> dict[str, Tensor]: bbox_regression = head_outputs["bbox_regression"] cls_logits = head_outputs["cls_logits"] @@ -324,8 +324,8 @@ def compute_loss( } def forward( - self, images: List[Tensor], targets: Optional[List[Dict[str, Tensor]]] = None - ) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]: + self, images: list[Tensor], targets: Optional[list[dict[str, Tensor]]] = None + ) -> tuple[dict[str, Tensor], list[dict[str, Tensor]]]: if self.training: if targets is None: torch._assert(False, "targets should not be none when in training mode") @@ -341,7 +341,7 @@ def forward( torch._assert(False, f"Expected target boxes to be of type Tensor, got {type(boxes)}.") # get the original image sizes - original_image_sizes: List[Tuple[int, int]] = [] + original_image_sizes: list[tuple[int, int]] = [] for img in images: val = img.shape[-2:] torch._assert( @@ -360,7 +360,7 @@ def forward( degenerate_boxes = boxes[:, 2:] <= boxes[:, :2] if degenerate_boxes.any(): bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0] - degen_bb: List[float] = boxes[bb_idx].tolist() + degen_bb: list[float] = boxes[bb_idx].tolist() torch._assert( False, "All bounding boxes should have positive height and width." @@ -381,7 +381,7 @@ def forward( anchors = self.anchor_generator(images, features) losses = {} - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] if self.training: matched_idxs = [] if targets is None: @@ -412,15 +412,15 @@ def forward( return self.eager_outputs(losses, detections) def postprocess_detections( - self, head_outputs: Dict[str, Tensor], image_anchors: List[Tensor], image_shapes: List[Tuple[int, int]] - ) -> List[Dict[str, Tensor]]: + self, head_outputs: dict[str, Tensor], image_anchors: list[Tensor], image_shapes: list[tuple[int, int]] + ) -> list[dict[str, Tensor]]: bbox_regression = head_outputs["bbox_regression"] pred_scores = F.softmax(head_outputs["cls_logits"], dim=-1) num_classes = pred_scores.size(-1) device = pred_scores.device - detections: List[Dict[str, Tensor]] = [] + detections: list[dict[str, Tensor]] = [] for boxes, scores, anchors, image_shape in zip(bbox_regression, pred_scores, image_anchors, image_shapes): boxes = self.box_coder.decode_single(boxes, anchors) @@ -536,7 +536,7 @@ def __init__(self, backbone: nn.Module, highres: bool): ) self.extra = extra - def forward(self, x: Tensor) -> Dict[str, Tensor]: + def forward(self, x: Tensor) -> dict[str, Tensor]: # L2 regularization + Rescaling of 1st block's feature map x = self.features(x) rescaled = self.scale_weight.view(1, -1, 1, 1) * F.normalize(x) diff --git a/torchvision/models/detection/ssdlite.py b/torchvision/models/detection/ssdlite.py index eda21bf941e..6b05aae0c0f 100644 --- a/torchvision/models/detection/ssdlite.py +++ b/torchvision/models/detection/ssdlite.py @@ -1,7 +1,7 @@ import warnings from collections import OrderedDict from functools import partial -from typing import Any, Callable, Dict, List, Optional, Union +from typing import Any, Callable, Optional, Union import torch from torch import nn, Tensor @@ -80,13 +80,13 @@ def _normal_init(conv: nn.Module): class SSDLiteHead(nn.Module): def __init__( - self, in_channels: List[int], num_anchors: List[int], num_classes: int, norm_layer: Callable[..., nn.Module] + self, in_channels: list[int], num_anchors: list[int], num_classes: int, norm_layer: Callable[..., nn.Module] ): super().__init__() self.classification_head = SSDLiteClassificationHead(in_channels, num_anchors, num_classes, norm_layer) self.regression_head = SSDLiteRegressionHead(in_channels, num_anchors, norm_layer) - def forward(self, x: List[Tensor]) -> Dict[str, Tensor]: + def forward(self, x: list[Tensor]) -> dict[str, Tensor]: return { "bbox_regression": self.regression_head(x), "cls_logits": self.classification_head(x), @@ -95,7 +95,7 @@ def forward(self, x: List[Tensor]) -> Dict[str, Tensor]: class SSDLiteClassificationHead(SSDScoringHead): def __init__( - self, in_channels: List[int], num_anchors: List[int], num_classes: int, norm_layer: Callable[..., nn.Module] + self, in_channels: list[int], num_anchors: list[int], num_classes: int, norm_layer: Callable[..., nn.Module] ): cls_logits = nn.ModuleList() for channels, anchors in zip(in_channels, num_anchors): @@ -105,7 +105,7 @@ def __init__( class SSDLiteRegressionHead(SSDScoringHead): - def __init__(self, in_channels: List[int], num_anchors: List[int], norm_layer: Callable[..., nn.Module]): + def __init__(self, in_channels: list[int], num_anchors: list[int], norm_layer: Callable[..., nn.Module]): bbox_reg = nn.ModuleList() for channels, anchors in zip(in_channels, num_anchors): bbox_reg.append(_prediction_block(channels, 4 * anchors, 3, norm_layer)) @@ -147,7 +147,7 @@ def __init__( self.extra = extra - def forward(self, x: Tensor) -> Dict[str, Tensor]: + def forward(self, x: Tensor) -> dict[str, Tensor]: # Get feature maps from backbone and extra. Can't be refactored due to JIT limitations. output = [] for block in self.features: diff --git a/torchvision/models/detection/transform.py b/torchvision/models/detection/transform.py index 9c569b0aafb..ac54873dee8 100644 --- a/torchvision/models/detection/transform.py +++ b/torchvision/models/detection/transform.py @@ -1,5 +1,5 @@ import math -from typing import Any, Dict, List, Optional, Tuple +from typing import Any, Optional import torch import torchvision @@ -26,9 +26,9 @@ def _resize_image_and_masks( image: Tensor, self_min_size: int, self_max_size: int, - target: Optional[Dict[str, Tensor]] = None, - fixed_size: Optional[Tuple[int, int]] = None, -) -> Tuple[Tensor, Optional[Dict[str, Tensor]]]: + target: Optional[dict[str, Tensor]] = None, + fixed_size: Optional[tuple[int, int]] = None, +) -> tuple[Tensor, Optional[dict[str, Tensor]]]: if torchvision._is_tracing(): im_shape = _get_shape_onnx(image) elif torch.jit.is_scripting(): @@ -36,7 +36,7 @@ def _resize_image_and_masks( else: im_shape = image.shape[-2:] - size: Optional[List[int]] = None + size: Optional[list[int]] = None scale_factor: Optional[float] = None recompute_scale_factor: Optional[bool] = None if fixed_size is not None: @@ -99,10 +99,10 @@ def __init__( self, min_size: int, max_size: int, - image_mean: List[float], - image_std: List[float], + image_mean: list[float], + image_std: list[float], size_divisible: int = 32, - fixed_size: Optional[Tuple[int, int]] = None, + fixed_size: Optional[tuple[int, int]] = None, **kwargs: Any, ): super().__init__() @@ -117,17 +117,17 @@ def __init__( self._skip_resize = kwargs.pop("_skip_resize", False) def forward( - self, images: List[Tensor], targets: Optional[List[Dict[str, Tensor]]] = None - ) -> Tuple[ImageList, Optional[List[Dict[str, Tensor]]]]: + self, images: list[Tensor], targets: Optional[list[dict[str, Tensor]]] = None + ) -> tuple[ImageList, Optional[list[dict[str, Tensor]]]]: images = [img for img in images] if targets is not None: # make a copy of targets to avoid modifying it in-place # once torchscript supports dict comprehension # this can be simplified as follows # targets = [{k: v for k,v in t.items()} for t in targets] - targets_copy: List[Dict[str, Tensor]] = [] + targets_copy: list[dict[str, Tensor]] = [] for t in targets: - data: Dict[str, Tensor] = {} + data: dict[str, Tensor] = {} for k, v in t.items(): data[k] = v targets_copy.append(data) @@ -146,7 +146,7 @@ def forward( image_sizes = [img.shape[-2:] for img in images] images = self.batch_images(images, size_divisible=self.size_divisible) - image_sizes_list: List[Tuple[int, int]] = [] + image_sizes_list: list[tuple[int, int]] = [] for image_size in image_sizes: torch._assert( len(image_size) == 2, @@ -168,7 +168,7 @@ def normalize(self, image: Tensor) -> Tensor: std = torch.as_tensor(self.image_std, dtype=dtype, device=device) return (image - mean[:, None, None]) / std[:, None, None] - def torch_choice(self, k: List[int]) -> int: + def torch_choice(self, k: list[int]) -> int: """ Implements `random.choice` via torch ops, so it can be compiled with TorchScript and we use PyTorch's RNG (not native RNG) @@ -179,8 +179,8 @@ def torch_choice(self, k: List[int]) -> int: def resize( self, image: Tensor, - target: Optional[Dict[str, Tensor]] = None, - ) -> Tuple[Tensor, Optional[Dict[str, Tensor]]]: + target: Optional[dict[str, Tensor]] = None, + ) -> tuple[Tensor, Optional[dict[str, Tensor]]]: h, w = image.shape[-2:] if self.training: if self._skip_resize: @@ -206,7 +206,7 @@ def resize( # _onnx_batch_images() is an implementation of # batch_images() that is supported by ONNX tracing. @torch.jit.unused - def _onnx_batch_images(self, images: List[Tensor], size_divisible: int = 32) -> Tensor: + def _onnx_batch_images(self, images: list[Tensor], size_divisible: int = 32) -> Tensor: max_size = [] for i in range(images[0].dim()): max_size_i = torch.max(torch.stack([img.shape[i] for img in images]).to(torch.float32)).to(torch.int64) @@ -227,14 +227,14 @@ def _onnx_batch_images(self, images: List[Tensor], size_divisible: int = 32) -> return torch.stack(padded_imgs) - def max_by_axis(self, the_list: List[List[int]]) -> List[int]: + def max_by_axis(self, the_list: list[list[int]]) -> list[int]: maxes = the_list[0] for sublist in the_list[1:]: for index, item in enumerate(sublist): maxes[index] = max(maxes[index], item) return maxes - def batch_images(self, images: List[Tensor], size_divisible: int = 32) -> Tensor: + def batch_images(self, images: list[Tensor], size_divisible: int = 32) -> Tensor: if torchvision._is_tracing(): # batch_images() does not export well to ONNX # call _onnx_batch_images() instead @@ -256,10 +256,10 @@ def batch_images(self, images: List[Tensor], size_divisible: int = 32) -> Tensor def postprocess( self, - result: List[Dict[str, Tensor]], - image_shapes: List[Tuple[int, int]], - original_image_sizes: List[Tuple[int, int]], - ) -> List[Dict[str, Tensor]]: + result: list[dict[str, Tensor]], + image_shapes: list[tuple[int, int]], + original_image_sizes: list[tuple[int, int]], + ) -> list[dict[str, Tensor]]: if self.training: return result for i, (pred, im_s, o_im_s) in enumerate(zip(result, image_shapes, original_image_sizes)): @@ -285,7 +285,7 @@ def __repr__(self) -> str: return format_string -def resize_keypoints(keypoints: Tensor, original_size: List[int], new_size: List[int]) -> Tensor: +def resize_keypoints(keypoints: Tensor, original_size: list[int], new_size: list[int]) -> Tensor: ratios = [ torch.tensor(s, dtype=torch.float32, device=keypoints.device) / torch.tensor(s_orig, dtype=torch.float32, device=keypoints.device) @@ -303,7 +303,7 @@ def resize_keypoints(keypoints: Tensor, original_size: List[int], new_size: List return resized_data -def resize_boxes(boxes: Tensor, original_size: List[int], new_size: List[int]) -> Tensor: +def resize_boxes(boxes: Tensor, original_size: list[int], new_size: list[int]) -> Tensor: ratios = [ torch.tensor(s, dtype=torch.float32, device=boxes.device) / torch.tensor(s_orig, dtype=torch.float32, device=boxes.device) diff --git a/torchvision/models/efficientnet.py b/torchvision/models/efficientnet.py index 65f0b2fef44..4b755a3e207 100644 --- a/torchvision/models/efficientnet.py +++ b/torchvision/models/efficientnet.py @@ -1,8 +1,9 @@ import copy import math +from collections.abc import Sequence from dataclasses import dataclass from functools import partial -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +from typing import Any, Callable, Optional, Union import torch from torch import nn, Tensor @@ -116,7 +117,7 @@ def __init__( self.use_res_connect = cnf.stride == 1 and cnf.input_channels == cnf.out_channels - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] activation_layer = nn.SiLU # expand @@ -182,7 +183,7 @@ def __init__( self.use_res_connect = cnf.stride == 1 and cnf.input_channels == cnf.out_channels - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] activation_layer = nn.SiLU expanded_channels = cnf.adjust_channels(cnf.input_channels, cnf.expand_ratio) @@ -264,7 +265,7 @@ def __init__( if norm_layer is None: norm_layer = nn.BatchNorm2d - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] # building first layer firstconv_output_channels = inverted_residual_setting[0].input_channels @@ -278,7 +279,7 @@ def __init__( total_stage_blocks = sum(cnf.num_layers for cnf in inverted_residual_setting) stage_block_id = 0 for cnf in inverted_residual_setting: - stage: List[nn.Module] = [] + stage: list[nn.Module] = [] for _ in range(cnf.num_layers): # copy to avoid modifications. shallow copy is enough block_cnf = copy.copy(cnf) @@ -365,7 +366,7 @@ def _efficientnet( def _efficientnet_conf( arch: str, **kwargs: Any, -) -> Tuple[Sequence[Union[MBConvConfig, FusedMBConvConfig]], Optional[int]]: +) -> tuple[Sequence[Union[MBConvConfig, FusedMBConvConfig]], Optional[int]]: inverted_residual_setting: Sequence[Union[MBConvConfig, FusedMBConvConfig]] if arch.startswith("efficientnet_b"): bneck_conf = partial(MBConvConfig, width_mult=kwargs.pop("width_mult"), depth_mult=kwargs.pop("depth_mult")) @@ -417,7 +418,7 @@ def _efficientnet_conf( return inverted_residual_setting, last_channel -_COMMON_META: Dict[str, Any] = { +_COMMON_META: dict[str, Any] = { "categories": _IMAGENET_CATEGORIES, } diff --git a/torchvision/models/feature_extraction.py b/torchvision/models/feature_extraction.py index a20387a6b89..320b1936d6f 100644 --- a/torchvision/models/feature_extraction.py +++ b/torchvision/models/feature_extraction.py @@ -6,7 +6,7 @@ from collections import OrderedDict from copy import deepcopy from itertools import chain -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import torch import torchvision @@ -175,7 +175,7 @@ def _warn_graph_differences(train_tracer: NodePathTracer, eval_tracer: NodePathT warnings.warn(msg + suggestion_msg) -def _get_leaf_modules_for_ops() -> List[type]: +def _get_leaf_modules_for_ops() -> list[type]: members = inspect.getmembers(torchvision.ops) result = [] for _, obj in members: @@ -184,7 +184,7 @@ def _get_leaf_modules_for_ops() -> List[type]: return result -def _set_default_tracer_kwargs(original_tr_kwargs: Optional[Dict[str, Any]]) -> Dict[str, Any]: +def _set_default_tracer_kwargs(original_tr_kwargs: Optional[dict[str, Any]]) -> dict[str, Any]: default_autowrap_modules = (math, torchvision.ops) default_leaf_modules = _get_leaf_modules_for_ops() result_tracer_kwargs = {} if original_tr_kwargs is None else original_tr_kwargs @@ -203,10 +203,10 @@ def _set_default_tracer_kwargs(original_tr_kwargs: Optional[Dict[str, Any]]) -> def get_graph_node_names( model: nn.Module, - tracer_kwargs: Optional[Dict[str, Any]] = None, + tracer_kwargs: Optional[dict[str, Any]] = None, suppress_diff_warning: bool = False, - concrete_args: Optional[Dict[str, Any]] = None, -) -> Tuple[List[str], List[str]]: + concrete_args: Optional[dict[str, Any]] = None, +) -> tuple[list[str], list[str]]: """ Dev utility to return node names in order of execution. See note on node names under :func:`create_feature_extractor`. Useful for seeing which node @@ -368,12 +368,12 @@ def __deepcopy__(self, memo): def create_feature_extractor( model: nn.Module, - return_nodes: Optional[Union[List[str], Dict[str, str]]] = None, - train_return_nodes: Optional[Union[List[str], Dict[str, str]]] = None, - eval_return_nodes: Optional[Union[List[str], Dict[str, str]]] = None, - tracer_kwargs: Optional[Dict[str, Any]] = None, + return_nodes: Optional[Union[list[str], dict[str, str]]] = None, + train_return_nodes: Optional[Union[list[str], dict[str, str]]] = None, + eval_return_nodes: Optional[Union[list[str], dict[str, str]]] = None, + tracer_kwargs: Optional[dict[str, Any]] = None, suppress_diff_warning: bool = False, - concrete_args: Optional[Dict[str, Any]] = None, + concrete_args: Optional[dict[str, Any]] = None, ) -> fx.GraphModule: """ Creates a new graph module that returns intermediate nodes from a given @@ -501,7 +501,7 @@ def create_feature_extractor( raise ValueError("If `train_return_nodes` and `eval_return_nodes` are specified, then both should be specified") # Put *_return_nodes into Dict[str, str] format - def to_strdict(n) -> Dict[str, str]: + def to_strdict(n) -> dict[str, str]: if isinstance(n, list): return {str(i): str(i) for i in n} return {str(k): str(v) for k, v in n.items()} @@ -517,7 +517,7 @@ def to_strdict(n) -> Dict[str, str]: # Repeat the tracing and graph rewriting for train and eval mode tracers = {} graphs = {} - mode_return_nodes: Dict[str, Dict[str, str]] = {"train": train_return_nodes, "eval": eval_return_nodes} + mode_return_nodes: dict[str, dict[str, str]] = {"train": train_return_nodes, "eval": eval_return_nodes} for mode in ["train", "eval"]: if mode == "train": model.train() diff --git a/torchvision/models/googlenet.py b/torchvision/models/googlenet.py index 1d8ecbcd3b2..bfb29764951 100644 --- a/torchvision/models/googlenet.py +++ b/torchvision/models/googlenet.py @@ -1,7 +1,7 @@ import warnings from collections import namedtuple from functools import partial -from typing import Any, Callable, List, Optional, Tuple +from typing import Any, Callable, Optional import torch import torch.nn as nn @@ -35,7 +35,7 @@ def __init__( aux_logits: bool = True, transform_input: bool = False, init_weights: Optional[bool] = None, - blocks: Optional[List[Callable[..., nn.Module]]] = None, + blocks: Optional[list[Callable[..., nn.Module]]] = None, dropout: float = 0.2, dropout_aux: float = 0.7, ) -> None: @@ -107,7 +107,7 @@ def _transform_input(self, x: Tensor) -> Tensor: x = torch.cat((x_ch0, x_ch1, x_ch2), 1) return x - def _forward(self, x: Tensor) -> Tuple[Tensor, Optional[Tensor], Optional[Tensor]]: + def _forward(self, x: Tensor) -> tuple[Tensor, Optional[Tensor], Optional[Tensor]]: # N x 3 x 224 x 224 x = self.conv1(x) # N x 64 x 112 x 112 @@ -214,7 +214,7 @@ def __init__( conv_block(in_channels, pool_proj, kernel_size=1), ) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch1 = self.branch1(x) branch2 = self.branch2(x) branch3 = self.branch3(x) diff --git a/torchvision/models/inception.py b/torchvision/models/inception.py index 447a7682d62..7c36ec2a0ad 100644 --- a/torchvision/models/inception.py +++ b/torchvision/models/inception.py @@ -1,7 +1,7 @@ import warnings from collections import namedtuple from functools import partial -from typing import Any, Callable, List, Optional, Tuple +from typing import Any, Callable, Optional import torch import torch.nn.functional as F @@ -31,7 +31,7 @@ def __init__( num_classes: int = 1000, aux_logits: bool = True, transform_input: bool = False, - inception_blocks: Optional[List[Callable[..., nn.Module]]] = None, + inception_blocks: Optional[list[Callable[..., nn.Module]]] = None, init_weights: Optional[bool] = None, dropout: float = 0.5, ) -> None: @@ -100,7 +100,7 @@ def _transform_input(self, x: Tensor) -> Tensor: x = torch.cat((x_ch0, x_ch1, x_ch2), 1) return x - def _forward(self, x: Tensor) -> Tuple[Tensor, Optional[Tensor]]: + def _forward(self, x: Tensor) -> tuple[Tensor, Optional[Tensor]]: # N x 3 x 299 x 299 x = self.Conv2d_1a_3x3(x) # N x 32 x 149 x 149 @@ -191,7 +191,7 @@ def __init__( self.branch_pool = conv_block(in_channels, pool_features, kernel_size=1) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch1x1 = self.branch1x1(x) branch5x5 = self.branch5x5_1(x) @@ -223,7 +223,7 @@ def __init__(self, in_channels: int, conv_block: Optional[Callable[..., nn.Modul self.branch3x3dbl_2 = conv_block(64, 96, kernel_size=3, padding=1) self.branch3x3dbl_3 = conv_block(96, 96, kernel_size=3, stride=2) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch3x3 = self.branch3x3(x) branch3x3dbl = self.branch3x3dbl_1(x) @@ -262,7 +262,7 @@ def __init__( self.branch_pool = conv_block(in_channels, 192, kernel_size=1) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch1x1 = self.branch1x1(x) branch7x7 = self.branch7x7_1(x) @@ -299,7 +299,7 @@ def __init__(self, in_channels: int, conv_block: Optional[Callable[..., nn.Modul self.branch7x7x3_3 = conv_block(192, 192, kernel_size=(7, 1), padding=(3, 0)) self.branch7x7x3_4 = conv_block(192, 192, kernel_size=3, stride=2) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch3x3 = self.branch3x3_1(x) branch3x3 = self.branch3x3_2(branch3x3) @@ -335,7 +335,7 @@ def __init__(self, in_channels: int, conv_block: Optional[Callable[..., nn.Modul self.branch_pool = conv_block(in_channels, 192, kernel_size=1) - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch1x1 = self.branch1x1(x) branch3x3 = self.branch3x3_1(x) diff --git a/torchvision/models/maxvit.py b/torchvision/models/maxvit.py index 66f49772218..53cc53e5ed9 100644 --- a/torchvision/models/maxvit.py +++ b/torchvision/models/maxvit.py @@ -1,7 +1,8 @@ import math from collections import OrderedDict +from collections.abc import Sequence from functools import partial -from typing import Any, Callable, List, Optional, Sequence, Tuple +from typing import Any, Callable, Optional import numpy as np import torch @@ -22,14 +23,14 @@ ] -def _get_conv_output_shape(input_size: Tuple[int, int], kernel_size: int, stride: int, padding: int) -> Tuple[int, int]: +def _get_conv_output_shape(input_size: tuple[int, int], kernel_size: int, stride: int, padding: int) -> tuple[int, int]: return ( (input_size[0] - kernel_size + 2 * padding) // stride + 1, (input_size[1] - kernel_size + 2 * padding) // stride + 1, ) -def _make_block_input_shapes(input_size: Tuple[int, int], n_blocks: int) -> List[Tuple[int, int]]: +def _make_block_input_shapes(input_size: tuple[int, int], n_blocks: int) -> list[tuple[int, int]]: """Util function to check that the input size is correct for a MaxVit configuration.""" shapes = [] block_input_shape = _get_conv_output_shape(input_size, 3, 2, 1) @@ -306,7 +307,7 @@ def __init__( partition_type: str, # grid size needs to be known at initialization time # because we need to know hamy relative offsets there are in the grid - grid_size: Tuple[int, int], + grid_size: tuple[int, int], mlp_ratio: int, activation_layer: Callable[..., nn.Module], norm_layer: Callable[..., nn.Module], @@ -423,7 +424,7 @@ def __init__( p_stochastic_dropout: float, # partitioning parameters partition_size: int, - grid_size: Tuple[int, int], + grid_size: tuple[int, int], ) -> None: super().__init__() @@ -519,10 +520,10 @@ def __init__( attention_dropout: float, # partitioning parameters partition_size: int, - input_grid_size: Tuple[int, int], + input_grid_size: tuple[int, int], # number of layers n_layers: int, - p_stochastic: List[float], + p_stochastic: list[float], ) -> None: super().__init__() if not len(p_stochastic) == n_layers: @@ -589,14 +590,14 @@ class MaxVit(nn.Module): def __init__( self, # input size parameters - input_size: Tuple[int, int], + input_size: tuple[int, int], # stem and task parameters stem_channels: int, # partitioning parameters partition_size: int, # block parameters - block_channels: List[int], - block_layers: List[int], + block_channels: list[int], + block_layers: list[int], # attention head dimensions head_dim: int, stochastic_depth_prob: float, @@ -730,8 +731,8 @@ def _maxvit( # stem parameters stem_channels: int, # block parameters - block_channels: List[int], - block_layers: List[int], + block_channels: list[int], + block_layers: list[int], stochastic_depth_prob: float, # partitioning parameters partition_size: int, diff --git a/torchvision/models/mnasnet.py b/torchvision/models/mnasnet.py index 5846111ab1c..a0efff4e962 100644 --- a/torchvision/models/mnasnet.py +++ b/torchvision/models/mnasnet.py @@ -1,6 +1,6 @@ import warnings from functools import partial -from typing import Any, Dict, List, Optional +from typing import Any, Optional import torch import torch.nn as nn @@ -87,7 +87,7 @@ def _round_to_multiple_of(val: float, divisor: int, round_up_bias: float = 0.9) return new_val if new_val >= round_up_bias * val else new_val + divisor -def _get_depths(alpha: float) -> List[int]: +def _get_depths(alpha: float) -> list[int]: """Scales tensor depths as in reference MobileNet code, prefers rounding up rather than down.""" depths = [32, 16, 24, 40, 80, 96, 192, 320] @@ -163,13 +163,13 @@ def forward(self, x: Tensor) -> Tensor: def _load_from_state_dict( self, - state_dict: Dict, + state_dict: dict, prefix: str, - local_metadata: Dict, + local_metadata: dict, strict: bool, - missing_keys: List[str], - unexpected_keys: List[str], - error_msgs: List[str], + missing_keys: list[str], + unexpected_keys: list[str], + error_msgs: list[str], ) -> None: version = local_metadata.get("version", None) if version not in [1, 2]: diff --git a/torchvision/models/mobilenetv2.py b/torchvision/models/mobilenetv2.py index fbb6a4981d6..97f62e398a3 100644 --- a/torchvision/models/mobilenetv2.py +++ b/torchvision/models/mobilenetv2.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, Callable, List, Optional +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -31,7 +31,7 @@ def __init__( hidden_dim = int(round(inp * expand_ratio)) self.use_res_connect = self.stride == 1 and inp == oup - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] if expand_ratio != 1: # pw layers.append( @@ -69,7 +69,7 @@ def __init__( self, num_classes: int = 1000, width_mult: float = 1.0, - inverted_residual_setting: Optional[List[List[int]]] = None, + inverted_residual_setting: Optional[list[list[int]]] = None, round_nearest: int = 8, block: Optional[Callable[..., nn.Module]] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, @@ -122,7 +122,7 @@ def __init__( # building first layer input_channel = _make_divisible(input_channel * width_mult, round_nearest) self.last_channel = _make_divisible(last_channel * max(1.0, width_mult), round_nearest) - features: List[nn.Module] = [ + features: list[nn.Module] = [ Conv2dNormActivation(3, input_channel, stride=2, norm_layer=norm_layer, activation_layer=nn.ReLU6) ] # building inverted residual blocks diff --git a/torchvision/models/mobilenetv3.py b/torchvision/models/mobilenetv3.py index 1041d4d149f..e6239d095ba 100644 --- a/torchvision/models/mobilenetv3.py +++ b/torchvision/models/mobilenetv3.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from functools import partial -from typing import Any, Callable, List, Optional, Sequence +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -63,7 +64,7 @@ def __init__( self.use_res_connect = cnf.stride == 1 and cnf.input_channels == cnf.out_channels - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] activation_layer = nn.Hardswish if cnf.use_hs else nn.ReLU # expand @@ -117,7 +118,7 @@ def forward(self, input: Tensor) -> Tensor: class MobileNetV3(nn.Module): def __init__( self, - inverted_residual_setting: List[InvertedResidualConfig], + inverted_residual_setting: list[InvertedResidualConfig], last_channel: int, num_classes: int = 1000, block: Optional[Callable[..., nn.Module]] = None, @@ -153,7 +154,7 @@ def __init__( if norm_layer is None: norm_layer = partial(nn.BatchNorm2d, eps=0.001, momentum=0.01) - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] # building first layer firstconv_output_channels = inverted_residual_setting[0].input_channels @@ -270,7 +271,7 @@ def _mobilenet_v3_conf( def _mobilenet_v3( - inverted_residual_setting: List[InvertedResidualConfig], + inverted_residual_setting: list[InvertedResidualConfig], last_channel: int, weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/optical_flow/raft.py b/torchvision/models/optical_flow/raft.py index 3622887e3a0..644adc2dc5c 100644 --- a/torchvision/models/optical_flow/raft.py +++ b/torchvision/models/optical_flow/raft.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional import torch import torch.nn as nn @@ -349,7 +349,7 @@ def __init__(self, *, num_levels: int = 4, radius: int = 4): self.num_levels = num_levels self.radius = radius - self.corr_pyramid: List[Tensor] = [torch.tensor(0)] # useless, but torchscript is otherwise confused :') + self.corr_pyramid: list[Tensor] = [torch.tensor(0)] # useless, but torchscript is otherwise confused :') # The neighborhood of a centroid pixel x' is {x' + delta, ||delta||_inf <= radius} # so it's a square surrounding x', and its sides have a length of 2 * radius + 1 diff --git a/torchvision/models/quantization/googlenet.py b/torchvision/models/quantization/googlenet.py index 30ef3356ba1..49ec1a340dd 100644 --- a/torchvision/models/quantization/googlenet.py +++ b/torchvision/models/quantization/googlenet.py @@ -138,9 +138,11 @@ class GoogLeNet_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: GoogLeNet_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else GoogLeNet_Weights.IMAGENET1K_V1, + lambda kwargs: ( + GoogLeNet_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else GoogLeNet_Weights.IMAGENET1K_V1 + ), ) ) def googlenet( diff --git a/torchvision/models/quantization/inception.py b/torchvision/models/quantization/inception.py index 75c126697e9..a6eb9370d0d 100644 --- a/torchvision/models/quantization/inception.py +++ b/torchvision/models/quantization/inception.py @@ -1,6 +1,6 @@ import warnings from functools import partial -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union import torch import torch.nn as nn @@ -90,7 +90,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: self.myop2 = nn.quantized.FloatFunctional() self.myop3 = nn.quantized.FloatFunctional() - def _forward(self, x: Tensor) -> List[Tensor]: + def _forward(self, x: Tensor) -> list[Tensor]: branch1x1 = self.branch1x1(x) branch3x3 = self.branch3x3_1(x) @@ -198,9 +198,11 @@ class Inception_V3_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: Inception_V3_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else Inception_V3_Weights.IMAGENET1K_V1, + lambda kwargs: ( + Inception_V3_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else Inception_V3_Weights.IMAGENET1K_V1 + ), ) ) def inception_v3( diff --git a/torchvision/models/quantization/mobilenetv2.py b/torchvision/models/quantization/mobilenetv2.py index 4700bb4af93..d1cef2d9413 100644 --- a/torchvision/models/quantization/mobilenetv2.py +++ b/torchvision/models/quantization/mobilenetv2.py @@ -95,9 +95,11 @@ class MobileNet_V2_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: MobileNet_V2_QuantizedWeights.IMAGENET1K_QNNPACK_V1 - if kwargs.get("quantize", False) - else MobileNet_V2_Weights.IMAGENET1K_V1, + lambda kwargs: ( + MobileNet_V2_QuantizedWeights.IMAGENET1K_QNNPACK_V1 + if kwargs.get("quantize", False) + else MobileNet_V2_Weights.IMAGENET1K_V1 + ), ) ) def mobilenet_v2( diff --git a/torchvision/models/quantization/mobilenetv3.py b/torchvision/models/quantization/mobilenetv3.py index f1fdcfec957..7431b07df85 100644 --- a/torchvision/models/quantization/mobilenetv3.py +++ b/torchvision/models/quantization/mobilenetv3.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union import torch from torch import nn, Tensor @@ -123,7 +123,7 @@ def fuse_model(self, is_qat: Optional[bool] = None) -> None: def _mobilenet_v3_model( - inverted_residual_setting: List[InvertedResidualConfig], + inverted_residual_setting: list[InvertedResidualConfig], last_channel: int, weights: Optional[WeightsEnum], progress: bool, @@ -190,9 +190,11 @@ class MobileNet_V3_Large_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: MobileNet_V3_Large_QuantizedWeights.IMAGENET1K_QNNPACK_V1 - if kwargs.get("quantize", False) - else MobileNet_V3_Large_Weights.IMAGENET1K_V1, + lambda kwargs: ( + MobileNet_V3_Large_QuantizedWeights.IMAGENET1K_QNNPACK_V1 + if kwargs.get("quantize", False) + else MobileNet_V3_Large_Weights.IMAGENET1K_V1 + ), ) ) def mobilenet_v3_large( diff --git a/torchvision/models/quantization/resnet.py b/torchvision/models/quantization/resnet.py index 39958a010fb..bc4ba003b6a 100644 --- a/torchvision/models/quantization/resnet.py +++ b/torchvision/models/quantization/resnet.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, List, Optional, Type, Union +from typing import Any, Optional, Union import torch import torch.nn as nn @@ -125,8 +125,8 @@ def fuse_model(self, is_qat: Optional[bool] = None) -> None: def _resnet( - block: Type[Union[QuantizableBasicBlock, QuantizableBottleneck]], - layers: List[int], + block: type[Union[QuantizableBasicBlock, QuantizableBottleneck]], + layers: list[int], weights: Optional[WeightsEnum], progress: bool, quantize: bool, @@ -284,9 +284,11 @@ class ResNeXt101_64X4D_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ResNet18_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ResNet18_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ResNet18_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ResNet18_Weights.IMAGENET1K_V1 + ), ) ) def resnet18( @@ -334,9 +336,11 @@ def resnet18( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ResNet50_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ResNet50_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ResNet50_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ResNet50_Weights.IMAGENET1K_V1 + ), ) ) def resnet50( @@ -384,9 +388,11 @@ def resnet50( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ResNeXt101_32X8D_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ResNeXt101_32X8D_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ResNeXt101_32X8D_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ResNeXt101_32X8D_Weights.IMAGENET1K_V1 + ), ) ) def resnext101_32x8d( @@ -436,9 +442,11 @@ def resnext101_32x8d( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ResNeXt101_64X4D_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ResNeXt101_64X4D_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ResNeXt101_64X4D_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ResNeXt101_64X4D_Weights.IMAGENET1K_V1 + ), ) ) def resnext101_64x4d( diff --git a/torchvision/models/quantization/shufflenetv2.py b/torchvision/models/quantization/shufflenetv2.py index 3e1b01356a7..d0a2eb8eb1b 100644 --- a/torchvision/models/quantization/shufflenetv2.py +++ b/torchvision/models/quantization/shufflenetv2.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union import torch import torch.nn as nn @@ -88,8 +88,8 @@ def fuse_model(self, is_qat: Optional[bool] = None) -> None: def _shufflenetv2( - stages_repeats: List[int], - stages_out_channels: List[int], + stages_repeats: list[int], + stages_out_channels: list[int], *, weights: Optional[WeightsEnum], progress: bool, @@ -215,9 +215,11 @@ class ShuffleNet_V2_X2_0_QuantizedWeights(WeightsEnum): @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ShuffleNet_V2_X0_5_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ShuffleNet_V2_X0_5_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ShuffleNet_V2_X0_5_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ShuffleNet_V2_X0_5_Weights.IMAGENET1K_V1 + ), ) ) def shufflenet_v2_x0_5( @@ -269,9 +271,11 @@ def shufflenet_v2_x0_5( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ShuffleNet_V2_X1_0_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ShuffleNet_V2_X1_0_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ShuffleNet_V2_X1_0_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ShuffleNet_V2_X1_0_Weights.IMAGENET1K_V1 + ), ) ) def shufflenet_v2_x1_0( @@ -323,9 +327,11 @@ def shufflenet_v2_x1_0( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ShuffleNet_V2_X1_5_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ShuffleNet_V2_X1_5_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ShuffleNet_V2_X1_5_Weights.IMAGENET1K_V1 + ), ) ) def shufflenet_v2_x1_5( @@ -377,9 +383,11 @@ def shufflenet_v2_x1_5( @handle_legacy_interface( weights=( "pretrained", - lambda kwargs: ShuffleNet_V2_X2_0_QuantizedWeights.IMAGENET1K_FBGEMM_V1 - if kwargs.get("quantize", False) - else ShuffleNet_V2_X2_0_Weights.IMAGENET1K_V1, + lambda kwargs: ( + ShuffleNet_V2_X2_0_QuantizedWeights.IMAGENET1K_FBGEMM_V1 + if kwargs.get("quantize", False) + else ShuffleNet_V2_X2_0_Weights.IMAGENET1K_V1 + ), ) ) def shufflenet_v2_x2_0( diff --git a/torchvision/models/quantization/utils.py b/torchvision/models/quantization/utils.py index a21e2af8e01..71d50bb9b48 100644 --- a/torchvision/models/quantization/utils.py +++ b/torchvision/models/quantization/utils.py @@ -1,4 +1,4 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union import torch from torch import nn @@ -43,7 +43,7 @@ def quantize_model(model: nn.Module, backend: str) -> None: def _fuse_modules( - model: nn.Module, modules_to_fuse: Union[List[str], List[List[str]]], is_qat: Optional[bool], **kwargs: Any + model: nn.Module, modules_to_fuse: Union[list[str], list[list[str]]], is_qat: Optional[bool], **kwargs: Any ): if is_qat is None: is_qat = model.training diff --git a/torchvision/models/regnet.py b/torchvision/models/regnet.py index f37b2994e48..915ef22bf33 100644 --- a/torchvision/models/regnet.py +++ b/torchvision/models/regnet.py @@ -1,7 +1,7 @@ import math from collections import OrderedDict from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Optional import torch from torch import nn, Tensor @@ -185,11 +185,11 @@ def __init__( class BlockParams: def __init__( self, - depths: List[int], - widths: List[int], - group_widths: List[int], - bottleneck_multipliers: List[float], - strides: List[int], + depths: list[int], + widths: list[int], + group_widths: list[int], + bottleneck_multipliers: list[float], + strides: list[int], se_ratio: Optional[float] = None, ) -> None: self.depths = depths @@ -277,8 +277,8 @@ def _get_expanded_params(self): @staticmethod def _adjust_widths_groups_compatibilty( - stage_widths: List[int], bottleneck_ratios: List[float], group_widths: List[int] - ) -> Tuple[List[int], List[int]]: + stage_widths: list[int], bottleneck_ratios: list[float], group_widths: list[int] + ) -> tuple[list[int], list[int]]: """ Adjusts the compatibility of widths and groups, depending on the bottleneck ratio. @@ -402,7 +402,7 @@ def _regnet( return model -_COMMON_META: Dict[str, Any] = { +_COMMON_META: dict[str, Any] = { "min_size": (1, 1), "categories": _IMAGENET_CATEGORIES, } diff --git a/torchvision/models/resnet.py b/torchvision/models/resnet.py index 83c0340cef7..47067ec8317 100644 --- a/torchvision/models/resnet.py +++ b/torchvision/models/resnet.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, Callable, List, Optional, Type, Union +from typing import Any, Callable, Optional, Union import torch import torch.nn as nn @@ -166,13 +166,13 @@ def forward(self, x: Tensor) -> Tensor: class ResNet(nn.Module): def __init__( self, - block: Type[Union[BasicBlock, Bottleneck]], - layers: List[int], + block: type[Union[BasicBlock, Bottleneck]], + layers: list[int], num_classes: int = 1000, zero_init_residual: bool = False, groups: int = 1, width_per_group: int = 64, - replace_stride_with_dilation: Optional[List[bool]] = None, + replace_stride_with_dilation: Optional[list[bool]] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, ) -> None: super().__init__() @@ -224,7 +224,7 @@ def __init__( def _make_layer( self, - block: Type[Union[BasicBlock, Bottleneck]], + block: type[Union[BasicBlock, Bottleneck]], planes: int, blocks: int, stride: int = 1, @@ -286,8 +286,8 @@ def forward(self, x: Tensor) -> Tensor: def _resnet( - block: Type[Union[BasicBlock, Bottleneck]], - layers: List[int], + block: type[Union[BasicBlock, Bottleneck]], + layers: list[int], weights: Optional[WeightsEnum], progress: bool, **kwargs: Any, diff --git a/torchvision/models/segmentation/_utils.py b/torchvision/models/segmentation/_utils.py index 56560e9dab5..45bc2e7c435 100644 --- a/torchvision/models/segmentation/_utils.py +++ b/torchvision/models/segmentation/_utils.py @@ -1,5 +1,5 @@ from collections import OrderedDict -from typing import Dict, Optional +from typing import Optional from torch import nn, Tensor from torch.nn import functional as F @@ -17,7 +17,7 @@ def __init__(self, backbone: nn.Module, classifier: nn.Module, aux_classifier: O self.classifier = classifier self.aux_classifier = aux_classifier - def forward(self, x: Tensor) -> Dict[str, Tensor]: + def forward(self, x: Tensor) -> dict[str, Tensor]: input_shape = x.shape[-2:] # contract: features is a dict of tensors features = self.backbone(x) diff --git a/torchvision/models/segmentation/deeplabv3.py b/torchvision/models/segmentation/deeplabv3.py index a92ddfe3b7a..62790ecb4dd 100644 --- a/torchvision/models/segmentation/deeplabv3.py +++ b/torchvision/models/segmentation/deeplabv3.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from functools import partial -from typing import Any, Optional, Sequence +from typing import Any, Optional import torch from torch import nn diff --git a/torchvision/models/segmentation/lraspp.py b/torchvision/models/segmentation/lraspp.py index 70bced70fd3..e49b06d5b9f 100644 --- a/torchvision/models/segmentation/lraspp.py +++ b/torchvision/models/segmentation/lraspp.py @@ -1,6 +1,6 @@ from collections import OrderedDict from functools import partial -from typing import Any, Dict, Optional +from typing import Any, Optional from torch import nn, Tensor from torch.nn import functional as F @@ -40,7 +40,7 @@ def __init__( self.backbone = backbone self.classifier = LRASPPHead(low_channels, high_channels, num_classes, inter_channels) - def forward(self, input: Tensor) -> Dict[str, Tensor]: + def forward(self, input: Tensor) -> dict[str, Tensor]: features = self.backbone(input) out = self.classifier(features) out = F.interpolate(out, size=input.shape[-2:], mode="bilinear", align_corners=False) @@ -67,7 +67,7 @@ def __init__(self, low_channels: int, high_channels: int, num_classes: int, inte self.low_classifier = nn.Conv2d(low_channels, num_classes, 1) self.high_classifier = nn.Conv2d(inter_channels, num_classes, 1) - def forward(self, input: Dict[str, Tensor]) -> Tensor: + def forward(self, input: dict[str, Tensor]) -> Tensor: low = input["low"] high = input["high"] diff --git a/torchvision/models/shufflenetv2.py b/torchvision/models/shufflenetv2.py index 3f3322b7a88..96736f6a7ac 100644 --- a/torchvision/models/shufflenetv2.py +++ b/torchvision/models/shufflenetv2.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, Callable, List, Optional +from typing import Any, Callable, Optional import torch import torch.nn as nn @@ -104,8 +104,8 @@ def forward(self, x: Tensor) -> Tensor: class ShuffleNetV2(nn.Module): def __init__( self, - stages_repeats: List[int], - stages_out_channels: List[int], + stages_repeats: list[int], + stages_out_channels: list[int], num_classes: int = 1000, inverted_residual: Callable[..., nn.Module] = InvertedResidual, ) -> None: diff --git a/torchvision/models/swin_transformer.py b/torchvision/models/swin_transformer.py index 2035f659bfc..80850b4a389 100644 --- a/torchvision/models/swin_transformer.py +++ b/torchvision/models/swin_transformer.py @@ -1,6 +1,6 @@ import math from functools import partial -from typing import Any, Callable, List, Optional +from typing import Any, Callable, Optional import torch import torch.nn.functional as F @@ -47,7 +47,7 @@ def _patch_merging_pad(x: torch.Tensor) -> torch.Tensor: def _get_relative_position_bias( - relative_position_bias_table: torch.Tensor, relative_position_index: torch.Tensor, window_size: List[int] + relative_position_bias_table: torch.Tensor, relative_position_index: torch.Tensor, window_size: list[int] ) -> torch.Tensor: N = window_size[0] * window_size[1] relative_position_bias = relative_position_bias_table[relative_position_index] # type: ignore[index] @@ -118,9 +118,9 @@ def shifted_window_attention( qkv_weight: Tensor, proj_weight: Tensor, relative_position_bias: Tensor, - window_size: List[int], + window_size: list[int], num_heads: int, - shift_size: List[int], + shift_size: list[int], attention_dropout: float = 0.0, dropout: float = 0.0, qkv_bias: Optional[Tensor] = None, @@ -239,8 +239,8 @@ class ShiftedWindowAttention(nn.Module): def __init__( self, dim: int, - window_size: List[int], - shift_size: List[int], + window_size: list[int], + shift_size: list[int], num_heads: int, qkv_bias: bool = True, proj_bias: bool = True, @@ -320,8 +320,8 @@ class ShiftedWindowAttentionV2(ShiftedWindowAttention): def __init__( self, dim: int, - window_size: List[int], - shift_size: List[int], + window_size: list[int], + shift_size: list[int], num_heads: int, qkv_bias: bool = True, proj_bias: bool = True, @@ -418,8 +418,8 @@ def __init__( self, dim: int, num_heads: int, - window_size: List[int], - shift_size: List[int], + window_size: list[int], + shift_size: list[int], mlp_ratio: float = 4.0, dropout: float = 0.0, attention_dropout: float = 0.0, @@ -475,8 +475,8 @@ def __init__( self, dim: int, num_heads: int, - window_size: List[int], - shift_size: List[int], + window_size: list[int], + shift_size: list[int], mlp_ratio: float = 4.0, dropout: float = 0.0, attention_dropout: float = 0.0, @@ -527,11 +527,11 @@ class SwinTransformer(nn.Module): def __init__( self, - patch_size: List[int], + patch_size: list[int], embed_dim: int, - depths: List[int], - num_heads: List[int], - window_size: List[int], + depths: list[int], + num_heads: list[int], + window_size: list[int], mlp_ratio: float = 4.0, dropout: float = 0.0, attention_dropout: float = 0.0, @@ -550,7 +550,7 @@ def __init__( if norm_layer is None: norm_layer = partial(nn.LayerNorm, eps=1e-5) - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] # split image into non-overlapping patches layers.append( nn.Sequential( @@ -566,7 +566,7 @@ def __init__( stage_block_id = 0 # build SwinTransformer blocks for i_stage in range(len(depths)): - stage: List[nn.Module] = [] + stage: list[nn.Module] = [] dim = embed_dim * 2**i_stage for i_layer in range(depths[i_stage]): # adjust stochastic depth probability based on the depth of the stage block @@ -615,11 +615,11 @@ def forward(self, x): def _swin_transformer( - patch_size: List[int], + patch_size: list[int], embed_dim: int, - depths: List[int], - num_heads: List[int], - window_size: List[int], + depths: list[int], + num_heads: list[int], + window_size: list[int], stochastic_depth_prob: float, weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/vgg.py b/torchvision/models/vgg.py index 0a548570dd4..feed0ce8d77 100644 --- a/torchvision/models/vgg.py +++ b/torchvision/models/vgg.py @@ -1,5 +1,5 @@ from functools import partial -from typing import Any, cast, Dict, List, Optional, Union +from typing import Any, cast, Optional, Union import torch import torch.nn as nn @@ -70,8 +70,8 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: return x -def make_layers(cfg: List[Union[str, int]], batch_norm: bool = False) -> nn.Sequential: - layers: List[nn.Module] = [] +def make_layers(cfg: list[Union[str, int]], batch_norm: bool = False) -> nn.Sequential: + layers: list[nn.Module] = [] in_channels = 3 for v in cfg: if v == "M": @@ -87,7 +87,7 @@ def make_layers(cfg: List[Union[str, int]], batch_norm: bool = False) -> nn.Sequ return nn.Sequential(*layers) -cfgs: Dict[str, List[Union[str, int]]] = { +cfgs: dict[str, list[Union[str, int]]] = { "A": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"], "B": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"], "D": [64, 64, "M", 128, 128, "M", 256, 256, 256, "M", 512, 512, 512, "M", 512, 512, 512, "M"], diff --git a/torchvision/models/video/mvit.py b/torchvision/models/video/mvit.py index 159c12a4f3e..64d6d171b75 100644 --- a/torchvision/models/video/mvit.py +++ b/torchvision/models/video/mvit.py @@ -1,7 +1,8 @@ import math +from collections.abc import Sequence from dataclasses import dataclass from functools import partial -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple +from typing import Any, Callable, Optional import torch import torch.fx @@ -29,10 +30,10 @@ class MSBlockConfig: num_heads: int input_channels: int output_channels: int - kernel_q: List[int] - kernel_kv: List[int] - stride_q: List[int] - stride_kv: List[int] + kernel_q: list[int] + kernel_kv: list[int] + stride_q: list[int] + stride_kv: list[int] def _prod(s: Sequence[int]) -> int: @@ -42,7 +43,7 @@ def _prod(s: Sequence[int]) -> int: return product -def _unsqueeze(x: torch.Tensor, target_dim: int, expand_dim: int) -> Tuple[torch.Tensor, int]: +def _unsqueeze(x: torch.Tensor, target_dim: int, expand_dim: int) -> tuple[torch.Tensor, int]: tensor_dim = x.dim() if tensor_dim == target_dim - 1: x = x.unsqueeze(expand_dim) @@ -79,7 +80,7 @@ def __init__( self.norm_act = nn.Sequential(*layers) if layers else None self.norm_before_pool = norm_before_pool - def forward(self, x: torch.Tensor, thw: Tuple[int, int, int]) -> Tuple[torch.Tensor, Tuple[int, int, int]]: + def forward(self, x: torch.Tensor, thw: tuple[int, int, int]) -> tuple[torch.Tensor, tuple[int, int, int]]: x, tensor_dim = _unsqueeze(x, 4, 1) # Separate the class token and reshape the input @@ -123,8 +124,8 @@ def _interpolate(embedding: torch.Tensor, d: int) -> torch.Tensor: def _add_rel_pos( attn: torch.Tensor, q: torch.Tensor, - q_thw: Tuple[int, int, int], - k_thw: Tuple[int, int, int], + q_thw: tuple[int, int, int], + k_thw: tuple[int, int, int], rel_pos_h: torch.Tensor, rel_pos_w: torch.Tensor, rel_pos_t: torch.Tensor, @@ -195,14 +196,14 @@ def _add_shortcut(x: torch.Tensor, shortcut: torch.Tensor, residual_with_cls_emb class MultiscaleAttention(nn.Module): def __init__( self, - input_size: List[int], + input_size: list[int], embed_dim: int, output_dim: int, num_heads: int, - kernel_q: List[int], - kernel_kv: List[int], - stride_q: List[int], - stride_kv: List[int], + kernel_q: list[int], + kernel_kv: list[int], + stride_q: list[int], + stride_kv: list[int], residual_pool: bool, residual_with_cls_embed: bool, rel_pos_embed: bool, @@ -219,7 +220,7 @@ def __init__( self.residual_with_cls_embed = residual_with_cls_embed self.qkv = nn.Linear(embed_dim, 3 * output_dim) - layers: List[nn.Module] = [nn.Linear(output_dim, output_dim)] + layers: list[nn.Module] = [nn.Linear(output_dim, output_dim)] if dropout > 0.0: layers.append(nn.Dropout(dropout, inplace=True)) self.project = nn.Sequential(*layers) @@ -285,7 +286,7 @@ def __init__( nn.init.trunc_normal_(self.rel_pos_w, std=0.02) nn.init.trunc_normal_(self.rel_pos_t, std=0.02) - def forward(self, x: torch.Tensor, thw: Tuple[int, int, int]) -> Tuple[torch.Tensor, Tuple[int, int, int]]: + def forward(self, x: torch.Tensor, thw: tuple[int, int, int]) -> tuple[torch.Tensor, tuple[int, int, int]]: B, N, C = x.shape q, k, v = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).transpose(1, 3).unbind(dim=2) @@ -323,7 +324,7 @@ def forward(self, x: torch.Tensor, thw: Tuple[int, int, int]) -> Tuple[torch.Ten class MultiscaleBlock(nn.Module): def __init__( self, - input_size: List[int], + input_size: list[int], cnf: MSBlockConfig, residual_pool: bool, residual_with_cls_embed: bool, @@ -379,7 +380,7 @@ def __init__( if cnf.input_channels != cnf.output_channels: self.project = nn.Linear(cnf.input_channels, cnf.output_channels) - def forward(self, x: torch.Tensor, thw: Tuple[int, int, int]) -> Tuple[torch.Tensor, Tuple[int, int, int]]: + def forward(self, x: torch.Tensor, thw: tuple[int, int, int]) -> tuple[torch.Tensor, tuple[int, int, int]]: x_norm1 = self.norm1(x.transpose(1, 2)).transpose(1, 2) if self.needs_transposal else self.norm1(x) x_attn, thw_new = self.attn(x_norm1, thw) x = x if self.project is None or not self.proj_after_attn else self.project(x_norm1) @@ -393,7 +394,7 @@ def forward(self, x: torch.Tensor, thw: Tuple[int, int, int]) -> Tuple[torch.Ten class PositionalEncoding(nn.Module): - def __init__(self, embed_size: int, spatial_size: Tuple[int, int], temporal_size: int, rel_pos_embed: bool) -> None: + def __init__(self, embed_size: int, spatial_size: tuple[int, int], temporal_size: int, rel_pos_embed: bool) -> None: super().__init__() self.spatial_size = spatial_size self.temporal_size = temporal_size @@ -424,7 +425,7 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: class MViT(nn.Module): def __init__( self, - spatial_size: Tuple[int, int], + spatial_size: tuple[int, int], temporal_size: int, block_setting: Sequence[MSBlockConfig], residual_pool: bool, @@ -437,9 +438,9 @@ def __init__( num_classes: int = 400, block: Optional[Callable[..., nn.Module]] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, - patch_embed_kernel: Tuple[int, int, int] = (3, 7, 7), - patch_embed_stride: Tuple[int, int, int] = (2, 4, 4), - patch_embed_padding: Tuple[int, int, int] = (1, 3, 3), + patch_embed_kernel: tuple[int, int, int] = (3, 7, 7), + patch_embed_stride: tuple[int, int, int] = (2, 4, 4), + patch_embed_padding: tuple[int, int, int] = (1, 3, 3), ) -> None: """ MViT main class. @@ -566,7 +567,7 @@ def forward(self, x: torch.Tensor) -> torch.Tensor: def _mvit( - block_setting: List[MSBlockConfig], + block_setting: list[MSBlockConfig], stochastic_depth_prob: float, weights: Optional[WeightsEnum], progress: bool, @@ -691,7 +692,7 @@ def mvit_v1_b(*, weights: Optional[MViT_V1_B_Weights] = None, progress: bool = T """ weights = MViT_V1_B_Weights.verify(weights) - config: Dict[str, List] = { + config: dict[str, list] = { "num_heads": [1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8], "input_channels": [96, 192, 192, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 768, 768], "output_channels": [192, 192, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 768, 768, 768], @@ -790,7 +791,7 @@ def mvit_v2_s(*, weights: Optional[MViT_V2_S_Weights] = None, progress: bool = T """ weights = MViT_V2_S_Weights.verify(weights) - config: Dict[str, List] = { + config: dict[str, list] = { "num_heads": [1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8], "input_channels": [96, 96, 192, 192, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 768], "output_channels": [96, 192, 192, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 768, 768], diff --git a/torchvision/models/video/resnet.py b/torchvision/models/video/resnet.py index a1cb2884013..43b0df48ffe 100644 --- a/torchvision/models/video/resnet.py +++ b/torchvision/models/video/resnet.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from functools import partial -from typing import Any, Callable, List, Optional, Sequence, Tuple, Type, Union +from typing import Any, Callable, Optional, Union import torch.nn as nn from torch import Tensor @@ -37,7 +38,7 @@ def __init__( ) @staticmethod - def get_downsample_stride(stride: int) -> Tuple[int, int, int]: + def get_downsample_stride(stride: int) -> tuple[int, int, int]: return stride, stride, stride @@ -60,7 +61,7 @@ def __init__(self, in_planes: int, out_planes: int, midplanes: int, stride: int ) @staticmethod - def get_downsample_stride(stride: int) -> Tuple[int, int, int]: + def get_downsample_stride(stride: int) -> tuple[int, int, int]: return stride, stride, stride @@ -79,7 +80,7 @@ def __init__( ) @staticmethod - def get_downsample_stride(stride: int) -> Tuple[int, int, int]: + def get_downsample_stride(stride: int) -> tuple[int, int, int]: return 1, stride, stride @@ -197,9 +198,9 @@ def __init__(self) -> None: class VideoResNet(nn.Module): def __init__( self, - block: Type[Union[BasicBlock, Bottleneck]], - conv_makers: Sequence[Type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]]], - layers: List[int], + block: type[Union[BasicBlock, Bottleneck]], + conv_makers: Sequence[type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]]], + layers: list[int], stem: Callable[..., nn.Module], num_classes: int = 400, zero_init_residual: bool = False, @@ -264,8 +265,8 @@ def forward(self, x: Tensor) -> Tensor: def _make_layer( self, - block: Type[Union[BasicBlock, Bottleneck]], - conv_builder: Type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]], + block: type[Union[BasicBlock, Bottleneck]], + conv_builder: type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]], planes: int, blocks: int, stride: int = 1, @@ -289,9 +290,9 @@ def _make_layer( def _video_resnet( - block: Type[Union[BasicBlock, Bottleneck]], - conv_makers: Sequence[Type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]]], - layers: List[int], + block: type[Union[BasicBlock, Bottleneck]], + conv_makers: Sequence[type[Union[Conv3DSimple, Conv3DNoTemporal, Conv2Plus1D]]], + layers: list[int], stem: Callable[..., nn.Module], weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/video/swin_transformer.py b/torchvision/models/video/swin_transformer.py index a8d87ffbe5a..1a198142874 100644 --- a/torchvision/models/video/swin_transformer.py +++ b/torchvision/models/video/swin_transformer.py @@ -2,7 +2,7 @@ # https://github.com/pytorch/vision/blob/main/torchvision/models/swin_transformer.py from functools import partial -from typing import Any, Callable, List, Optional, Tuple +from typing import Any, Callable, Optional import torch import torch.nn.functional as F @@ -30,8 +30,8 @@ def _get_window_and_shift_size( - shift_size: List[int], size_dhw: List[int], window_size: List[int] -) -> Tuple[List[int], List[int]]: + shift_size: list[int], size_dhw: list[int], window_size: list[int] +) -> tuple[list[int], list[int]]: for i in range(3): if size_dhw[i] <= window_size[i]: # In this case, window_size will adapt to the input size, and no need to shift @@ -45,7 +45,7 @@ def _get_window_and_shift_size( def _get_relative_position_bias( - relative_position_bias_table: torch.Tensor, relative_position_index: torch.Tensor, window_size: List[int] + relative_position_bias_table: torch.Tensor, relative_position_index: torch.Tensor, window_size: list[int] ) -> Tensor: window_vol = window_size[0] * window_size[1] * window_size[2] # In 3d case we flatten the relative_position_bias @@ -60,7 +60,7 @@ def _get_relative_position_bias( torch.fx.wrap("_get_relative_position_bias") -def _compute_pad_size_3d(size_dhw: Tuple[int, int, int], patch_size: Tuple[int, int, int]) -> Tuple[int, int, int]: +def _compute_pad_size_3d(size_dhw: tuple[int, int, int], patch_size: tuple[int, int, int]) -> tuple[int, int, int]: pad_size = [(patch_size[i] - size_dhw[i] % patch_size[i]) % patch_size[i] for i in range(3)] return pad_size[0], pad_size[1], pad_size[2] @@ -70,9 +70,9 @@ def _compute_pad_size_3d(size_dhw: Tuple[int, int, int], patch_size: Tuple[int, def _compute_attention_mask_3d( x: Tensor, - size_dhw: Tuple[int, int, int], - window_size: Tuple[int, int, int], - shift_size: Tuple[int, int, int], + size_dhw: tuple[int, int, int], + window_size: tuple[int, int, int], + shift_size: tuple[int, int, int], ) -> Tensor: # generate attention mask attn_mask = x.new_zeros(*size_dhw) @@ -117,9 +117,9 @@ def shifted_window_attention_3d( qkv_weight: Tensor, proj_weight: Tensor, relative_position_bias: Tensor, - window_size: List[int], + window_size: list[int], num_heads: int, - shift_size: List[int], + shift_size: list[int], attention_dropout: float = 0.0, dropout: float = 0.0, qkv_bias: Optional[Tensor] = None, @@ -235,8 +235,8 @@ class ShiftedWindowAttention3d(nn.Module): def __init__( self, dim: int, - window_size: List[int], - shift_size: List[int], + window_size: list[int], + shift_size: list[int], num_heads: int, qkv_bias: bool = True, proj_bias: bool = True, @@ -288,7 +288,7 @@ def define_relative_position_index(self) -> None: relative_position_index = relative_coords.sum(-1) # Wd*Wh*Ww, Wd*Wh*Ww self.register_buffer("relative_position_index", relative_position_index) - def get_relative_position_bias(self, window_size: List[int]) -> torch.Tensor: + def get_relative_position_bias(self, window_size: list[int]) -> torch.Tensor: return _get_relative_position_bias(self.relative_position_bias_table, self.relative_position_index, window_size) # type: ignore def forward(self, x: Tensor) -> Tensor: @@ -330,7 +330,7 @@ class PatchEmbed3d(nn.Module): def __init__( self, - patch_size: List[int], + patch_size: list[int], in_channels: int = 3, embed_dim: int = 96, norm_layer: Optional[Callable[..., nn.Module]] = None, @@ -385,11 +385,11 @@ class SwinTransformer3d(nn.Module): def __init__( self, - patch_size: List[int], + patch_size: list[int], embed_dim: int, - depths: List[int], - num_heads: List[int], - window_size: List[int], + depths: list[int], + num_heads: list[int], + window_size: list[int], mlp_ratio: float = 4.0, dropout: float = 0.0, attention_dropout: float = 0.0, @@ -417,12 +417,12 @@ def __init__( self.patch_embed = patch_embed(patch_size=patch_size, embed_dim=embed_dim, norm_layer=norm_layer) self.pos_drop = nn.Dropout(p=dropout) - layers: List[nn.Module] = [] + layers: list[nn.Module] = [] total_stage_blocks = sum(depths) stage_block_id = 0 # build SwinTransformer blocks for i_stage in range(len(depths)): - stage: List[nn.Module] = [] + stage: list[nn.Module] = [] dim = embed_dim * 2**i_stage for i_layer in range(depths[i_stage]): # adjust stochastic depth probability based on the depth of the stage block @@ -473,11 +473,11 @@ def forward(self, x: Tensor) -> Tensor: def _swin_transformer3d( - patch_size: List[int], + patch_size: list[int], embed_dim: int, - depths: List[int], - num_heads: List[int], - window_size: List[int], + depths: list[int], + num_heads: list[int], + window_size: list[int], stochastic_depth_prob: float, weights: Optional[WeightsEnum], progress: bool, diff --git a/torchvision/models/vision_transformer.py b/torchvision/models/vision_transformer.py index f2983ef9db0..4ec3a5c59f0 100644 --- a/torchvision/models/vision_transformer.py +++ b/torchvision/models/vision_transformer.py @@ -1,7 +1,7 @@ import math from collections import OrderedDict from functools import partial -from typing import Any, Callable, Dict, List, NamedTuple, Optional +from typing import Any, Callable, NamedTuple, Optional import torch import torch.nn as nn @@ -173,7 +173,7 @@ def __init__( num_classes: int = 1000, representation_size: Optional[int] = None, norm_layer: Callable[..., torch.nn.Module] = partial(nn.LayerNorm, eps=1e-6), - conv_stem_configs: Optional[List[ConvStemConfig]] = None, + conv_stem_configs: Optional[list[ConvStemConfig]] = None, ): super().__init__() _log_api_usage_once(self) @@ -337,7 +337,7 @@ def _vision_transformer( return model -_COMMON_META: Dict[str, Any] = { +_COMMON_META: dict[str, Any] = { "categories": _IMAGENET_CATEGORIES, } diff --git a/torchvision/ops/_utils.py b/torchvision/ops/_utils.py index a6ca557a98b..40bae605d02 100644 --- a/torchvision/ops/_utils.py +++ b/torchvision/ops/_utils.py @@ -1,10 +1,10 @@ -from typing import List, Optional, Tuple, Union +from typing import Optional, Union import torch from torch import nn, Tensor -def _cat(tensors: List[Tensor], dim: int = 0) -> Tensor: +def _cat(tensors: list[Tensor], dim: int = 0) -> Tensor: """ Efficient version of torch.cat that avoids a copy if there is only a single element in a list """ @@ -15,7 +15,7 @@ def _cat(tensors: List[Tensor], dim: int = 0) -> Tensor: return torch.cat(tensors, dim) -def convert_boxes_to_roi_format(boxes: List[Tensor]) -> Tensor: +def convert_boxes_to_roi_format(boxes: list[Tensor]) -> Tensor: concat_boxes = _cat([b for b in boxes], dim=0) temp = [] for i, b in enumerate(boxes): @@ -25,7 +25,7 @@ def convert_boxes_to_roi_format(boxes: List[Tensor]) -> Tensor: return rois -def check_roi_boxes_shape(boxes: Union[Tensor, List[Tensor]]): +def check_roi_boxes_shape(boxes: Union[Tensor, list[Tensor]]): if isinstance(boxes, (list, tuple)): for _tensor in boxes: torch._assert( @@ -39,8 +39,8 @@ def check_roi_boxes_shape(boxes: Union[Tensor, List[Tensor]]): def split_normalization_params( - model: nn.Module, norm_classes: Optional[List[type]] = None -) -> Tuple[List[Tensor], List[Tensor]]: + model: nn.Module, norm_classes: Optional[list[type]] = None +) -> tuple[list[Tensor], list[Tensor]]: # Adapted from https://github.com/facebookresearch/ClassyVision/blob/659d7f78/classy_vision/generic/util.py#L501 if not norm_classes: norm_classes = [ @@ -87,7 +87,7 @@ def _upcast_non_float(t: Tensor) -> Tensor: def _loss_inter_union( boxes1: torch.Tensor, boxes2: torch.Tensor, -) -> Tuple[torch.Tensor, torch.Tensor]: +) -> tuple[torch.Tensor, torch.Tensor]: x1, y1, x2, y2 = boxes1.unbind(dim=-1) x1g, y1g, x2g, y2g = boxes2.unbind(dim=-1) diff --git a/torchvision/ops/boxes.py b/torchvision/ops/boxes.py index 48df4d85cc7..be8d59716bf 100644 --- a/torchvision/ops/boxes.py +++ b/torchvision/ops/boxes.py @@ -1,5 +1,3 @@ -from typing import Tuple - import torch import torchvision from torch import Tensor @@ -148,7 +146,7 @@ def remove_small_boxes(boxes: Tensor, min_size: float) -> Tensor: return keep -def clip_boxes_to_image(boxes: Tensor, size: Tuple[int, int]) -> Tensor: +def clip_boxes_to_image(boxes: Tensor, size: tuple[int, int]) -> Tensor: """ Clip boxes so that they lie inside an image of size ``size``. @@ -293,7 +291,7 @@ def box_area(boxes: Tensor) -> Tensor: # implementation from https://github.com/kuangliu/torchcv/blob/master/torchcv/utils/box.py # with slight modifications -def _box_inter_union(boxes1: Tensor, boxes2: Tensor) -> Tuple[Tensor, Tensor]: +def _box_inter_union(boxes1: Tensor, boxes2: Tensor) -> tuple[Tensor, Tensor]: area1 = box_area(boxes1) area2 = box_area(boxes2) @@ -418,7 +416,7 @@ def distance_box_iou(boxes1: Tensor, boxes2: Tensor, eps: float = 1e-7) -> Tenso return diou -def _box_diou_iou(boxes1: Tensor, boxes2: Tensor, eps: float = 1e-7) -> Tuple[Tensor, Tensor]: +def _box_diou_iou(boxes1: Tensor, boxes2: Tensor, eps: float = 1e-7) -> tuple[Tensor, Tensor]: iou = box_iou(boxes1, boxes2) lti = torch.min(boxes1[:, None, :2], boxes2[:, :2]) @@ -431,9 +429,7 @@ def _box_diou_iou(boxes1: Tensor, boxes2: Tensor, eps: float = 1e-7) -> Tuple[Te x_g = (boxes2[:, 0] + boxes2[:, 2]) / 2 y_g = (boxes2[:, 1] + boxes2[:, 3]) / 2 # The distance between boxes' centers squared. - centers_distance_squared = (_upcast((x_p[:, None] - x_g[None, :])) ** 2) + ( - _upcast((y_p[:, None] - y_g[None, :])) ** 2 - ) + centers_distance_squared = (_upcast(x_p[:, None] - x_g[None, :]) ** 2) + (_upcast(y_p[:, None] - y_g[None, :]) ** 2) # The distance IoU is the IoU penalized by a normalized # distance between boxes' centers squared. return iou - (centers_distance_squared / diagonal_distance_squared), iou diff --git a/torchvision/ops/ciou_loss.py b/torchvision/ops/ciou_loss.py index 75a1c4cb1f3..d825e79dff0 100644 --- a/torchvision/ops/ciou_loss.py +++ b/torchvision/ops/ciou_loss.py @@ -11,7 +11,6 @@ def complete_box_iou_loss( reduction: str = "none", eps: float = 1e-7, ) -> torch.Tensor: - """ Gradient-friendly IoU loss with an additional penalty that is non-zero when the boxes do not overlap. This loss function considers important geometrical diff --git a/torchvision/ops/deform_conv.py b/torchvision/ops/deform_conv.py index b3cc83332a0..da13ee6da9a 100644 --- a/torchvision/ops/deform_conv.py +++ b/torchvision/ops/deform_conv.py @@ -1,5 +1,5 @@ import math -from typing import Optional, Tuple +from typing import Optional import torch from torch import nn, Tensor @@ -16,9 +16,9 @@ def deform_conv2d( offset: Tensor, weight: Tensor, bias: Optional[Tensor] = None, - stride: Tuple[int, int] = (1, 1), - padding: Tuple[int, int] = (0, 0), - dilation: Tuple[int, int] = (1, 1), + stride: tuple[int, int] = (1, 1), + padding: tuple[int, int] = (0, 0), + dilation: tuple[int, int] = (1, 1), mask: Optional[Tensor] = None, ) -> Tensor: r""" diff --git a/torchvision/ops/diou_loss.py b/torchvision/ops/diou_loss.py index c64c6673a88..9381878ce1d 100644 --- a/torchvision/ops/diou_loss.py +++ b/torchvision/ops/diou_loss.py @@ -1,5 +1,3 @@ -from typing import Tuple - import torch from ..utils import _log_api_usage_once @@ -12,7 +10,6 @@ def distance_box_iou_loss( reduction: str = "none", eps: float = 1e-7, ) -> torch.Tensor: - """ Gradient-friendly IoU loss with an additional penalty that is non-zero when the distance between boxes' centers isn't zero. Indeed, for two exactly overlapping @@ -68,7 +65,7 @@ def _diou_iou_loss( boxes1: torch.Tensor, boxes2: torch.Tensor, eps: float = 1e-7, -) -> Tuple[torch.Tensor, torch.Tensor]: +) -> tuple[torch.Tensor, torch.Tensor]: intsct, union = _loss_inter_union(boxes1, boxes2) iou = intsct / (union + eps) diff --git a/torchvision/ops/feature_pyramid_network.py b/torchvision/ops/feature_pyramid_network.py index 2e7aef0e2fa..5c85e19a699 100644 --- a/torchvision/ops/feature_pyramid_network.py +++ b/torchvision/ops/feature_pyramid_network.py @@ -1,5 +1,5 @@ from collections import OrderedDict -from typing import Callable, Dict, List, Optional, Tuple +from typing import Callable, Optional import torch.nn.functional as F from torch import nn, Tensor @@ -26,10 +26,10 @@ class ExtraFPNBlock(nn.Module): def forward( self, - results: List[Tensor], - x: List[Tensor], - names: List[str], - ) -> Tuple[List[Tensor], List[str]]: + results: list[Tensor], + x: list[Tensor], + names: list[str], + ) -> tuple[list[Tensor], list[str]]: pass @@ -76,7 +76,7 @@ class FeaturePyramidNetwork(nn.Module): def __init__( self, - in_channels_list: List[int], + in_channels_list: list[int], out_channels: int, extra_blocks: Optional[ExtraFPNBlock] = None, norm_layer: Optional[Callable[..., nn.Module]] = None, @@ -169,7 +169,7 @@ def get_result_from_layer_blocks(self, x: Tensor, idx: int) -> Tensor: out = module(x) return out - def forward(self, x: Dict[str, Tensor]) -> Dict[str, Tensor]: + def forward(self, x: dict[str, Tensor]) -> dict[str, Tensor]: """ Computes the FPN for a set of feature maps. @@ -211,10 +211,10 @@ class LastLevelMaxPool(ExtraFPNBlock): def forward( self, - x: List[Tensor], - y: List[Tensor], - names: List[str], - ) -> Tuple[List[Tensor], List[str]]: + x: list[Tensor], + y: list[Tensor], + names: list[str], + ) -> tuple[list[Tensor], list[str]]: names.append("pool") # Use max pooling to simulate stride 2 subsampling x.append(F.max_pool2d(x[-1], kernel_size=1, stride=2, padding=0)) @@ -237,10 +237,10 @@ def __init__(self, in_channels: int, out_channels: int): def forward( self, - p: List[Tensor], - c: List[Tensor], - names: List[str], - ) -> Tuple[List[Tensor], List[str]]: + p: list[Tensor], + c: list[Tensor], + names: list[str], + ) -> tuple[list[Tensor], list[str]]: p5, c5 = p[-1], c[-1] x = p5 if self.use_P5 else c5 p6 = self.p6(x) diff --git a/torchvision/ops/giou_loss.py b/torchvision/ops/giou_loss.py index ec8bc8852fe..e56dcc16c7d 100644 --- a/torchvision/ops/giou_loss.py +++ b/torchvision/ops/giou_loss.py @@ -10,7 +10,6 @@ def generalized_box_iou_loss( reduction: str = "none", eps: float = 1e-7, ) -> torch.Tensor: - """ Gradient-friendly IoU loss with an additional penalty that is non-zero when the boxes do not overlap and scales with the size of their smallest enclosing box. diff --git a/torchvision/ops/misc.py b/torchvision/ops/misc.py index 0bbea6bce43..cfa1e23a5ee 100644 --- a/torchvision/ops/misc.py +++ b/torchvision/ops/misc.py @@ -1,5 +1,6 @@ import warnings -from typing import Callable, List, Optional, Sequence, Tuple, Union +from collections.abc import Sequence +from typing import Callable, Optional, Union import torch from torch import Tensor @@ -38,9 +39,9 @@ def _load_from_state_dict( prefix: str, local_metadata: dict, strict: bool, - missing_keys: List[str], - unexpected_keys: List[str], - error_msgs: List[str], + missing_keys: list[str], + unexpected_keys: list[str], + error_msgs: list[str], ): num_batches_tracked_key = prefix + "num_batches_tracked" if num_batches_tracked_key in state_dict: @@ -70,13 +71,13 @@ def __init__( self, in_channels: int, out_channels: int, - kernel_size: Union[int, Tuple[int, ...]] = 3, - stride: Union[int, Tuple[int, ...]] = 1, - padding: Optional[Union[int, Tuple[int, ...], str]] = None, + kernel_size: Union[int, tuple[int, ...]] = 3, + stride: Union[int, tuple[int, ...]] = 1, + padding: Optional[Union[int, tuple[int, ...], str]] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm2d, activation_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.ReLU, - dilation: Union[int, Tuple[int, ...]] = 1, + dilation: Union[int, tuple[int, ...]] = 1, inplace: Optional[bool] = True, bias: Optional[bool] = None, conv_layer: Callable[..., torch.nn.Module] = torch.nn.Conv2d, @@ -145,13 +146,13 @@ def __init__( self, in_channels: int, out_channels: int, - kernel_size: Union[int, Tuple[int, int]] = 3, - stride: Union[int, Tuple[int, int]] = 1, - padding: Optional[Union[int, Tuple[int, int], str]] = None, + kernel_size: Union[int, tuple[int, int]] = 3, + stride: Union[int, tuple[int, int]] = 1, + padding: Optional[Union[int, tuple[int, int], str]] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm2d, activation_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.ReLU, - dilation: Union[int, Tuple[int, int]] = 1, + dilation: Union[int, tuple[int, int]] = 1, inplace: Optional[bool] = True, bias: Optional[bool] = None, ) -> None: @@ -194,13 +195,13 @@ def __init__( self, in_channels: int, out_channels: int, - kernel_size: Union[int, Tuple[int, int, int]] = 3, - stride: Union[int, Tuple[int, int, int]] = 1, - padding: Optional[Union[int, Tuple[int, int, int], str]] = None, + kernel_size: Union[int, tuple[int, int, int]] = 3, + stride: Union[int, tuple[int, int, int]] = 1, + padding: Optional[Union[int, tuple[int, int, int], str]] = None, groups: int = 1, norm_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.BatchNorm3d, activation_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.ReLU, - dilation: Union[int, Tuple[int, int, int]] = 1, + dilation: Union[int, tuple[int, int, int]] = 1, inplace: Optional[bool] = True, bias: Optional[bool] = None, ) -> None: @@ -277,7 +278,7 @@ class MLP(torch.nn.Sequential): def __init__( self, in_channels: int, - hidden_channels: List[int], + hidden_channels: list[int], norm_layer: Optional[Callable[..., torch.nn.Module]] = None, activation_layer: Optional[Callable[..., torch.nn.Module]] = torch.nn.ReLU, inplace: Optional[bool] = None, @@ -312,7 +313,7 @@ class Permute(torch.nn.Module): dims (List[int]): The desired ordering of dimensions """ - def __init__(self, dims: List[int]): + def __init__(self, dims: list[int]): super().__init__() self.dims = dims diff --git a/torchvision/ops/poolers.py b/torchvision/ops/poolers.py index 9cdd83a598b..f887f6aee33 100644 --- a/torchvision/ops/poolers.py +++ b/torchvision/ops/poolers.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Tuple, Union +from typing import Optional, Union import torch import torch.fx @@ -15,7 +15,7 @@ # _onnx_merge_levels() is an implementation supported by ONNX # that merges the levels to the right indices @torch.jit.unused -def _onnx_merge_levels(levels: Tensor, unmerged_results: List[Tensor]) -> Tensor: +def _onnx_merge_levels(levels: Tensor, unmerged_results: list[Tensor]) -> Tensor: first_result = unmerged_results[0] dtype, device = first_result.dtype, first_result.device res = torch.zeros( @@ -70,7 +70,7 @@ def __init__( self.lvl0 = canonical_level self.eps = eps - def __call__(self, boxlists: List[Tensor]) -> Tensor: + def __call__(self, boxlists: list[Tensor]) -> Tensor: """ Args: boxlists (list[BoxList]) @@ -84,7 +84,7 @@ def __call__(self, boxlists: List[Tensor]) -> Tensor: return (target_lvls.to(torch.int64) - self.k_min).to(torch.int64) -def _convert_to_roi_format(boxes: List[Tensor]) -> Tensor: +def _convert_to_roi_format(boxes: list[Tensor]) -> Tensor: concat_boxes = torch.cat(boxes, dim=0) device, dtype = concat_boxes.device, concat_boxes.dtype ids = torch.cat( @@ -95,10 +95,10 @@ def _convert_to_roi_format(boxes: List[Tensor]) -> Tensor: return rois -def _infer_scale(feature: Tensor, original_size: List[int]) -> float: +def _infer_scale(feature: Tensor, original_size: list[int]) -> float: # assumption: the scale is of the form 2 ** (-k), with k integer size = feature.shape[-2:] - possible_scales: List[float] = [] + possible_scales: list[float] = [] for s1, s2 in zip(size, original_size): approx_scale = float(s1) / float(s2) scale = 2 ** float(torch.tensor(approx_scale).log2().round()) @@ -108,8 +108,8 @@ def _infer_scale(feature: Tensor, original_size: List[int]) -> float: @torch.fx.wrap def _setup_scales( - features: List[Tensor], image_shapes: List[Tuple[int, int]], canonical_scale: int, canonical_level: int -) -> Tuple[List[float], LevelMapper]: + features: list[Tensor], image_shapes: list[tuple[int, int]], canonical_scale: int, canonical_level: int +) -> tuple[list[float], LevelMapper]: if not image_shapes: raise ValueError("images list should not be empty") max_x = 0 @@ -135,7 +135,7 @@ def _setup_scales( @torch.fx.wrap -def _filter_input(x: Dict[str, Tensor], featmap_names: List[str]) -> List[Tensor]: +def _filter_input(x: dict[str, Tensor], featmap_names: list[str]) -> list[Tensor]: x_filtered = [] for k, v in x.items(): if k in featmap_names: @@ -145,11 +145,11 @@ def _filter_input(x: Dict[str, Tensor], featmap_names: List[str]) -> List[Tensor @torch.fx.wrap def _multiscale_roi_align( - x_filtered: List[Tensor], - boxes: List[Tensor], - output_size: List[int], + x_filtered: list[Tensor], + boxes: list[Tensor], + output_size: list[int], sampling_ratio: int, - scales: Optional[List[float]], + scales: Optional[list[float]], mapper: Optional[LevelMapper], ) -> Tensor: """ @@ -263,12 +263,12 @@ class MultiScaleRoIAlign(nn.Module): """ - __annotations__ = {"scales": Optional[List[float]], "map_levels": Optional[LevelMapper]} + __annotations__ = {"scales": Optional[list[float]], "map_levels": Optional[LevelMapper]} def __init__( self, - featmap_names: List[str], - output_size: Union[int, Tuple[int], List[int]], + featmap_names: list[str], + output_size: Union[int, tuple[int], list[int]], sampling_ratio: int, *, canonical_scale: int = 224, @@ -288,9 +288,9 @@ def __init__( def forward( self, - x: Dict[str, Tensor], - boxes: List[Tensor], - image_shapes: List[Tuple[int, int]], + x: dict[str, Tensor], + boxes: list[Tensor], + image_shapes: list[tuple[int, int]], ) -> Tensor: """ Args: diff --git a/torchvision/ops/roi_align.py b/torchvision/ops/roi_align.py index ddbaf4b6cbe..25214d6b130 100644 --- a/torchvision/ops/roi_align.py +++ b/torchvision/ops/roi_align.py @@ -1,5 +1,5 @@ import functools -from typing import List, Union +from typing import Union import torch import torch.fx @@ -203,7 +203,7 @@ def from_K(t): @torch.fx.wrap def roi_align( input: Tensor, - boxes: Union[Tensor, List[Tensor]], + boxes: Union[Tensor, list[Tensor]], output_size: BroadcastingList2[int], spatial_scale: float = 1.0, sampling_ratio: int = -1, @@ -279,7 +279,7 @@ def __init__( self.sampling_ratio = sampling_ratio self.aligned = aligned - def forward(self, input: Tensor, rois: Union[Tensor, List[Tensor]]) -> Tensor: + def forward(self, input: Tensor, rois: Union[Tensor, list[Tensor]]) -> Tensor: return roi_align(input, rois, self.output_size, self.spatial_scale, self.sampling_ratio, self.aligned) def __repr__(self) -> str: diff --git a/torchvision/ops/roi_pool.py b/torchvision/ops/roi_pool.py index 96282418f07..5f4bb95c0f3 100644 --- a/torchvision/ops/roi_pool.py +++ b/torchvision/ops/roi_pool.py @@ -1,4 +1,4 @@ -from typing import List, Union +from typing import Union import torch import torch.fx @@ -14,7 +14,7 @@ @torch.fx.wrap def roi_pool( input: Tensor, - boxes: Union[Tensor, List[Tensor]], + boxes: Union[Tensor, list[Tensor]], output_size: BroadcastingList2[int], spatial_scale: float = 1.0, ) -> Tensor: @@ -64,7 +64,7 @@ def __init__(self, output_size: BroadcastingList2[int], spatial_scale: float): self.output_size = output_size self.spatial_scale = spatial_scale - def forward(self, input: Tensor, rois: Union[Tensor, List[Tensor]]) -> Tensor: + def forward(self, input: Tensor, rois: Union[Tensor, list[Tensor]]) -> Tensor: return roi_pool(input, rois, self.output_size, self.spatial_scale) def __repr__(self) -> str: diff --git a/torchvision/prototype/datasets/_api.py b/torchvision/prototype/datasets/_api.py index f6f06c60a21..ab126e4a49e 100644 --- a/torchvision/prototype/datasets/_api.py +++ b/torchvision/prototype/datasets/_api.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Callable, Dict, List, Optional, Type, TypeVar, Union +from typing import Any, Callable, Optional, TypeVar, Union from torchvision.prototype.datasets import home from torchvision.prototype.datasets.utils import Dataset @@ -7,13 +7,13 @@ T = TypeVar("T") -D = TypeVar("D", bound=Type[Dataset]) +D = TypeVar("D", bound=type[Dataset]) -BUILTIN_INFOS: Dict[str, Dict[str, Any]] = {} +BUILTIN_INFOS: dict[str, dict[str, Any]] = {} -def register_info(name: str) -> Callable[[Callable[[], Dict[str, Any]]], Callable[[], Dict[str, Any]]]: - def wrapper(fn: Callable[[], Dict[str, Any]]) -> Callable[[], Dict[str, Any]]: +def register_info(name: str) -> Callable[[Callable[[], dict[str, Any]]], Callable[[], dict[str, Any]]]: + def wrapper(fn: Callable[[], dict[str, Any]]) -> Callable[[], dict[str, Any]]: BUILTIN_INFOS[name] = fn() return fn @@ -31,11 +31,11 @@ def wrapper(dataset_cls: D) -> D: return wrapper -def list_datasets() -> List[str]: +def list_datasets() -> list[str]: return sorted(BUILTIN_DATASETS.keys()) -def find(dct: Dict[str, T], name: str) -> T: +def find(dct: dict[str, T], name: str) -> T: name = name.lower() try: return dct[name] @@ -52,7 +52,7 @@ def find(dct: Dict[str, T], name: str) -> T: ) from error -def info(name: str) -> Dict[str, Any]: +def info(name: str) -> dict[str, Any]: return find(BUILTIN_INFOS, name) diff --git a/torchvision/prototype/datasets/_builtin/caltech.py b/torchvision/prototype/datasets/_builtin/caltech.py index 5072902b212..e4d8b8579d0 100644 --- a/torchvision/prototype/datasets/_builtin/caltech.py +++ b/torchvision/prototype/datasets/_builtin/caltech.py @@ -1,6 +1,6 @@ import pathlib import re -from typing import Any, BinaryIO, Dict, List, Tuple, Union +from typing import Any, BinaryIO, Union import numpy as np @@ -21,7 +21,7 @@ @register_info("caltech101") -def _caltech101_info() -> Dict[str, Any]: +def _caltech101_info() -> dict[str, Any]: return dict(categories=read_categories_file("caltech101")) @@ -46,7 +46,7 @@ def __init__( skip_integrity_check=skip_integrity_check, ) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: images = GDriveResource( "137RyRjvTBkBiIfeYBNZBtViDHQ6_Ewsp", file_name="101_ObjectCategories.tar.gz", @@ -69,15 +69,15 @@ def _resources(self) -> List[OnlineResource]: "Airplanes_Side_2": "airplanes", } - def _is_not_background_image(self, data: Tuple[str, Any]) -> bool: + def _is_not_background_image(self, data: tuple[str, Any]) -> bool: path = pathlib.Path(data[0]) return path.parent.name != "BACKGROUND_Google" - def _is_ann(self, data: Tuple[str, Any]) -> bool: + def _is_ann(self, data: tuple[str, Any]) -> bool: path = pathlib.Path(data[0]) return bool(self._ANNS_NAME_PATTERN.match(path.name)) - def _images_key_fn(self, data: Tuple[str, Any]) -> Tuple[str, str]: + def _images_key_fn(self, data: tuple[str, Any]) -> tuple[str, str]: path = pathlib.Path(data[0]) category = path.parent.name @@ -85,7 +85,7 @@ def _images_key_fn(self, data: Tuple[str, Any]) -> Tuple[str, str]: return category, id - def _anns_key_fn(self, data: Tuple[str, Any]) -> Tuple[str, str]: + def _anns_key_fn(self, data: tuple[str, Any]) -> tuple[str, str]: path = pathlib.Path(data[0]) category = path.parent.name @@ -97,8 +97,8 @@ def _anns_key_fn(self, data: Tuple[str, Any]) -> Tuple[str, str]: return category, id def _prepare_sample( - self, data: Tuple[Tuple[str, str], Tuple[Tuple[str, BinaryIO], Tuple[str, BinaryIO]]] - ) -> Dict[str, Any]: + self, data: tuple[tuple[str, str], tuple[tuple[str, BinaryIO], tuple[str, BinaryIO]]] + ) -> dict[str, Any]: key, (image_data, ann_data) = data category, _ = key image_path, image_buffer = image_data @@ -120,7 +120,7 @@ def _prepare_sample( contour=torch.as_tensor(ann["obj_contour"].T), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: images_dp, anns_dp = resource_dps images_dp = Filter(images_dp, self._is_not_background_image) @@ -142,7 +142,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, def __len__(self) -> int: return 8677 - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) @@ -152,7 +152,7 @@ def _generate_categories(self) -> List[str]: @register_info("caltech256") -def _caltech256_info() -> Dict[str, Any]: +def _caltech256_info() -> dict[str, Any]: return dict(categories=read_categories_file("caltech256")) @@ -171,7 +171,7 @@ def __init__( super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ GDriveResource( "1r6o0pSROcV1_VwT4oSjA2FBUSCWGuxLK", @@ -180,11 +180,11 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _is_not_rogue_file(self, data: Tuple[str, Any]) -> bool: + def _is_not_rogue_file(self, data: tuple[str, Any]) -> bool: path = pathlib.Path(data[0]) return path.name != "RENAME2" - def _prepare_sample(self, data: Tuple[str, BinaryIO]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[str, BinaryIO]) -> dict[str, Any]: path, buffer = data return dict( @@ -193,7 +193,7 @@ def _prepare_sample(self, data: Tuple[str, BinaryIO]) -> Dict[str, Any]: label=Label(int(pathlib.Path(path).parent.name.split(".", 1)[0]) - 1, categories=self._categories), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: dp = resource_dps[0] dp = Filter(dp, self._is_not_rogue_file) dp = hint_shuffling(dp) @@ -203,7 +203,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, def __len__(self) -> int: return 30607 - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) diff --git a/torchvision/prototype/datasets/_builtin/celeba.py b/torchvision/prototype/datasets/_builtin/celeba.py index 5ec3ee3ebef..4fcb38bf8d7 100644 --- a/torchvision/prototype/datasets/_builtin/celeba.py +++ b/torchvision/prototype/datasets/_builtin/celeba.py @@ -1,6 +1,7 @@ import csv import pathlib -from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Sequence, Tuple, Union +from collections.abc import Iterator, Sequence +from typing import Any, BinaryIO, Optional, Union import torch from torchdata.datapipes.iter import Filter, IterDataPipe, IterKeyZipper, Mapper, Zipper @@ -20,17 +21,17 @@ csv.register_dialect("celeba", delimiter=" ", skipinitialspace=True) -class CelebACSVParser(IterDataPipe[Tuple[str, Dict[str, str]]]): +class CelebACSVParser(IterDataPipe[tuple[str, dict[str, str]]]): def __init__( self, - datapipe: IterDataPipe[Tuple[Any, BinaryIO]], + datapipe: IterDataPipe[tuple[Any, BinaryIO]], *, fieldnames: Optional[Sequence[str]] = None, ) -> None: self.datapipe = datapipe self.fieldnames = fieldnames - def __iter__(self) -> Iterator[Tuple[str, Dict[str, str]]]: + def __iter__(self) -> Iterator[tuple[str, dict[str, str]]]: for _, file in self.datapipe: try: lines = (line.decode() for line in file) @@ -58,7 +59,7 @@ def __iter__(self) -> Iterator[Tuple[str, Dict[str, str]]]: @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict() @@ -79,7 +80,7 @@ def __init__( super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: splits = GDriveResource( "0B7EVK8r0v71pY0NSMzRuSXJEVkk", sha256="fc955bcb3ef8fbdf7d5640d9a8693a8431b5f2ee291a5c1449a1549e7e073fe7", @@ -112,7 +113,7 @@ def _resources(self) -> List[OnlineResource]: ) return [splits, images, identities, attributes, bounding_boxes, landmarks] - def _filter_split(self, data: Tuple[str, Dict[str, str]]) -> bool: + def _filter_split(self, data: tuple[str, dict[str, str]]) -> bool: split_id = { "train": "0", "val": "1", @@ -122,16 +123,16 @@ def _filter_split(self, data: Tuple[str, Dict[str, str]]) -> bool: def _prepare_sample( self, - data: Tuple[ - Tuple[str, Tuple[Tuple[str, List[str]], Tuple[str, BinaryIO]]], - Tuple[ - Tuple[str, Dict[str, str]], - Tuple[str, Dict[str, str]], - Tuple[str, Dict[str, str]], - Tuple[str, Dict[str, str]], + data: tuple[ + tuple[str, tuple[tuple[str, list[str]], tuple[str, BinaryIO]]], + tuple[ + tuple[str, dict[str, str]], + tuple[str, dict[str, str]], + tuple[str, dict[str, str]], + tuple[str, dict[str, str]], ], ], - ) -> Dict[str, Any]: + ) -> dict[str, Any]: split_and_image_data, ann_data = data _, (_, image_data) = split_and_image_data path, buffer = image_data @@ -155,7 +156,7 @@ def _prepare_sample( }, ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: splits_dp, images_dp, identities_dp, attributes_dp, bounding_boxes_dp, landmarks_dp = resource_dps splits_dp = CelebACSVParser(splits_dp, fieldnames=("image_id", "split_id")) diff --git a/torchvision/prototype/datasets/_builtin/cifar.py b/torchvision/prototype/datasets/_builtin/cifar.py index 0668ec9fc42..ef90d4d53ba 100644 --- a/torchvision/prototype/datasets/_builtin/cifar.py +++ b/torchvision/prototype/datasets/_builtin/cifar.py @@ -2,7 +2,8 @@ import io import pathlib import pickle -from typing import Any, BinaryIO, cast, Dict, Iterator, List, Optional, Tuple, Union +from collections.abc import Iterator +from typing import Any, BinaryIO, cast, Optional, Union import numpy as np from torchdata.datapipes.iter import Filter, IterDataPipe, Mapper @@ -19,12 +20,12 @@ from .._api import register_dataset, register_info -class CifarFileReader(IterDataPipe[Tuple[np.ndarray, int]]): - def __init__(self, datapipe: IterDataPipe[Dict[str, Any]], *, labels_key: str) -> None: +class CifarFileReader(IterDataPipe[tuple[np.ndarray, int]]): + def __init__(self, datapipe: IterDataPipe[dict[str, Any]], *, labels_key: str) -> None: self.datapipe = datapipe self.labels_key = labels_key - def __iter__(self) -> Iterator[Tuple[np.ndarray, int]]: + def __iter__(self) -> Iterator[tuple[np.ndarray, int]]: for mapping in self.datapipe: image_arrays = mapping["data"].reshape((-1, 3, 32, 32)) category_idcs = mapping[self.labels_key] @@ -37,7 +38,7 @@ class _CifarBase(Dataset): _LABELS_KEY: str _META_FILE_NAME: str _CATEGORIES_KEY: str - _categories: List[str] + _categories: list[str] def __init__( self, @@ -50,10 +51,10 @@ def __init__( super().__init__(root, skip_integrity_check=skip_integrity_check) @abc.abstractmethod - def _is_data_file(self, data: Tuple[str, BinaryIO]) -> Optional[int]: + def _is_data_file(self, data: tuple[str, BinaryIO]) -> Optional[int]: pass - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ HttpResource( f"https://www.cs.toronto.edu/~kriz/{self._FILE_NAME}", @@ -61,20 +62,20 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _unpickle(self, data: Tuple[str, io.BytesIO]) -> Dict[str, Any]: + def _unpickle(self, data: tuple[str, io.BytesIO]) -> dict[str, Any]: _, file = data - content = cast(Dict[str, Any], pickle.load(file, encoding="latin1")) + content = cast(dict[str, Any], pickle.load(file, encoding="latin1")) file.close() return content - def _prepare_sample(self, data: Tuple[np.ndarray, int]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[np.ndarray, int]) -> dict[str, Any]: image_array, category_idx = data return dict( image=Image(image_array), label=Label(category_idx, categories=self._categories), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: dp = resource_dps[0] dp = Filter(dp, self._is_data_file) dp = Mapper(dp, self._unpickle) @@ -86,18 +87,18 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, def __len__(self) -> int: return 50_000 if self._split == "train" else 10_000 - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) dp = Filter(dp, path_comparator("name", self._META_FILE_NAME)) dp = Mapper(dp, self._unpickle) - return cast(List[str], next(iter(dp))[self._CATEGORIES_KEY]) + return cast(list[str], next(iter(dp))[self._CATEGORIES_KEY]) @register_info("cifar10") -def _cifar10_info() -> Dict[str, Any]: +def _cifar10_info() -> dict[str, Any]: return dict(categories=read_categories_file("cifar10")) @@ -114,13 +115,13 @@ class Cifar10(_CifarBase): _CATEGORIES_KEY = "label_names" _categories = _cifar10_info()["categories"] - def _is_data_file(self, data: Tuple[str, Any]) -> bool: + def _is_data_file(self, data: tuple[str, Any]) -> bool: path = pathlib.Path(data[0]) return path.name.startswith("data" if self._split == "train" else "test") @register_info("cifar100") -def _cifar100_info() -> Dict[str, Any]: +def _cifar100_info() -> dict[str, Any]: return dict(categories=read_categories_file("cifar100")) @@ -137,6 +138,6 @@ class Cifar100(_CifarBase): _CATEGORIES_KEY = "fine_label_names" _categories = _cifar100_info()["categories"] - def _is_data_file(self, data: Tuple[str, Any]) -> bool: + def _is_data_file(self, data: tuple[str, Any]) -> bool: path = pathlib.Path(data[0]) return path.name == self._split diff --git a/torchvision/prototype/datasets/_builtin/clevr.py b/torchvision/prototype/datasets/_builtin/clevr.py index 46cef90efbb..4880b6bb49c 100644 --- a/torchvision/prototype/datasets/_builtin/clevr.py +++ b/torchvision/prototype/datasets/_builtin/clevr.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, Optional, Union from torchdata.datapipes.iter import Demultiplexer, Filter, IterDataPipe, IterKeyZipper, JsonParser, Mapper, UnBatcher from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -19,7 +19,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict() @@ -36,14 +36,14 @@ def __init__( super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: archive = HttpResource( "https://dl.fbaipublicfiles.com/clevr/CLEVR_v1.0.zip", sha256="5cd61cf1096ed20944df93c9adb31e74d189b8459a94f54ba00090e5c59936d1", ) return [archive] - def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) if path.parents[1].name == "images": return 0 @@ -52,14 +52,14 @@ def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: else: return None - def _filter_scene_anns(self, data: Tuple[str, Any]) -> bool: + def _filter_scene_anns(self, data: tuple[str, Any]) -> bool: key, _ = data return key == "scenes" - def _add_empty_anns(self, data: Tuple[str, BinaryIO]) -> Tuple[Tuple[str, BinaryIO], None]: + def _add_empty_anns(self, data: tuple[str, BinaryIO]) -> tuple[tuple[str, BinaryIO], None]: return data, None - def _prepare_sample(self, data: Tuple[Tuple[str, BinaryIO], Optional[Dict[str, Any]]]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[tuple[str, BinaryIO], Optional[dict[str, Any]]]) -> dict[str, Any]: image_data, scenes_data = data path, buffer = image_data @@ -69,7 +69,7 @@ def _prepare_sample(self, data: Tuple[Tuple[str, BinaryIO], Optional[Dict[str, A label=Label(len(scenes_data["objects"])) if scenes_data else None, ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: archive_dp = resource_dps[0] images_dp, scenes_dp = Demultiplexer( archive_dp, diff --git a/torchvision/prototype/datasets/_builtin/coco.py b/torchvision/prototype/datasets/_builtin/coco.py index 628629e33c0..121e1786c75 100644 --- a/torchvision/prototype/datasets/_builtin/coco.py +++ b/torchvision/prototype/datasets/_builtin/coco.py @@ -1,7 +1,7 @@ import pathlib import re from collections import defaultdict, OrderedDict -from typing import Any, BinaryIO, cast, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, cast, Optional, Union import torch from torchdata.datapipes.iter import ( @@ -34,7 +34,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: categories, super_categories = zip(*read_categories_file(NAME)) return dict(categories=categories, super_categories=super_categories) @@ -87,7 +87,7 @@ def __init__( "2017": "113a836d90195ee1f884e704da6304dfaaecff1f023f49b6ca93c4aaae470268", } - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: images = HttpResource( f"{self._IMAGE_URL_BASE}/{self._split}{self._year}.zip", sha256=self._IMAGES_CHECKSUMS[(self._year, self._split)], @@ -99,7 +99,7 @@ def _resources(self) -> List[OnlineResource]: return [images, meta] def _segmentation_to_mask( - self, segmentation: Any, *, is_crowd: bool, spatial_size: Tuple[int, int] + self, segmentation: Any, *, is_crowd: bool, spatial_size: tuple[int, int] ) -> torch.Tensor: from pycocotools import mask @@ -110,7 +110,7 @@ def _segmentation_to_mask( return torch.from_numpy(mask.decode(segmentation)).to(torch.bool) - def _decode_instances_anns(self, anns: List[Dict[str, Any]], image_meta: Dict[str, Any]) -> Dict[str, Any]: + def _decode_instances_anns(self, anns: list[dict[str, Any]], image_meta: dict[str, Any]) -> dict[str, Any]: spatial_size = (image_meta["height"], image_meta["width"]) labels = [ann["category_id"] for ann in anns] return dict( @@ -136,7 +136,7 @@ def _decode_instances_anns(self, anns: List[Dict[str, Any]], image_meta: Dict[st ann_ids=[ann["id"] for ann in anns], ) - def _decode_captions_ann(self, anns: List[Dict[str, Any]], image_meta: Dict[str, Any]) -> Dict[str, Any]: + def _decode_captions_ann(self, anns: list[dict[str, Any]], image_meta: dict[str, Any]) -> dict[str, Any]: return dict( captions=[ann["caption"] for ann in anns], ann_ids=[ann["id"] for ann in anns], @@ -153,7 +153,7 @@ def _decode_captions_ann(self, anns: List[Dict[str, Any]], image_meta: Dict[str, rf"(?P({'|'.join(_ANN_DECODERS.keys())}))_(?P[a-zA-Z]+)(?P\d+)[.]json" ) - def _filter_meta_files(self, data: Tuple[str, Any]) -> bool: + def _filter_meta_files(self, data: tuple[str, Any]) -> bool: match = self._META_FILE_PATTERN.match(pathlib.Path(data[0]).name) return bool( match @@ -162,7 +162,7 @@ def _filter_meta_files(self, data: Tuple[str, Any]) -> bool: and match["annotations"] == self._annotations ) - def _classify_meta(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_meta(self, data: tuple[str, Any]) -> Optional[int]: key, _ = data if key == "images": return 0 @@ -171,7 +171,7 @@ def _classify_meta(self, data: Tuple[str, Any]) -> Optional[int]: else: return None - def _prepare_image(self, data: Tuple[str, BinaryIO]) -> Dict[str, Any]: + def _prepare_image(self, data: tuple[str, BinaryIO]) -> dict[str, Any]: path, buffer = data return dict( path=path, @@ -180,8 +180,8 @@ def _prepare_image(self, data: Tuple[str, BinaryIO]) -> Dict[str, Any]: def _prepare_sample( self, - data: Tuple[Tuple[List[Dict[str, Any]], Dict[str, Any]], Tuple[str, BinaryIO]], - ) -> Dict[str, Any]: + data: tuple[tuple[list[dict[str, Any]], dict[str, Any]], tuple[str, BinaryIO]], + ) -> dict[str, Any]: ann_data, image_data = data anns, image_meta = ann_data @@ -191,7 +191,7 @@ def _prepare_sample( sample.update(self._ANN_DECODERS[annotations](self, anns, image_meta)) return sample - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: images_dp, meta_dp = resource_dps if self._annotations is None: @@ -203,7 +203,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, meta_dp = Filter(meta_dp, self._filter_meta_files) meta_dp = JsonParser(meta_dp) meta_dp = Mapper(meta_dp, getitem(1)) - meta_dp: IterDataPipe[Dict[str, Dict[str, Any]]] = MappingIterator(meta_dp) + meta_dp: IterDataPipe[dict[str, dict[str, Any]]] = MappingIterator(meta_dp) images_meta_dp, anns_meta_dp = Demultiplexer( meta_dp, 2, @@ -247,7 +247,7 @@ def __len__(self) -> int: self._annotations # type: ignore[index] ] - def _generate_categories(self) -> Tuple[Tuple[str, str]]: + def _generate_categories(self) -> tuple[tuple[str, str]]: self._annotations = "instances" resources = self._resources() @@ -257,7 +257,7 @@ def _generate_categories(self) -> Tuple[Tuple[str, str]]: _, meta = next(iter(dp)) # List[Tuple[super_category, id, category]] - label_data = [cast(Tuple[str, int, str], tuple(info.values())) for info in meta["categories"]] + label_data = [cast(tuple[str, int, str], tuple(info.values())) for info in meta["categories"]] # COCO actually defines 91 categories, but only 80 of them have instances. Still, the category_id refers to the # full set. To keep the labels dense, we fill the gaps with N/A. Note that there are only 10 gaps, so the total @@ -271,4 +271,4 @@ def _generate_categories(self) -> Tuple[Tuple[str, str]]: super_categories, _, categories = zip(*sorted(label_data, key=lambda info: info[1])) - return cast(Tuple[Tuple[str, str]], tuple(zip(categories, super_categories))) + return cast(tuple[tuple[str, str]], tuple(zip(categories, super_categories))) diff --git a/torchvision/prototype/datasets/_builtin/country211.py b/torchvision/prototype/datasets/_builtin/country211.py index 3308ddb99c9..2f1d5ac7da8 100644 --- a/torchvision/prototype/datasets/_builtin/country211.py +++ b/torchvision/prototype/datasets/_builtin/country211.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Dict, List, Tuple, Union +from typing import Any, Union from torchdata.datapipes.iter import Filter, IterDataPipe, Mapper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -17,7 +17,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -41,7 +41,7 @@ def __init__( super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ HttpResource( "https://openaipublic.azureedge.net/clip/data/country211.tgz", @@ -49,7 +49,7 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _prepare_sample(self, data: Tuple[str, Any]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[str, Any]) -> dict[str, Any]: path, buffer = data category = pathlib.Path(path).parent.name return dict( @@ -58,10 +58,10 @@ def _prepare_sample(self, data: Tuple[str, Any]) -> Dict[str, Any]: image=EncodedImage.from_file(buffer), ) - def _filter_split(self, data: Tuple[str, Any], *, split: str) -> bool: + def _filter_split(self, data: tuple[str, Any], *, split: str) -> bool: return pathlib.Path(data[0]).parent.parent.name == split - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: dp = resource_dps[0] dp = Filter(dp, path_comparator("parent.parent.name", self._split_folder_name)) dp = hint_shuffling(dp) @@ -75,7 +75,7 @@ def __len__(self) -> int: "test": 21_100, }[self._split] - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) return sorted({pathlib.Path(path).parent.name for path, _ in dp}) diff --git a/torchvision/prototype/datasets/_builtin/cub200.py b/torchvision/prototype/datasets/_builtin/cub200.py index 1230c88fb8d..c7efecaedf5 100644 --- a/torchvision/prototype/datasets/_builtin/cub200.py +++ b/torchvision/prototype/datasets/_builtin/cub200.py @@ -1,7 +1,7 @@ import csv import functools import pathlib -from typing import Any, BinaryIO, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, Callable, Optional, Union import torch from torchdata.datapipes.iter import ( @@ -38,7 +38,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -68,7 +68,7 @@ def __init__( skip_integrity_check=skip_integrity_check, ) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: if self._year == "2011": archive = GDriveResource( "1hbzc_P1FuxMkcabkgn9ZKinBwW683j45", @@ -104,7 +104,7 @@ def _resources(self) -> List[OnlineResource]: ) return [split, images, anns] - def _2011_classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _2011_classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) if path.parents[1].name == "images": return 0 @@ -120,20 +120,20 @@ def _2011_classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: def _2011_extract_file_name(self, rel_posix_path: str) -> str: return rel_posix_path.rsplit("/", maxsplit=1)[1] - def _2011_filter_split(self, row: List[str]) -> bool: + def _2011_filter_split(self, row: list[str]) -> bool: _, split_id = row return { "0": "test", "1": "train", }[split_id] == self._split - def _2011_segmentation_key(self, data: Tuple[str, Any]) -> str: + def _2011_segmentation_key(self, data: tuple[str, Any]) -> str: path = pathlib.Path(data[0]) return path.with_suffix(".jpg").name def _2011_prepare_ann( - self, data: Tuple[str, Tuple[List[str], Tuple[str, BinaryIO]]], spatial_size: Tuple[int, int] - ) -> Dict[str, Any]: + self, data: tuple[str, tuple[list[str], tuple[str, BinaryIO]]], spatial_size: tuple[int, int] + ) -> dict[str, Any]: _, (bounding_boxes_data, segmentation_data) = data segmentation_path, segmentation_buffer = segmentation_data return dict( @@ -147,13 +147,13 @@ def _2011_prepare_ann( def _2010_split_key(self, data: str) -> str: return data.rsplit("/", maxsplit=1)[1] - def _2010_anns_key(self, data: Tuple[str, BinaryIO]) -> Tuple[str, Tuple[str, BinaryIO]]: + def _2010_anns_key(self, data: tuple[str, BinaryIO]) -> tuple[str, tuple[str, BinaryIO]]: path = pathlib.Path(data[0]) return path.with_suffix(".jpg").name, data def _2010_prepare_ann( - self, data: Tuple[str, Tuple[str, BinaryIO]], spatial_size: Tuple[int, int] - ) -> Dict[str, Any]: + self, data: tuple[str, tuple[str, BinaryIO]], spatial_size: tuple[int, int] + ) -> dict[str, Any]: _, (path, buffer) = data content = read_mat(buffer) return dict( @@ -168,10 +168,10 @@ def _2010_prepare_ann( def _prepare_sample( self, - data: Tuple[Tuple[str, Tuple[str, BinaryIO]], Any], + data: tuple[tuple[str, tuple[str, BinaryIO]], Any], *, - prepare_ann_fn: Callable[[Any, Tuple[int, int]], Dict[str, Any]], - ) -> Dict[str, Any]: + prepare_ann_fn: Callable[[Any, tuple[int, int]], dict[str, Any]], + ) -> dict[str, Any]: data, anns_data = data _, image_data = data path, buffer = image_data @@ -187,7 +187,7 @@ def _prepare_sample( ), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: prepare_ann_fn: Callable if self._year == "2011": archive_dp, segmentations_dp = resource_dps @@ -254,7 +254,7 @@ def __len__(self) -> int: ("test", "2011"): 5_794, }[(self._split, self._year)] - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: self._year = "2011" resources = self._resources() diff --git a/torchvision/prototype/datasets/_builtin/dtd.py b/torchvision/prototype/datasets/_builtin/dtd.py index 5b9922a8269..7d199f0f7ec 100644 --- a/torchvision/prototype/datasets/_builtin/dtd.py +++ b/torchvision/prototype/datasets/_builtin/dtd.py @@ -1,6 +1,6 @@ import enum import pathlib -from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, Optional, Union from torchdata.datapipes.iter import CSVParser, Demultiplexer, Filter, IterDataPipe, IterKeyZipper, LineReader, Mapper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -27,7 +27,7 @@ class DTDDemux(enum.IntEnum): @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -55,7 +55,7 @@ def __init__( super().__init__(root, skip_integrity_check=skip_validation_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: archive = HttpResource( "https://www.robots.ox.ac.uk/~vgg/data/dtd/download/dtd-r1.0.1.tar.gz", sha256="e42855a52a4950a3b59612834602aa253914755c95b0cff9ead6d07395f8e205", @@ -63,7 +63,7 @@ def _resources(self) -> List[OnlineResource]: ) return [archive] - def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) if path.parent.name == "labels": if path.name == "labels_joint_anno.txt": @@ -75,12 +75,12 @@ def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: else: return None - def _image_key_fn(self, data: Tuple[str, Any]) -> str: + def _image_key_fn(self, data: tuple[str, Any]) -> str: path = pathlib.Path(data[0]) # The split files contain hardcoded posix paths for the images, e.g. banded/banded_0001.jpg return str(path.relative_to(path.parents[1]).as_posix()) - def _prepare_sample(self, data: Tuple[Tuple[str, List[str]], Tuple[str, BinaryIO]]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[tuple[str, list[str]], tuple[str, BinaryIO]]) -> dict[str, Any]: (_, joint_categories_data), image_data = data _, *joint_categories = joint_categories_data path, buffer = image_data @@ -94,7 +94,7 @@ def _prepare_sample(self, data: Tuple[Tuple[str, List[str]], Tuple[str, BinaryIO image=EncodedImage.from_file(buffer), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: archive_dp = resource_dps[0] splits_dp, joint_categories_dp, images_dp = Demultiplexer( @@ -124,10 +124,10 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, ) return Mapper(dp, self._prepare_sample) - def _filter_images(self, data: Tuple[str, Any]) -> bool: + def _filter_images(self, data: tuple[str, Any]) -> bool: return self._classify_archive(data) == DTDDemux.IMAGES - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) diff --git a/torchvision/prototype/datasets/_builtin/eurosat.py b/torchvision/prototype/datasets/_builtin/eurosat.py index 747f0320e86..a3631253dbb 100644 --- a/torchvision/prototype/datasets/_builtin/eurosat.py +++ b/torchvision/prototype/datasets/_builtin/eurosat.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Dict, List, Tuple, Union +from typing import Any, Union from torchdata.datapipes.iter import IterDataPipe, Mapper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -12,7 +12,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict( categories=( "AnnualCrop", @@ -39,7 +39,7 @@ def __init__(self, root: Union[str, pathlib.Path], *, skip_integrity_check: bool self._categories = _info()["categories"] super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ HttpResource( "https://madm.dfki.de/files/sentinel/EuroSAT.zip", @@ -47,7 +47,7 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _prepare_sample(self, data: Tuple[str, Any]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[str, Any]) -> dict[str, Any]: path, buffer = data category = pathlib.Path(path).parent.name return dict( @@ -56,7 +56,7 @@ def _prepare_sample(self, data: Tuple[str, Any]) -> Dict[str, Any]: image=EncodedImage.from_file(buffer), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: dp = resource_dps[0] dp = hint_shuffling(dp) dp = hint_sharding(dp) diff --git a/torchvision/prototype/datasets/_builtin/fer2013.py b/torchvision/prototype/datasets/_builtin/fer2013.py index e6194ab01bd..c3c47b43e8f 100644 --- a/torchvision/prototype/datasets/_builtin/fer2013.py +++ b/torchvision/prototype/datasets/_builtin/fer2013.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Dict, List, Union +from typing import Any, Union import torch from torchdata.datapipes.iter import CSVDictParser, IterDataPipe, Mapper @@ -14,7 +14,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=("angry", "disgust", "fear", "happy", "sad", "surprise", "neutral")) @@ -37,7 +37,7 @@ def __init__( "test": "dec8dfe8021e30cd6704b85ec813042b4a5d99d81cb55e023291a94104f575c3", } - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: archive = KaggleDownloadResource( "https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge", file_name=f"{self._split}.csv.zip", @@ -45,7 +45,7 @@ def _resources(self) -> List[OnlineResource]: ) return [archive] - def _prepare_sample(self, data: Dict[str, Any]) -> Dict[str, Any]: + def _prepare_sample(self, data: dict[str, Any]) -> dict[str, Any]: label_id = data.get("emotion") return dict( @@ -53,7 +53,7 @@ def _prepare_sample(self, data: Dict[str, Any]) -> Dict[str, Any]: label=Label(int(label_id), categories=self._categories) if label_id is not None else None, ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: dp = resource_dps[0] dp = CSVDictParser(dp) dp = hint_shuffling(dp) diff --git a/torchvision/prototype/datasets/_builtin/food101.py b/torchvision/prototype/datasets/_builtin/food101.py index ed446f342e9..ab06703408f 100644 --- a/torchvision/prototype/datasets/_builtin/food101.py +++ b/torchvision/prototype/datasets/_builtin/food101.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, Optional, Union from torchdata.datapipes.iter import Demultiplexer, Filter, IterDataPipe, IterKeyZipper, LineReader, Mapper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -20,7 +20,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -36,7 +36,7 @@ def __init__(self, root: Union[str, Path], *, split: str = "train", skip_integri super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ HttpResource( url="http://data.vision.ee.ethz.ch/cvl/food-101.tar.gz", @@ -45,7 +45,7 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = Path(data[0]) if path.parents[1].name == "images": return 0 @@ -54,7 +54,7 @@ def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: else: return None - def _prepare_sample(self, data: Tuple[str, Tuple[str, BinaryIO]]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[str, tuple[str, BinaryIO]]) -> dict[str, Any]: id, (path, buffer) = data return dict( label=Label.from_category(id.split("/", 1)[0], categories=self._categories), @@ -62,11 +62,11 @@ def _prepare_sample(self, data: Tuple[str, Tuple[str, BinaryIO]]) -> Dict[str, A image=EncodedImage.from_file(buffer), ) - def _image_key(self, data: Tuple[str, Any]) -> str: + def _image_key(self, data: tuple[str, Any]) -> str: path = Path(data[0]) return path.relative_to(path.parents[1]).with_suffix("").as_posix() - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: archive_dp = resource_dps[0] images_dp, split_dp = Demultiplexer( archive_dp, 2, self._classify_archive, drop_none=True, buffer_size=INFINITE_BUFFER_SIZE @@ -86,7 +86,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, return Mapper(dp, self._prepare_sample) - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[0].load(self._root) dp = Filter(dp, path_comparator("name", "classes.txt")) diff --git a/torchvision/prototype/datasets/_builtin/gtsrb.py b/torchvision/prototype/datasets/_builtin/gtsrb.py index b31793c0fa9..4c981ffaec0 100644 --- a/torchvision/prototype/datasets/_builtin/gtsrb.py +++ b/torchvision/prototype/datasets/_builtin/gtsrb.py @@ -1,5 +1,5 @@ import pathlib -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Optional, Union from torchdata.datapipes.iter import CSVDictParser, Demultiplexer, Filter, IterDataPipe, Mapper, Zipper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -18,7 +18,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict( categories=[f"{label:05d}" for label in range(43)], ) @@ -50,8 +50,8 @@ def __init__( "test_ground_truth": "f94e5a7614d75845c74c04ddb26b8796b9e483f43541dd95dd5b726504e16d6d", } - def _resources(self) -> List[OnlineResource]: - rsrcs: List[OnlineResource] = [HttpResource(self._URLS[self._split], sha256=self._CHECKSUMS[self._split])] + def _resources(self) -> list[OnlineResource]: + rsrcs: list[OnlineResource] = [HttpResource(self._URLS[self._split], sha256=self._CHECKSUMS[self._split])] if self._split == "test": rsrcs.append( @@ -63,7 +63,7 @@ def _resources(self) -> List[OnlineResource]: return rsrcs - def _classify_train_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_train_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) if path.suffix == ".ppm": return 0 @@ -72,7 +72,7 @@ def _classify_train_archive(self, data: Tuple[str, Any]) -> Optional[int]: else: return None - def _prepare_sample(self, data: Tuple[Tuple[str, Any], Dict[str, Any]]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[tuple[str, Any], dict[str, Any]]) -> dict[str, Any]: (path, buffer), csv_info = data label = int(csv_info["ClassId"]) @@ -89,7 +89,7 @@ def _prepare_sample(self, data: Tuple[Tuple[str, Any], Dict[str, Any]]) -> Dict[ "bounding_boxes": bounding_boxes, } - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: if self._split == "train": images_dp, ann_dp = Demultiplexer( resource_dps[0], 2, self._classify_train_archive, drop_none=True, buffer_size=INFINITE_BUFFER_SIZE diff --git a/torchvision/prototype/datasets/_builtin/imagenet.py b/torchvision/prototype/datasets/_builtin/imagenet.py index ad561c48c7d..ec27da61523 100644 --- a/torchvision/prototype/datasets/_builtin/imagenet.py +++ b/torchvision/prototype/datasets/_builtin/imagenet.py @@ -1,8 +1,10 @@ import enum import pathlib import re +from collections.abc import Iterator +from re import Match -from typing import Any, BinaryIO, cast, Dict, Iterator, List, Match, Optional, Tuple, Union +from typing import Any, BinaryIO, cast, Optional, Union from torchdata.datapipes.iter import ( Demultiplexer, @@ -33,7 +35,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: categories, wnids = zip(*read_categories_file(NAME)) return dict(categories=categories, wnids=wnids) @@ -56,10 +58,10 @@ class CategoryAndWordNetIDExtractor(IterDataPipe): "n03710721": "tank suit", } - def __init__(self, datapipe: IterDataPipe[Tuple[str, BinaryIO]]) -> None: + def __init__(self, datapipe: IterDataPipe[tuple[str, BinaryIO]]) -> None: self.datapipe = datapipe - def __iter__(self) -> Iterator[Tuple[str, str]]: + def __iter__(self) -> Iterator[tuple[str, str]]: for _, stream in self.datapipe: synsets = read_mat(stream, squeeze_me=True)["synsets"] for _, wnid, category, _, num_children, *_ in synsets: @@ -99,13 +101,13 @@ def __init__( "test_v10102019": "9cf7f8249639510f17d3d8a0deb47cd22a435886ba8e29e2b3223e65a4079eb4", } - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: name = "test_v10102019" if self._split == "test" else self._split images = ImageNetResource( file_name=f"ILSVRC2012_img_{name}.tar", sha256=self._IMAGES_CHECKSUMS[name], ) - resources: List[OnlineResource] = [images] + resources: list[OnlineResource] = [images] if self._split == "val": devkit = ImageNetResource( @@ -118,16 +120,16 @@ def _resources(self) -> List[OnlineResource]: _TRAIN_IMAGE_NAME_PATTERN = re.compile(r"(?Pn\d{8})_\d+[.]JPEG") - def _prepare_train_data(self, data: Tuple[str, BinaryIO]) -> Tuple[Tuple[Label, str], Tuple[str, BinaryIO]]: + def _prepare_train_data(self, data: tuple[str, BinaryIO]) -> tuple[tuple[Label, str], tuple[str, BinaryIO]]: path = pathlib.Path(data[0]) wnid = cast(Match[str], self._TRAIN_IMAGE_NAME_PATTERN.match(path.name))["wnid"] label = Label.from_category(self._wnid_to_category[wnid], categories=self._categories) return (label, wnid), data - def _prepare_test_data(self, data: Tuple[str, BinaryIO]) -> Tuple[None, Tuple[str, BinaryIO]]: + def _prepare_test_data(self, data: tuple[str, BinaryIO]) -> tuple[None, tuple[str, BinaryIO]]: return None, data - def _classifiy_devkit(self, data: Tuple[str, BinaryIO]) -> Optional[int]: + def _classifiy_devkit(self, data: tuple[str, BinaryIO]) -> Optional[int]: return { "meta.mat": ImageNetDemux.META, "ILSVRC2012_validation_ground_truth.txt": ImageNetDemux.LABEL, @@ -139,8 +141,8 @@ def _val_test_image_key(self, path: pathlib.Path) -> int: return int(self._VAL_TEST_IMAGE_NAME_PATTERN.match(path.name)["id"]) # type: ignore[index] def _prepare_val_data( - self, data: Tuple[Tuple[int, str], Tuple[str, BinaryIO]] - ) -> Tuple[Tuple[Label, str], Tuple[str, BinaryIO]]: + self, data: tuple[tuple[int, str], tuple[str, BinaryIO]] + ) -> tuple[tuple[Label, str], tuple[str, BinaryIO]]: label_data, image_data = data _, wnid = label_data label = Label.from_category(self._wnid_to_category[wnid], categories=self._categories) @@ -148,8 +150,8 @@ def _prepare_val_data( def _prepare_sample( self, - data: Tuple[Optional[Tuple[Label, str]], Tuple[str, BinaryIO]], - ) -> Dict[str, Any]: + data: tuple[Optional[tuple[Label, str]], tuple[str, BinaryIO]], + ) -> dict[str, Any]: label_data, (path, buffer) = data return dict( @@ -158,7 +160,7 @@ def _prepare_sample( image=EncodedImage.from_file(buffer), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: if self._split in {"train", "test"}: dp = resource_dps[0] @@ -185,7 +187,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, label_dp = LineReader(label_dp, decode=True, return_path=False) label_dp = Mapper(label_dp, int) label_dp = Mapper(label_dp, wnid_map.__getitem__) - label_dp: IterDataPipe[Tuple[int, str]] = Enumerator(label_dp, 1) + label_dp: IterDataPipe[tuple[int, str]] = Enumerator(label_dp, 1) label_dp = hint_shuffling(label_dp) label_dp = hint_sharding(label_dp) @@ -207,10 +209,10 @@ def __len__(self) -> int: "test": 100_000, }[self._split] - def _filter_meta(self, data: Tuple[str, Any]) -> bool: + def _filter_meta(self, data: tuple[str, Any]) -> bool: return self._classifiy_devkit(data) == ImageNetDemux.META - def _generate_categories(self) -> List[Tuple[str, ...]]: + def _generate_categories(self) -> list[tuple[str, ...]]: self._split = "val" resources = self._resources() @@ -218,6 +220,6 @@ def _generate_categories(self) -> List[Tuple[str, ...]]: meta_dp = Filter(devkit_dp, self._filter_meta) meta_dp = CategoryAndWordNetIDExtractor(meta_dp) - categories_and_wnids = cast(List[Tuple[str, ...]], list(meta_dp)) + categories_and_wnids = cast(list[tuple[str, ...]], list(meta_dp)) categories_and_wnids.sort(key=lambda category_and_wnid: category_and_wnid[1]) return categories_and_wnids diff --git a/torchvision/prototype/datasets/_builtin/mnist.py b/torchvision/prototype/datasets/_builtin/mnist.py index 218b8b330ba..48787eaaace 100644 --- a/torchvision/prototype/datasets/_builtin/mnist.py +++ b/torchvision/prototype/datasets/_builtin/mnist.py @@ -3,7 +3,8 @@ import operator import pathlib import string -from typing import Any, BinaryIO, cast, Dict, Iterator, List, Optional, Sequence, Tuple, Union +from collections.abc import Iterator, Sequence +from typing import Any, BinaryIO, cast, Optional, Union import torch from torchdata.datapipes.iter import Decompressor, Demultiplexer, IterDataPipe, Mapper, Zipper @@ -30,7 +31,7 @@ class MNISTFileReader(IterDataPipe[torch.Tensor]): } def __init__( - self, datapipe: IterDataPipe[Tuple[Any, BinaryIO]], *, start: Optional[int], stop: Optional[int] + self, datapipe: IterDataPipe[tuple[Any, BinaryIO]], *, start: Optional[int], stop: Optional[int] ) -> None: self.datapipe = datapipe self.start = start @@ -46,7 +47,7 @@ def __iter__(self) -> Iterator[torch.Tensor]: ndim = magic % 256 - 1 num_samples = int(read(dtype=torch.int32, count=1)) - shape = cast(List[int], read(dtype=torch.int32, count=ndim).tolist()) if ndim else [] + shape = cast(list[int], read(dtype=torch.int32, count=ndim).tolist()) if ndim else [] count = prod(shape) if shape else 1 start = self.start or 0 @@ -66,10 +67,10 @@ class _MNISTBase(Dataset): _URL_BASE: Union[str, Sequence[str]] @abc.abstractmethod - def _files_and_checksums(self) -> Tuple[Tuple[str, str], Tuple[str, str]]: + def _files_and_checksums(self) -> tuple[tuple[str, str], tuple[str, str]]: pass - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: (images_file, images_sha256), ( labels_file, labels_sha256, @@ -87,19 +88,19 @@ def _resources(self) -> List[OnlineResource]: return [images, labels] - def start_and_stop(self) -> Tuple[Optional[int], Optional[int]]: + def start_and_stop(self) -> tuple[Optional[int], Optional[int]]: return None, None - _categories: List[str] + _categories: list[str] - def _prepare_sample(self, data: Tuple[torch.Tensor, torch.Tensor]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[torch.Tensor, torch.Tensor]) -> dict[str, Any]: image, label = data return dict( image=Image(image), label=Label(label, dtype=torch.int64, categories=self._categories), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: images_dp, labels_dp = resource_dps start, stop = self.start_and_stop() @@ -116,7 +117,7 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, @register_info("mnist") -def _mnist_info() -> Dict[str, Any]: +def _mnist_info() -> dict[str, Any]: return dict( categories=[str(label) for label in range(10)], ) @@ -149,7 +150,7 @@ def __init__( "t10k-labels-idx1-ubyte.gz": "f7ae60f92e00ec6debd23a6088c31dbd2371eca3ffa0defaefb259924204aec6", } - def _files_and_checksums(self) -> Tuple[Tuple[str, str], Tuple[str, str]]: + def _files_and_checksums(self) -> tuple[tuple[str, str], tuple[str, str]]: prefix = "train" if self._split == "train" else "t10k" images_file = f"{prefix}-images-idx3-ubyte.gz" labels_file = f"{prefix}-labels-idx1-ubyte.gz" @@ -165,7 +166,7 @@ def __len__(self) -> int: @register_info("fashionmnist") -def _fashionmnist_info() -> Dict[str, Any]: +def _fashionmnist_info() -> dict[str, Any]: return dict( categories=[ "T-shirt/top", @@ -200,7 +201,7 @@ class FashionMNIST(MNIST): @register_info("kmnist") -def _kmnist_info() -> Dict[str, Any]: +def _kmnist_info() -> dict[str, Any]: return dict( categories=["o", "ki", "su", "tsu", "na", "ha", "ma", "ya", "re", "wo"], ) @@ -224,7 +225,7 @@ class KMNIST(MNIST): @register_info("emnist") -def _emnist_info() -> Dict[str, Any]: +def _emnist_info() -> dict[str, Any]: return dict( categories=list(string.digits + string.ascii_uppercase + string.ascii_lowercase), ) @@ -252,14 +253,14 @@ def __init__( _URL_BASE = "https://rds.westernsydney.edu.au/Institutes/MARCS/BENS/EMNIST" - def _files_and_checksums(self) -> Tuple[Tuple[str, str], Tuple[str, str]]: + def _files_and_checksums(self) -> tuple[tuple[str, str], tuple[str, str]]: prefix = f"emnist-{self._image_set.replace('_', '').lower()}-{self._split}" images_file = f"{prefix}-images-idx3-ubyte.gz" labels_file = f"{prefix}-labels-idx1-ubyte.gz" # Since EMNIST provides the data files inside an archive, we don't need to provide checksums for them return (images_file, ""), (labels_file, "") - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ HttpResource( f"{self._URL_BASE}/emnist-gzip.zip", @@ -267,7 +268,7 @@ def _resources(self) -> List[OnlineResource]: ) ] - def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) (images_file, _), (labels_file, _) = self._files_and_checksums() if path.name == images_file: @@ -291,7 +292,7 @@ def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: 46: 9, } - def _prepare_sample(self, data: Tuple[torch.Tensor, torch.Tensor]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[torch.Tensor, torch.Tensor]) -> dict[str, Any]: # In these two splits, some lowercase letters are merged into their uppercase ones (see Fig 2. in the paper). # That means for example that there is 'D', 'd', and 'C', but not 'c'. Since the labels are nevertheless dense, # i.e. no gaps between 0 and 46 for 47 total classes, we need to add an offset to create these gaps. For @@ -306,7 +307,7 @@ def _prepare_sample(self, data: Tuple[torch.Tensor, torch.Tensor]) -> Dict[str, data = (image, label) return super()._prepare_sample(data) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: archive_dp = resource_dps[0] images_dp, labels_dp = Demultiplexer( archive_dp, @@ -335,7 +336,7 @@ def __len__(self) -> int: @register_info("qmnist") -def _qmnist_info() -> Dict[str, Any]: +def _qmnist_info() -> dict[str, Any]: return dict( categories=[str(label) for label in range(10)], ) @@ -367,7 +368,7 @@ def __init__( "xnist-labels-idx2-int.xz": "db042968723ec2b7aed5f1beac25d2b6e983b9286d4f4bf725f1086e5ae55c4f", } - def _files_and_checksums(self) -> Tuple[Tuple[str, str], Tuple[str, str]]: + def _files_and_checksums(self) -> tuple[tuple[str, str], tuple[str, str]]: prefix = "xnist" if self._split == "nist" else f"qmnist-{'train' if self._split == 'train' else 'test'}" suffix = "xz" if self._split == "nist" else "gz" images_file = f"{prefix}-images-idx3-ubyte.{suffix}" @@ -377,7 +378,7 @@ def _files_and_checksums(self) -> Tuple[Tuple[str, str], Tuple[str, str]]: self._CHECKSUMS[labels_file], ) - def start_and_stop(self) -> Tuple[Optional[int], Optional[int]]: + def start_and_stop(self) -> tuple[Optional[int], Optional[int]]: start: Optional[int] stop: Optional[int] if self._split == "test10k": @@ -393,7 +394,7 @@ def start_and_stop(self) -> Tuple[Optional[int], Optional[int]]: _categories = _emnist_info()["categories"] - def _prepare_sample(self, data: Tuple[torch.Tensor, torch.Tensor]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[torch.Tensor, torch.Tensor]) -> dict[str, Any]: image, ann = data label, *extra_anns = ann sample = super()._prepare_sample((image, label)) diff --git a/torchvision/prototype/datasets/_builtin/oxford_iiit_pet.py b/torchvision/prototype/datasets/_builtin/oxford_iiit_pet.py index 9d14a7b9b6f..9b03486d952 100644 --- a/torchvision/prototype/datasets/_builtin/oxford_iiit_pet.py +++ b/torchvision/prototype/datasets/_builtin/oxford_iiit_pet.py @@ -1,6 +1,6 @@ import enum import pathlib -from typing import Any, BinaryIO, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, Optional, Union from torchdata.datapipes.iter import CSVDictParser, Demultiplexer, Filter, IterDataPipe, IterKeyZipper, Mapper from torchvision.prototype.datasets.utils import Dataset, EncodedImage, HttpResource, OnlineResource @@ -27,7 +27,7 @@ class OxfordIIITPetDemux(enum.IntEnum): @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -44,7 +44,7 @@ def __init__( self._categories = _info()["categories"] super().__init__(root, skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: images = HttpResource( "https://www.robots.ox.ac.uk/~vgg/data/pets/data/images.tar.gz", sha256="67195c5e1c01f1ab5f9b6a5d22b8c27a580d896ece458917e61d459337fa318d", @@ -57,21 +57,21 @@ def _resources(self) -> List[OnlineResource]: ) return [images, anns] - def _classify_anns(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_anns(self, data: tuple[str, Any]) -> Optional[int]: return { "annotations": OxfordIIITPetDemux.SPLIT_AND_CLASSIFICATION, "trimaps": OxfordIIITPetDemux.SEGMENTATIONS, }.get(pathlib.Path(data[0]).parent.name) - def _filter_images(self, data: Tuple[str, Any]) -> bool: + def _filter_images(self, data: tuple[str, Any]) -> bool: return pathlib.Path(data[0]).suffix == ".jpg" - def _filter_segmentations(self, data: Tuple[str, Any]) -> bool: + def _filter_segmentations(self, data: tuple[str, Any]) -> bool: return not pathlib.Path(data[0]).name.startswith(".") def _prepare_sample( - self, data: Tuple[Tuple[Dict[str, str], Tuple[str, BinaryIO]], Tuple[str, BinaryIO]] - ) -> Dict[str, Any]: + self, data: tuple[tuple[dict[str, str], tuple[str, BinaryIO]], tuple[str, BinaryIO]] + ) -> dict[str, Any]: ann_data, image_data = data classification_data, segmentation_data = ann_data segmentation_path, segmentation_buffer = segmentation_data @@ -86,7 +86,7 @@ def _prepare_sample( image=EncodedImage.from_file(image_buffer), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: images_dp, anns_dp = resource_dps images_dp = Filter(images_dp, self._filter_images) @@ -125,10 +125,10 @@ def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, ) return Mapper(dp, self._prepare_sample) - def _filter_split_and_classification_anns(self, data: Tuple[str, Any]) -> bool: + def _filter_split_and_classification_anns(self, data: tuple[str, Any]) -> bool: return self._classify_anns(data) == OxfordIIITPetDemux.SPLIT_AND_CLASSIFICATION - def _generate_categories(self) -> List[str]: + def _generate_categories(self) -> list[str]: resources = self._resources() dp = resources[1].load(self._root) diff --git a/torchvision/prototype/datasets/_builtin/pcam.py b/torchvision/prototype/datasets/_builtin/pcam.py index 6eb4118ca28..e0c0f3f2d9e 100644 --- a/torchvision/prototype/datasets/_builtin/pcam.py +++ b/torchvision/prototype/datasets/_builtin/pcam.py @@ -1,7 +1,8 @@ import io import pathlib from collections import namedtuple -from typing import Any, Dict, Iterator, List, Optional, Tuple, Union +from collections.abc import Iterator +from typing import Any, Optional, Union from torchdata.datapipes.iter import IterDataPipe, Mapper, Zipper from torchvision.prototype.datasets.utils import Dataset, GDriveResource, OnlineResource @@ -15,16 +16,16 @@ NAME = "pcam" -class PCAMH5Reader(IterDataPipe[Tuple[str, io.IOBase]]): +class PCAMH5Reader(IterDataPipe[tuple[str, io.IOBase]]): def __init__( self, - datapipe: IterDataPipe[Tuple[str, io.IOBase]], + datapipe: IterDataPipe[tuple[str, io.IOBase]], key: Optional[str] = None, # Note: this key thing might be very specific to the PCAM dataset ) -> None: self.datapipe = datapipe self.key = key - def __iter__(self) -> Iterator[Tuple[str, io.IOBase]]: + def __iter__(self) -> Iterator[tuple[str, io.IOBase]]: import h5py for _, handle in self.datapipe: @@ -41,7 +42,7 @@ def __iter__(self) -> Iterator[Tuple[str, io.IOBase]]: @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=["0", "1"]) @@ -99,13 +100,13 @@ def __init__( ), } - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: return [ # = [images resource, targets resource] GDriveResource(file_name=file_name, id=gdrive_id, sha256=sha256, preprocess="decompress") for file_name, gdrive_id, sha256 in self._RESOURCES[self._split] ] - def _prepare_sample(self, data: Tuple[Any, Any]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[Any, Any]) -> dict[str, Any]: image, target = data # They're both numpy arrays at this point return { @@ -113,7 +114,7 @@ def _prepare_sample(self, data: Tuple[Any, Any]) -> Dict[str, Any]: "label": Label(target.item(), categories=self._categories), } - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: images_dp, targets_dp = resource_dps diff --git a/torchvision/prototype/datasets/_builtin/sbd.py b/torchvision/prototype/datasets/_builtin/sbd.py index 97986b58b5d..dafceb793e0 100644 --- a/torchvision/prototype/datasets/_builtin/sbd.py +++ b/torchvision/prototype/datasets/_builtin/sbd.py @@ -1,6 +1,6 @@ import pathlib import re -from typing import Any, BinaryIO, cast, Dict, List, Optional, Tuple, Union +from typing import Any, BinaryIO, cast, Optional, Union import numpy as np import torch @@ -23,7 +23,7 @@ @register_info(NAME) -def _info() -> Dict[str, Any]: +def _info() -> dict[str, Any]: return dict(categories=read_categories_file(NAME)) @@ -48,7 +48,7 @@ def __init__( super().__init__(root, dependencies=("scipy",), skip_integrity_check=skip_integrity_check) - def _resources(self) -> List[OnlineResource]: + def _resources(self) -> list[OnlineResource]: resources = [ HttpResource( "https://www2.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/semantic_contours/benchmark.tgz", @@ -64,7 +64,7 @@ def _resources(self) -> List[OnlineResource]: ) return resources # type: ignore[return-value] - def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: + def _classify_archive(self, data: tuple[str, Any]) -> Optional[int]: path = pathlib.Path(data[0]) parent, grandparent, *_ = path.parents @@ -79,7 +79,7 @@ def _classify_archive(self, data: Tuple[str, Any]) -> Optional[int]: return None - def _prepare_sample(self, data: Tuple[Tuple[Any, Tuple[str, BinaryIO]], Tuple[str, BinaryIO]]) -> Dict[str, Any]: + def _prepare_sample(self, data: tuple[tuple[Any, tuple[str, BinaryIO]], tuple[str, BinaryIO]]) -> dict[str, Any]: split_and_image_data, ann_data = data _, image_data = split_and_image_data image_path, image_buffer = image_data @@ -98,7 +98,7 @@ def _prepare_sample(self, data: Tuple[Tuple[Any, Tuple[str, BinaryIO]], Tuple[st segmentation=torch.as_tensor(anns["Segmentation"].item()), ) - def _datapipe(self, resource_dps: List[IterDataPipe]) -> IterDataPipe[Dict[str, Any]]: + def _datapipe(self, resource_dps: list[IterDataPipe]) -> IterDataPipe[dict[str, Any]]: if self._split == "train_noval": archive_dp, split_dp = resource_dps images_dp, anns_dp = Demultiplexer( @@ -141,7 +141,7 @@ def __len__(self) -> int: "train_noval": 5_623, }[self._split] - def _generate_categories(self) -> Tuple[str, ...]: + def _generate_categories(self) -> tuple[str, ...]: resources = self._resources() dp = resources[0].load(self._root) @@ -152,7 +152,7 @@ def _generate_categories(self) -> Tuple[str, ...]: pattern = re.compile(r"\s*'(?P\w+)';\s*%(?P