Skip to content

Commit b373dd7

Browse files
committed
chore(ci): enable Python 3.13 support
Signed-off-by: Rickypanta0 <[email protected]>
1 parent f006ab7 commit b373dd7

File tree

50 files changed

+146
-10503
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+146
-10503
lines changed

.github/workflows/pre_merge.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- name: Set up Python
3131
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6
3232
with:
33-
python-version: "3.10"
33+
python-version: "3.13"
3434
- name: Install Tox
3535
run: pip install tox
3636
- name: Code quality checks
@@ -43,8 +43,8 @@ jobs:
4343
max-parallel: 1
4444
matrix:
4545
include:
46-
- python-version: "3.10"
47-
tox-env: "py310"
46+
- python-version: "3.13"
47+
tox-env: "py313"
4848
steps:
4949
- name: Checkout repository
5050
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5

docs/source/markdown/guides/developer/contributing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Set up your development environment to start contributing. This involves install
1818
1. Create and activate a new Conda environment:
1919

2020
```bash
21-
conda create -n anomalib_dev python=3.10
21+
conda create -n anomalib_dev python=3.13
2222
conda activate anomalib_dev
2323
```
2424

pyproject.toml

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ name = "anomalib"
99
dynamic = ["version"]
1010
readme = "README.md"
1111
description = "anomalib - Anomaly Detection Library"
12-
requires-python = ">=3.10"
12+
requires-python = ">=3.13"
1313
license = { file = "LICENSE" }
1414
authors = [{ name = "Intel OpenVINO" }]
1515

