From 4bb5cb51495ebb0b9a74e19c7883582c34d1e701 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Sat, 26 Oct 2024 23:49:48 -0300 Subject: [PATCH] misc: Initial addition of IGDB typehints The short-term goal is to completely typehint the IGDB API responses. This first change adds the base structures and enums RomM currently uses. The `ExpandableField` type will allow us to model the expansion mechanism the IGDB API provides, where a field can include either an ID, or the full nested structure. --- .trunk/trunk.yaml | 2 +- backend/adapters/services/igdb_types.py | 286 +++++++++++++++++++++++ backend/handler/metadata/igdb_handler.py | 6 +- poetry.lock | 66 +++--- pyproject.toml | 2 +- 5 files changed, 326 insertions(+), 36 deletions(-) create mode 100644 backend/adapters/services/igdb_types.py diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index 1564f2ea3..1b01f49fe 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -26,7 +26,7 @@ lint: - checkov@3.2.239 - git-diff-check - isort@5.13.2 - - mypy@1.11.2 + - mypy@1.13.0 - osv-scanner@1.8.4 - oxipng@9.1.2 - prettier@3.3.3 diff --git a/backend/adapters/services/igdb_types.py b/backend/adapters/services/igdb_types.py new file mode 100644 index 000000000..5315b37a0 --- /dev/null +++ b/backend/adapters/services/igdb_types.py @@ -0,0 +1,286 @@ +from __future__ import annotations + +import enum +from typing import NewType, TypedDict + +# https://api-docs.igdb.com/#expander +type ExpandableField[T] = T | int + +# TODO: Add missing structures until all are implemented. +UnimplementedEntity = NewType("UnimplementedEntity", dict) +AgeRatingContentDescription = UnimplementedEntity +AlternativeName = UnimplementedEntity +Artwork = UnimplementedEntity +CollectionRelation = UnimplementedEntity +CollectionType = UnimplementedEntity +Cover = UnimplementedEntity +ExternalGame = UnimplementedEntity +Franchise = UnimplementedEntity +GameEngine = UnimplementedEntity +GameLocalization = UnimplementedEntity +GameMode = UnimplementedEntity +Genre = UnimplementedEntity +InvolvedCompany = UnimplementedEntity +Keyword = UnimplementedEntity +LanguageSupport = UnimplementedEntity +MultiplayerMode = UnimplementedEntity +PlatformFamily = UnimplementedEntity +PlatformLogo = UnimplementedEntity +PlatformVersionCompany = UnimplementedEntity +PlatformVersionReleaseDate = UnimplementedEntity +PlatformWebsite = UnimplementedEntity +PlayerPerspective = UnimplementedEntity +ReleaseDate = UnimplementedEntity +TagNumber = UnimplementedEntity +Theme = UnimplementedEntity +Website = UnimplementedEntity + + +class IGDBEntity(TypedDict): + """Base class for all IGDB entities. + + All IGDB entities include an ID field. They must inherit from this class, and set `total=False` + in the class definition, as they only include the `fields` requested in the API query. + """ + + id: int + + +# https://api-docs.igdb.com/#age-rating-enums +class AgeRatingCategory(enum.IntEnum): + ESRB = 1 + PEGI = 2 + CERO = 3 + USK = 4 + GRAC = 5 + CLASS_IND = 6 + ACB = 7 + + +# https://api-docs.igdb.com/#age-rating-enums +class AgeRatingRating(enum.IntEnum): + THREE = 1 + SEVEN = 2 + TWELVE = 3 + SIXTEEN = 4 + EIGHTEEN = 5 + RP = 6 + EC = 7 + E = 8 + E10 = 9 + T = 10 + M = 11 + AO = 12 + CERO_A = 13 + CERO_B = 14 + CERO_C = 15 + CERO_D = 16 + CERO_Z = 17 + USK_0 = 18 + USK_6 = 19 + USK_12 = 20 + USK_16 = 21 + USK_18 = 22 + GRAC_ALL = 23 + GRAC_TWELVE = 24 + GRAC_FIFTEEN = 25 + GRAC_EIGHTEEN = 26 + GRAC_TESTING = 27 + CLASS_IND_L = 28 + CLASS_IND_TEN = 29 + CLASS_IND_TWELVE = 30 + CLASS_IND_FOURTEEN = 31 + CLASS_IND_SIXTEEN = 32 + CLASS_IND_EIGHTEEN = 33 + ACB_G = 34 + ACB_PG = 35 + ACB_M = 36 + ACB_MA15 = 37 + ACB_R18 = 38 + ACB_RC = 39 + + +# https://api-docs.igdb.com/#age-rating +class AgeRating(IGDBEntity, total=False): + category: AgeRatingCategory + checksum: str # uuid + content_descriptions: list[ExpandableField[AgeRatingContentDescription]] + rating: AgeRatingRating + rating_cover_url: str + synopsis: str + + +# https://api-docs.igdb.com/#collection +class Collection(IGDBEntity, total=False): + as_child_relations: list[ExpandableField[CollectionRelation]] + as_parent_relations: list[ExpandableField[CollectionRelation]] + checksum: str # uuid + created_at: int # timestamp + games: list[ExpandableField[Game]] + name: str + slug: str + type: ExpandableField[CollectionType] + updated_at: int # timestamp + url: str + + +# https://api-docs.igdb.com/#game-enums +class GameCategory(enum.IntEnum): + MAIN_GAME = 0 + DLC_ADDON = 1 + EXPANSION = 2 + BUNDLE = 3 + STANDALONE_EXPANSION = 4 + MOD = 5 + EPISODE = 6 + SEASON = 7 + REMAKE = 8 + REMASTER = 9 + EXPANDED_GAME = 10 + PORT = 11 + FORK = 12 + PACK = 13 + UPDATE = 14 + + +# https://api-docs.igdb.com/#game-enums +class GameStatus(enum.IntEnum): + RELEASED = 0 + ALPHA = 2 + BETA = 3 + EARLY_ACCESS = 4 + OFFLINE = 5 + CANCELLED = 6 + RUMORED = 7 + DELISTED = 8 + + +# https://api-docs.igdb.com/#game +class Game(IGDBEntity, total=False): + age_ratings: list[ExpandableField[AgeRating]] + aggregated_rating: float + aggregated_rating_count: int + alternative_names: list[ExpandableField[AlternativeName]] + artworks: list[ExpandableField[Artwork]] + bundles: list[ExpandableField[Game]] + category: GameCategory + checksum: str # uuid + collections: list[ExpandableField[Collection]] + cover: ExpandableField[Cover] + created_at: int # timestamp + dlcs: list[ExpandableField[Game]] + expanded_games: list[ExpandableField[Game]] + expansions: list[ExpandableField[Game]] + external_games: list[ExpandableField[ExternalGame]] + first_release_date: int # timestamp + forks: list[ExpandableField[Game]] + franchise: ExpandableField[Franchise] + franchises: list[ExpandableField[Franchise]] + game_engines: list[ExpandableField[GameEngine]] + game_localizations: list[ExpandableField[GameLocalization]] + game_modes: list[ExpandableField[GameMode]] + genres: list[ExpandableField[Genre]] + hypes: int + involved_companies: list[ExpandableField[InvolvedCompany]] + keywords: list[ExpandableField[Keyword]] + language_supports: list[ExpandableField[LanguageSupport]] + multiplayer_modes: list[ExpandableField[MultiplayerMode]] + name: str + parent_game: ExpandableField[Game] + platforms: list[ExpandableField[Platform]] + player_perspectives: list[ExpandableField[PlayerPerspective]] + ports: list[ExpandableField[Game]] + rating: float + rating_count: int + release_dates: list[ExpandableField[ReleaseDate]] + remakes: list[ExpandableField[Game]] + remasters: list[ExpandableField[Game]] + screenshots: list[ExpandableField[Screenshot]] + similar_games: list[ExpandableField[Game]] + slug: str + standalone_expansions: list[ExpandableField[Game]] + status: GameStatus + storyline: str + summary: str + tags: list[TagNumber] + themes: list[ExpandableField[Theme]] + total_rating: float + total_rating_count: int + updated_at: int # timestamp + url: str + version_parent: ExpandableField[Game] + version_title: str + videos: list[ExpandableField[GameVideo]] + websites: list[ExpandableField[Website]] + + +# https://api-docs.igdb.com/#game-video +class GameVideo(IGDBEntity, total=False): + checksum: str # uuid + game: ExpandableField[Game] + name: str + video_id: str + + +# https://api-docs.igdb.com/#platform-enums +class PlatformCategory(enum.IntEnum): + CONSOLE = 1 + ARCADE = 2 + PLATFORM = 3 + OPERATING_SYSTEM = 4 + PORTABLE_CONSOLE = 5 + COMPUTER = 6 + + +# https://api-docs.igdb.com/#platform +class Platform(IGDBEntity, total=False): + abbreviation: str + alternative_name: str + category: PlatformCategory + checksum: str # uuid + created_at: int # timestamp + generation: int + name: str + platform_family: ExpandableField[PlatformFamily] + platform_logo: ExpandableField[PlatformLogo] + slug: str + summary: str + updated_at: int # timestamp + url: str + versions: list[ExpandableField[PlatformVersion]] + websites: list[ExpandableField[PlatformWebsite]] + + +# https://api-docs.igdb.com/#platform-version +class PlatformVersion(IGDBEntity, total=False): + checksum: str # uuid + companies: list[ExpandableField[PlatformVersionCompany]] + connectivity: str + cpu: str + graphics: str + main_manufacturer: ExpandableField[PlatformVersionCompany] + media: str + memory: str + name: str + os: str + output: str + platform_logo: ExpandableField[PlatformLogo] + platform_version_release_dates: list[ExpandableField[PlatformVersionReleaseDate]] + resolutions: str + slug: str + sound: str + storage: str + summary: str + url: str + + +# https://api-docs.igdb.com/#screenshot +class Screenshot(IGDBEntity, total=False): + alpha_channel: bool + animated: bool + checksum: str # uuid + game: ExpandableField[Game] + height: int + image_id: str + url: str + width: int diff --git a/backend/handler/metadata/igdb_handler.py b/backend/handler/metadata/igdb_handler.py index 7cd5db801..1d72b69b3 100644 --- a/backend/handler/metadata/igdb_handler.py +++ b/backend/handler/metadata/igdb_handler.py @@ -5,6 +5,7 @@ import httpx import pydash +from adapters.services.igdb_types import GameCategory from config import IGDB_CLIENT_ID, IGDB_CLIENT_SECRET, IS_PYTEST_RUN from fastapi import HTTPException, status from handler.redis_handler import sync_cache @@ -23,9 +24,6 @@ # Used to display the IGDB API status in the frontend IGDB_API_ENABLED: Final = bool(IGDB_CLIENT_ID) and bool(IGDB_CLIENT_SECRET) -MAIN_GAME_CATEGORY: Final = 0 -EXPANDED_GAME_CATEGORY: Final = 10 -N_SCREENSHOTS: Final = 5 PS1_IGDB_ID: Final = 7 PS2_IGDB_ID: Final = 8 PSP_IGDB_ID: Final = 38 @@ -274,7 +272,7 @@ async def _search_rom( search_term = uc(search_term) category_filter: str = ( - f"& (category={MAIN_GAME_CATEGORY} | category={EXPANDED_GAME_CATEGORY})" + f"& (category={GameCategory.MAIN_GAME} | category={GameCategory.EXPANDED_GAME})" if with_category else "" ) diff --git a/poetry.lock b/poetry.lock index 362b6a402..bf6141a69 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1214,46 +1214,52 @@ type = ["mypy", "mypy-extensions"] [[package]] name = "mypy" -version = "1.10.1" +version = "1.13.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e36f229acfe250dc660790840916eb49726c928e8ce10fbdf90715090fe4ae02"}, - {file = "mypy-1.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:51a46974340baaa4145363b9e051812a2446cf583dfaeba124af966fa44593f7"}, - {file = "mypy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:901c89c2d67bba57aaaca91ccdb659aa3a312de67f23b9dfb059727cce2e2e0a"}, - {file = "mypy-1.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0cd62192a4a32b77ceb31272d9e74d23cd88c8060c34d1d3622db3267679a5d9"}, - {file = "mypy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:a2cbc68cb9e943ac0814c13e2452d2046c2f2b23ff0278e26599224cf164e78d"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bd6f629b67bb43dc0d9211ee98b96d8dabc97b1ad38b9b25f5e4c4d7569a0c6a"}, - {file = "mypy-1.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1bbb3a6f5ff319d2b9d40b4080d46cd639abe3516d5a62c070cf0114a457d84"}, - {file = "mypy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8edd4e9bbbc9d7b79502eb9592cab808585516ae1bcc1446eb9122656c6066f"}, - {file = "mypy-1.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6166a88b15f1759f94a46fa474c7b1b05d134b1b61fca627dd7335454cc9aa6b"}, - {file = "mypy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:5bb9cd11c01c8606a9d0b83ffa91d0b236a0e91bc4126d9ba9ce62906ada868e"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d8681909f7b44d0b7b86e653ca152d6dff0eb5eb41694e163c6092124f8246d7"}, - {file = "mypy-1.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:378c03f53f10bbdd55ca94e46ec3ba255279706a6aacaecac52ad248f98205d3"}, - {file = "mypy-1.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bacf8f3a3d7d849f40ca6caea5c055122efe70e81480c8328ad29c55c69e93e"}, - {file = "mypy-1.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:701b5f71413f1e9855566a34d6e9d12624e9e0a8818a5704d74d6b0402e66c04"}, - {file = "mypy-1.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:3c4c2992f6ea46ff7fce0072642cfb62af7a2484efe69017ed8b095f7b39ef31"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:604282c886497645ffb87b8f35a57ec773a4a2721161e709a4422c1636ddde5c"}, - {file = "mypy-1.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37fd87cab83f09842653f08de066ee68f1182b9b5282e4634cdb4b407266bade"}, - {file = "mypy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8addf6313777dbb92e9564c5d32ec122bf2c6c39d683ea64de6a1fd98b90fe37"}, - {file = "mypy-1.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cc3ca0a244eb9a5249c7c583ad9a7e881aa5d7b73c35652296ddcdb33b2b9c7"}, - {file = "mypy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:1b3a2ffce52cc4dbaeee4df762f20a2905aa171ef157b82192f2e2f368eec05d"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe85ed6836165d52ae8b88f99527d3d1b2362e0cb90b005409b8bed90e9059b3"}, - {file = "mypy-1.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c2ae450d60d7d020d67ab440c6e3fae375809988119817214440033f26ddf7bf"}, - {file = "mypy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6be84c06e6abd72f960ba9a71561c14137a583093ffcf9bbfaf5e613d63fa531"}, - {file = "mypy-1.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2189ff1e39db399f08205e22a797383613ce1cb0cb3b13d8bcf0170e45b96cc3"}, - {file = "mypy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:97a131ee36ac37ce9581f4220311247ab6cba896b4395b9c87af0675a13a755f"}, - {file = "mypy-1.10.1-py3-none-any.whl", hash = "sha256:71d8ac0b906354ebda8ef1673e5fde785936ac1f29ff6987c7483cfbd5a4235a"}, - {file = "mypy-1.10.1.tar.gz", hash = "sha256:1f8f492d7db9e3593ef42d4f115f04e556130f2819ad33ab84551403e97dd4c0"}, + {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, + {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, + {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, + {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, + {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, + {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, + {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, + {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, + {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, + {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, + {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, + {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, + {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, + {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, + {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, + {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, + {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, + {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, + {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, + {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, + {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, + {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, + {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, + {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, + {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, + {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, + {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, + {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, + {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, + {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, + {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, + {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] reports = ["lxml"] @@ -3362,4 +3368,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "1383ee0e5eb84115038aad232d280808237f5f43c3b85c06264369fd3a34dc20" +content-hash = "3ceb6142076c34c62e83aecf590af01085d0a692eafab4654fe4c158040dff56" diff --git a/pyproject.toml b/pyproject.toml index 0c0f4e0f3..474aa3eda 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,5 +55,5 @@ pytest-recording = "^0.13" [tool.poetry.group.dev.dependencies] ipdb = "^0.13.13" -mypy = "^1.10.0" +mypy = "^1.13" ipykernel = "^6.29.4"