@@ -18,10 +18,7 @@ classifiers = [
1818
"Intended Audience :: Developers",
1919
"License :: OSI Approved :: Apache Software License",
2020
"Programming Language :: Python",
21-
"Programming Language :: Python :: 3",
22-
"Programming Language :: Python :: 3.10",
23-
"Programming Language :: Python :: 3.11",
24-
"Programming Language :: Python :: 3.12",
21+
"Programming Language :: Python :: 3.13",
2522
"Topic :: Software Development :: Libraries",
2623
"Topic :: Scientific/Engineering :: Artificial Intelligence",
2724
]
@@ -100,19 +97,19 @@ test = [
10097
]
10198
# PyTorch dependency groups
10299
cpu = [
103-
"torch>=2.4.0,<=2.8.0",
100+
"torch>=2.4.0",
104101
"torchvision>=0.19.0",
105102
]
106103
cu118 = [
107-
"torch>=2.4.0,<=2.8.0",
108-
"torchvision>=0.19.0",
104+
"torch>=2.4.0,<=2.5.1 ; python_version < '3.13'",
105+
"torchvision>=0.19.0 ; python_version < '3.13'",
109106
]
110107
cu121 = [
111-
"torch>=2.4.0,<=2.8.0",
112-
"torchvision>=0.19.0",
108+
"torch>=2.4.0 ; python_version < '3.13'",
109+
"torchvision>=0.19.0 ; python_version < '3.13'",
113110
]
114111
cu124 = [
115-
"torch>=2.4.0,<=2.8.0",
112+
"torch>=2.4.0",
116113
"torchvision>=0.19.0",
117114
]
118115
cu130 = [
@@ -238,6 +235,44 @@ pytorch-triton-xpu = [
238235
# Enable preview features
239236
preview = true
240237

238+
# Exclude a variety of commonly ignored directories.
239+
exclude = [
240+
".bzr",
241+
".direnv",
242+
".eggs",
243+
".git",
244+
".hg",
245+
".mypy_cache",
246+
".nox",
247+
".pants.d",
248+
".pytype",
249+
".ruff_cache",
250+
".svn",
251+
".tox",
252+
".venv",
253+
"__pypackages__",
254+
"_build",
255+
"buck-out",
256+
"build",
257+
"dist",
258+
"node_modules",
259+
"venv",
260+
]
261+
262+
# Same as Black.
263+
line-length = 120
264+
265+
# Assume Python 3.13.
266+
target-version = "py313"
267+
268+
# Allow imports relative to the "src" and "tests" directories.
269+
src = ["src", "tests"]
270+
271+
[tool.ruff.lint]
272+
273+
# Allow unused variables when underscore-prefixed.
274+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
275+
241276
# Enable rules
242277
select = [
243278
"F", # Pyflakes (`F`)
@@ -292,6 +327,7 @@ select = [
292327

293328
ignore = [
294329
# pydocstyle
330+
"COM812",
295331
"D107", # Missing docstring in __init__
296332

297333
# pylint
@@ -346,57 +382,21 @@ ignore = [
346382
fixable = ["ALL"]
347383
unfixable = []
348384

349-
# Exclude a variety of commonly ignored directories.
350-
exclude = [
351-
".bzr",
352-
".direnv",
353-
".eggs",
354-
".git",
355-
".hg",
356-
".mypy_cache",
357-
".nox",
358-
".pants.d",
359-
".pytype",
360-
".ruff_cache",
361-
".svn",
362-
".tox",
363-
".venv",
364-
"__pypackages__",
365-
"_build",
366-
"buck-out",
367-
"build",
368-
"dist",
369-
"node_modules",
370-
"venv",
371-
]
372-
373-
# Same as Black.
374-
line-length = 120
375-
376-
# Allow unused variables when underscore-prefixed.
377-
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
378-
379-
# Assume Python 3.10.
380-
target-version = "py310"
381-
382-
# Allow imports relative to the "src" and "tests" directories.
383-
src = ["src", "tests"]
384-
385-
[tool.ruff.mccabe]
385+
[tool.ruff.lint.mccabe]
386386
# Unlike Flake8, default to a complexity level of 10.
387387
max-complexity = 15
388388

389389

390-
[tool.ruff.pydocstyle]
390+
[tool.ruff.lint.pydocstyle]
391391
convention = "google"
392392

393-
[tool.ruff.flake8-copyright]
393+
[tool.ruff.lint.flake8-copyright]
394394
notice-rgx = """
395395
# Copyright \\(C\\) (\\d{4}(-\\d{4})?) Intel Corporation
396396
# SPDX-License-Identifier: Apache-2\\.0
397397
"""
398398

399-
[tool.ruff.per-file-ignores]
399+
[tool.ruff.lint.per-file-ignores]
400400
"examples/notebooks/**/*" = ["CPY001"]
401401

402402
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

src/anomalib/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@
3232
with a focus on reproducibility and ease of use.
3333
"""
3434

35-
from enum import Enum
35+
from enum import StrEnum
3636

3737
__version__ = "2.3.0dev"
3838

3939

40-
class LearningType(str, Enum):
40+
class LearningType(StrEnum):
4141
"""Learning type defining how the model learns from the dataset samples.
4242
4343
This enum defines the different learning paradigms supported by anomalib models:
@@ -62,7 +62,7 @@ class LearningType(str, Enum):
6262
FEW_SHOT = "few_shot"
6363

6464

65-
class TaskType(str, Enum):
65+
class TaskType(StrEnum):
6666
"""Task type defining the model's prediction output format.
6767
6868
This enum defines the different task types supported by anomalib models:
@@ -88,7 +88,7 @@ class TaskType(str, Enum):
8888
SEGMENTATION = "segmentation"
8989

9090

91-
class PrecisionType(str, Enum):
91+
class PrecisionType(StrEnum):
9292
"""Precision type defining the numerical precision used in model computations.
9393
9494
This enum defines the different precision types supported by anomalib models:

src/anomalib/data/dataclasses/generic.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,9 @@
5353

5454

5555
Instance = TypeVar("Instance")
56-
Value = TypeVar("Value")
5756

5857

59-
class FieldDescriptor(Generic[Value]):
58+
class FieldDescriptor[Value]:
6059
"""Descriptor for Anomalib's dataclass fields.
6160
6261
Using a descriptor ensures that the values of dataclass fields can be
@@ -160,7 +159,7 @@ def is_optional(self, owner: type[Instance]) -> bool:
160159

161160

162161
@dataclass
163-
class _InputFields(Generic[T, ImageT, MaskT, PathT], ABC):
162+
class _InputFields(Generic[T, ImageT, MaskT, PathT], ABC): # noqa: UP046
164163
"""Generic dataclass that defines the standard input fields for Anomalib.
165164
166165
This abstract base class provides a structure for input data used in Anomalib.
@@ -258,7 +257,7 @@ def validate_gt_label(gt_label: T) -> T | None:
258257

259258

260259
@dataclass
261-
class _ImageInputFields(Generic[PathT], ABC):
260+
class _ImageInputFields(Generic[PathT], ABC): # noqa: UP046
262261
"""Generic dataclass for image-specific input fields in Anomalib.
263262
264263
This class extends standard input fields with an ``image_path`` attribute for
@@ -295,7 +294,7 @@ def validate_image_path(image_path: PathT) -> PathT | None:
295294

296295

297296
@dataclass
298-
class _VideoInputFields(Generic[T, ImageT, MaskT, PathT], ABC):
297+
class _VideoInputFields(Generic[T, ImageT, MaskT, PathT], ABC): # noqa: UP046
299298
"""Generic dataclass that defines the video input fields for Anomalib.
300299
301300
This class extends standard input fields with attributes specific to
@@ -411,7 +410,7 @@ def validate_last_frame(last_frame: T) -> T | None:
411410

412411

413412
@dataclass
414-
class _DepthInputFields(Generic[T, PathT], _ImageInputFields[PathT], ABC):
413+
class _DepthInputFields(Generic[T, PathT], _ImageInputFields[PathT], ABC): # noqa: UP046
415414
"""Generic dataclass that defines the depth input fields for Anomalib.
416415
417416
This class extends standard input fields with depth-specific attributes for
@@ -473,7 +472,7 @@ def validate_depth_path(depth_path: PathT) -> PathT | None:
473472

474473

475474
@dataclass
476-
class _OutputFields(Generic[T, MaskT, PathT], ABC):
475+
class _OutputFields(Generic[T, MaskT, PathT], ABC): # noqa: UP046
477476
"""Generic dataclass that defines the standard output fields for Anomalib.
478477
479478
This class defines the standard output fields used in Anomalib, including
@@ -640,7 +639,7 @@ def update(self, in_place: bool = True, **changes) -> Any: # noqa: ANN401
640639
@dataclass
641640
class _GenericItem(
642641
UpdateMixin,
643-
Generic[T, ImageT, MaskT, PathT],
642+
Generic[T, ImageT, MaskT, PathT], # noqa: UP046
644643
_OutputFields[T, MaskT, PathT],
645644
_InputFields[T, ImageT, MaskT, PathT],
646645
):
@@ -669,7 +668,7 @@ class _GenericItem(
669668
@dataclass
670669
class _GenericBatch(
671670
UpdateMixin,
672-
Generic[T, ImageT, MaskT, PathT],
671+
Generic[T, ImageT, MaskT, PathT], # noqa: UP046
673672
_OutputFields[T, MaskT, PathT],
674673
_InputFields[T, ImageT, MaskT, PathT],
675674
):
@@ -696,7 +695,7 @@ class _GenericBatch(
696695

697696

698697
@dataclass
699-
class BatchIterateMixin(Generic[ItemT]):
698+
class BatchIterateMixin(Generic[ItemT]): # noqa: UP046
700699
"""Mixin class for iterating over batches of items in Anomalib datasets.
701700
702701
This class provides functionality to iterate over individual items within a

src/anomalib/data/dataclasses/numpy/depth.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
(224, 224)
2727
"""
2828

29+
from collections.abc import Callable
2930
from dataclasses import dataclass
31+
from typing import ClassVar
3032

3133
import numpy as np
3234

@@ -65,6 +67,7 @@ class NumpyDepthItem(
6567
"""
6668

6769

70+
@dataclass
6871
class NumpyDepthBatch(
6972
BatchIterateMixin[NumpyDepthItem],
7073
NumpyDepthBatchValidator,
@@ -87,4 +90,4 @@ class NumpyDepthBatch(
8790
tensor-like fields.
8891
"""
8992

90-
item_class = NumpyDepthItem
93+
item_class: ClassVar[Callable] = NumpyDepthItem

src/anomalib/data/dataclasses/torch/base.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@
1313

1414
from collections.abc import Callable
1515
from dataclasses import dataclass, fields
16-
from typing import Any, ClassVar, Generic, NamedTuple, TypeVar
16+
from typing import Any, ClassVar, Generic, NamedTuple
1717

1818
import torch
1919
from torchvision.tv_tensors import Mask
2020

2121
from anomalib.data.dataclasses.generic import ImageT, _GenericBatch, _GenericItem
2222

23-
NumpyT = TypeVar("NumpyT")
24-
2523

2624
class InferenceBatch(NamedTuple):
2725
"""Batch for use in torch and inference models.
@@ -44,7 +42,7 @@ class InferenceBatch(NamedTuple):
4442

4543

4644
@dataclass
47-
class ToNumpyMixin(Generic[NumpyT]):
45+
class ToNumpyMixin[NumpyT]:
4846
"""Mixin for converting torch-based dataclasses to numpy.
4947
5048
This mixin provides functionality to convert PyTorch tensor data to numpy
@@ -103,7 +101,7 @@ def to_numpy(self) -> NumpyT:
103101

104102

105103
@dataclass
106-
class DatasetItem(Generic[ImageT], _GenericItem[torch.Tensor, ImageT, Mask, str]):
104+
class DatasetItem(Generic[ImageT], _GenericItem[torch.Tensor, ImageT, Mask, str]): # noqa: UP046
107105
"""Base dataclass for individual items in Anomalib datasets using PyTorch.
108106
109107
This class extends the generic ``_GenericItem`` class to provide a
@@ -122,7 +120,7 @@ class DatasetItem(Generic[ImageT], _GenericItem[torch.Tensor, ImageT, Mask, str]
122120

123121

124122
@dataclass
125-
class Batch(Generic[ImageT], _GenericBatch[torch.Tensor, ImageT, Mask, list[str]]):
123+
class Batch(Generic[ImageT], _GenericBatch[torch.Tensor, ImageT, Mask, list[str]]): # noqa: UP046
126124
"""Base dataclass for batches of items in Anomalib datasets using PyTorch.
127125
128126
This class extends the generic ``_GenericBatch`` class to provide a

src/anomalib/data/datamodules/depth/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
"""Anomalib Depth Data Modules."""
55

6-
from enum import Enum
6+
from enum import StrEnum
77

88
from .adam_3d import ADAM3D
99
from .folder_3d import Folder3D
1010
from .mvtec_3d import MVTec3D
1111

1212

13-
class DepthDataFormat(str, Enum):
13+
class DepthDataFormat(StrEnum):
1414
"""Supported Depth Dataset Types."""
1515

1616
MVTEC_3D = "mvtec_3d"

0 commit comments

Comments
 (0)