From f12542c7355e4790376a0a106974a9cc92454c06 Mon Sep 17 00:00:00 2001 From: Patrick Ogenstad Date: Fri, 4 Sep 2026 07:37:24 +0200 Subject: [PATCH 1/3] chore(deps): upgrade ty to 0.0.74 ty 0.0.14 was 60 releases behind, and no intermediate version lands clean -- even 0.0.15 reports 44 diagnostics. Two upstream changes account for nearly all of the 357: 0.0.17 began erroring when an attribute is missing on any member of a union, and 0.0.25 stopped reading bare mypy codes in `# type: ignore[...]` as ty suppressions. Six of those diagnostics were genuine imprecision and are fixed rather than suppressed. `dict[str, Any]` in the task manager and schema dropdown mutations becomes `dict[str, dict[str, Any]]`, since ty narrows a declaration to the assigned literal's shape and then rejects writes to sibling keys. The CLI's relationship store drops `dict[str, object]` for the `RelationshipManager` that node.py already declares it holds. The rest are recorded as scoped `[[tool.ty.overrides]]` entries with violation counts, matching how the repo already tracks incremental type debt. Every production diagnostic moved into config was already suppressed inline for mypy on the same line, so no signal is lost. No inline ty suppressions are introduced; the comment rule is updated to say so and to point at the config instead. Tooling-only: no runtime or public-API impact. --- .agents/rules/code-comments.md | 9 ++++- infrahub_sdk/ctl/object/update.py | 3 +- infrahub_sdk/schema/__init__.py | 4 +- infrahub_sdk/task/manager.py | 4 +- pyproject.toml | 65 ++++++++++++++++++++++++++++++- uv.lock | 45 ++++++++++----------- 6 files changed, 101 insertions(+), 29 deletions(-) diff --git a/.agents/rules/code-comments.md b/.agents/rules/code-comments.md index f1740c405..71bf49f29 100644 --- a/.agents/rules/code-comments.md +++ b/.agents/rules/code-comments.md @@ -17,4 +17,11 @@ Do not reference specs, tasks, plans, tickets, issue numbers, user stories, or t ## Type-ignore comments -Use the standard `# type: ignore[]` form (for example `# type: ignore[arg-type]`), never `# ty: ignore`. Only `# type: ignore[...]` is honored by mypy, pyright, and pytype, so a `# ty:` comment suppresses nothing and is dead. +Use the standard `# type: ignore[]` form (for example `# type: ignore[arg-type]`), never `# ty: ignore`. +Inline comments carry mypy codes only. + +`ty` does not read a bare mypy code as a suppression; it wants either `# ty: ignore[]` or a +`ty:`-prefixed code inside the standard brackets (`# type: ignore[arg-type, ty:invalid-argument-type]`). +Do not use either form. Remaining `ty` violations belong in `[[tool.ty.overrides]]` in `pyproject.toml`, +scoped to the narrowest file or glob that covers them and annotated with the violation count so they can be +retired incrementally. diff --git a/infrahub_sdk/ctl/object/update.py b/infrahub_sdk/ctl/object/update.py index cb4c79d7f..5228d33f7 100644 --- a/infrahub_sdk/ctl/object/update.py +++ b/infrahub_sdk/ctl/object/update.py @@ -24,6 +24,7 @@ if TYPE_CHECKING: from infrahub_sdk import InfrahubClient from infrahub_sdk.node import InfrahubNode + from infrahub_sdk.node.relationship import RelationshipManager from infrahub_sdk.schema import MainSchemaTypesAPI console = Console() @@ -205,7 +206,7 @@ def _apply_relationship( return # Cardinality many: access the RelationshipManager from internal storage - many_data: dict[str, object] = getattr(node, "_relationship_cardinality_many_data", {}) + many_data: dict[str, RelationshipManager] = getattr(node, "_relationship_cardinality_many_data", {}) rel_manager = many_data.get(key) if rel_manager is None or not hasattr(rel_manager, "peers"): return diff --git a/infrahub_sdk/schema/__init__.py b/infrahub_sdk/schema/__init__.py index 37658da37..fb2d5cddf 100644 --- a/infrahub_sdk/schema/__init__.py +++ b/infrahub_sdk/schema/__init__.py @@ -506,7 +506,7 @@ async def _mutate_dropdown_attribute( if schema_attr.kind != "Dropdown": raise ValueError(f"Attribute '{schema_attr.name}' is not of kind Dropdown") - input_data: dict[str, Any] = { + input_data: dict[str, dict[str, Any]] = { "data": { "kind": node_kind, "attribute": schema_attr.name, @@ -783,7 +783,7 @@ def _mutate_dropdown_attribute( if schema_attr.kind != "Dropdown": raise ValueError(f"Attribute '{schema_attr.name}' is not of kind Dropdown") - input_data: dict[str, Any] = { + input_data: dict[str, dict[str, Any]] = { "data": { "kind": node_kind, "attribute": schema_attr.name, diff --git a/infrahub_sdk/task/manager.py b/infrahub_sdk/task/manager.py index 59f17f869..feabf2c2c 100644 --- a/infrahub_sdk/task/manager.py +++ b/infrahub_sdk/task/manager.py @@ -28,7 +28,7 @@ def _generate_query( limit: int | None = None, count: bool = False, ) -> Query: - query: dict[str, Any] = { + query: dict[str, dict[str, Any]] = { "InfrahubTask": { "edges": { "node": { @@ -92,7 +92,7 @@ def _generate_query( @classmethod def _generate_count_query(cls, filters: TaskFilter | None = None) -> Query: - query: dict[str, Any] = { + query: dict[str, dict[str, Any]] = { "InfrahubTask": { "count": None, } diff --git a/pyproject.toml b/pyproject.toml index 7fc4dd69b..c2b16119e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,7 +98,7 @@ lint = [ "mypy==2.3.1", "ruff==0.15.12", "astroid>=3.1,<4.0", - "ty==0.0.14", + "ty==0.0.74", "rumdl==0.2.28", ] types = [ @@ -180,6 +180,40 @@ include = ["infrahub_sdk/node/node.py"] [tool.ty.overrides.rules] invalid-argument-type = "ignore" # 8 violations +unresolved-attribute = "ignore" # 22 violations - `_schema` is a union and only some members carry the attribute +unsupported-operator = "ignore" # 1 violation + +[[tool.ty.overrides]] +include = ["infrahub_sdk/pytest_plugin/**"] + +[tool.ty.overrides.rules] +unresolved-attribute = "ignore" # 35 violations - resource_config is a union of repository config element types + +[[tool.ty.overrides]] +include = ["infrahub_sdk/node/attribute.py"] + +[tool.ty.overrides.rules] +invalid-argument-type = "ignore" # 2 violations + +[[tool.ty.overrides]] +include = ["infrahub_sdk/config.py"] + +[tool.ty.overrides.rules] +invalid-return-type = "ignore" # 1 violation + +[[tool.ty.overrides]] +# Mirrors the module-level mypy `return-value` override for the same code. +include = ["infrahub_sdk/utils.py"] + +[tool.ty.overrides.rules] +invalid-return-type = "ignore" # 1 violation + +[[tool.ty.overrides]] +# Mirrors the module-level mypy `call-overload` override for the same code. +include = ["infrahub_sdk/ctl/check.py"] + +[tool.ty.overrides.rules] +no-matching-overload = "ignore" # 1 violation - `**filters` cannot be matched against `get()` overloads [[tool.ty.overrides]] @@ -200,6 +234,7 @@ include = ["tests/fixtures/**"] [tool.ty.overrides.rules] possibly-missing-attribute = "ignore" # Test fixtures use dynamic attributes +unresolved-attribute = "ignore" # 5 violations - fixtures use dynamic node attributes # Test-specific overrides - tests have more lenient type checking # Fix these incrementally, starting with files that have fewer violations @@ -237,6 +272,7 @@ invalid-argument-type = "ignore" # ~120 violations across integration tests invalid-assignment = "ignore" no-matching-overload = "ignore" possibly-missing-attribute = "ignore" # Tests use dynamic node attributes +unresolved-attribute = "ignore" # ~205 violations - `node..value` resolves to a union of attribute/relationship types [[tool.ty.overrides]] include = [ @@ -249,6 +285,7 @@ include = [ invalid-argument-type = "ignore" # 25 violations invalid-assignment = "ignore" possibly-missing-attribute = "ignore" +unresolved-attribute = "ignore" # 1 violation in test_client.py [[tool.ty.overrides]] include = [ @@ -261,6 +298,11 @@ include = [ "tests/unit/sdk/test_schema_sorter.py", "tests/unit/sdk/test_topological_sort.py", "tests/unit/sdk/test_schema_export.py", + "tests/unit/ctl/formatters/test_init.py", + "tests/unit/ctl/test_marketplace_app.py", + "tests/unit/sdk/test_file_handler.py", + "tests/unit/sdk/test_graph_traversal.py", + "tests/unit/sdk/test_store.py", ] [tool.ty.overrides.rules] @@ -268,6 +310,27 @@ invalid-argument-type = "ignore" # Remaining files with 1-5 violations each invalid-method-override = "ignore" no-matching-overload = "ignore" +[[tool.ty.overrides]] +include = ["tests/__init__.py", "tests/unit/__init__.py", "tests/unit/sdk/pool/test_allocate.py"] + +[tool.ty.overrides.rules] +unresolved-attribute = "ignore" # 5 violations - `builtins` is patched with rich helpers for tests + +[[tool.ty.overrides]] +include = ["tests/conftest.py", "tests/unit/sdk/test_file_object.py"] + +[tool.ty.overrides.rules] +invalid-assignment = "ignore" # 21 violations - assigning to `node..value` through a union + +[[tool.ty.overrides]] +include = ["tests/unit/sdk/test_priority.py"] + +[tool.ty.overrides.rules] +invalid-argument-type = "ignore" # 22 violations total +invalid-await = "ignore" +unknown-argument = "ignore" +unresolved-attribute = "ignore" + [[tool.ty.overrides]] include = ["docs/**"] diff --git a/uv.lock b/uv.lock index f5fdbaf11..31c23f504 100644 --- a/uv.lock +++ b/uv.lock @@ -896,7 +896,7 @@ dev = [ { name = "ruff", specifier = "==0.15.12" }, { name = "rumdl", specifier = "==0.2.28" }, { name = "towncrier", specifier = ">=24.8.0" }, - { name = "ty", specifier = "==0.0.14" }, + { name = "ty", specifier = "==0.0.74" }, { name = "types-python-slugify", specifier = ">=8.0.0.3" }, { name = "types-pyyaml", specifier = ">=6.0.12" }, { name = "types-ujson", specifier = ">=5.10" }, @@ -908,7 +908,7 @@ lint = [ { name = "mypy", specifier = "==2.3.1" }, { name = "ruff", specifier = "==0.15.12" }, { name = "rumdl", specifier = "==0.2.28" }, - { name = "ty", specifier = "==0.0.14" }, + { name = "ty", specifier = "==0.0.74" }, { name = "yamllint", specifier = ">=1.35" }, ] tests = [ @@ -2735,26 +2735,27 @@ wheels = [ [[package]] name = "ty" -version = "0.0.14" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/57/22c3d6bf95c2229120c49ffc2f0da8d9e8823755a1c3194da56e51f1cc31/ty-0.0.14.tar.gz", hash = "sha256:a691010565f59dd7f15cf324cdcd1d9065e010c77a04f887e1ea070ba34a7de2", size = 5036573, upload-time = "2026-01-27T00:57:31.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/99/cb/cc6d1d8de59beb17a41f9a614585f884ec2d95450306c173b3b7cc090d2e/ty-0.0.14-py3-none-linux_armv6l.whl", hash = "sha256:32cf2a7596e693094621d3ae568d7ee16707dce28c34d1762947874060fdddaa", size = 10034228, upload-time = "2026-01-27T00:57:53.133Z" }, - { url = "https://files.pythonhosted.org/packages/f3/96/dd42816a2075a8f31542296ae687483a8d047f86a6538dfba573223eaf9a/ty-0.0.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f971bf9805f49ce8c0968ad53e29624d80b970b9eb597b7cbaba25d8a18ce9a2", size = 9939162, upload-time = "2026-01-27T00:57:43.857Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b4/73c4859004e0f0a9eead9ecb67021438b2e8e5fdd8d03e7f5aca77623992/ty-0.0.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:45448b9e4806423523268bc15e9208c4f3f2ead7c344f615549d2e2354d6e924", size = 9418661, upload-time = "2026-01-27T00:58:03.411Z" }, - { url = "https://files.pythonhosted.org/packages/58/35/839c4551b94613db4afa20ee555dd4f33bfa7352d5da74c5fa416ffa0fd2/ty-0.0.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee94a9b747ff40114085206bdb3205a631ef19a4d3fb89e302a88754cbbae54c", size = 9837872, upload-time = "2026-01-27T00:57:23.718Z" }, - { url = "https://files.pythonhosted.org/packages/41/2b/bbecf7e2faa20c04bebd35fc478668953ca50ee5847ce23e08acf20ea119/ty-0.0.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6756715a3c33182e9ab8ffca2bb314d3c99b9c410b171736e145773ee0ae41c3", size = 9848819, upload-time = "2026-01-27T00:57:58.501Z" }, - { url = "https://files.pythonhosted.org/packages/be/60/3c0ba0f19c0f647ad9d2b5b5ac68c0f0b4dc899001bd53b3a7537fb247a2/ty-0.0.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89d0038a2f698ba8b6fec5cf216a4e44e2f95e4a5095a8c0f57fe549f87087c2", size = 10324371, upload-time = "2026-01-27T00:57:29.291Z" }, - { url = "https://files.pythonhosted.org/packages/24/32/99d0a0b37d0397b0a989ffc2682493286aa3bc252b24004a6714368c2c3d/ty-0.0.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c64a83a2d669b77f50a4957039ca1450626fb474619f18f6f8a3eb885bf7544", size = 10865898, upload-time = "2026-01-27T00:57:33.542Z" }, - { url = "https://files.pythonhosted.org/packages/1a/88/30b583a9e0311bb474269cfa91db53350557ebec09002bfc3fb3fc364e8c/ty-0.0.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:242488bfb547ef080199f6fd81369ab9cb638a778bb161511d091ffd49c12129", size = 10555777, upload-time = "2026-01-27T00:58:05.853Z" }, - { url = "https://files.pythonhosted.org/packages/cd/a2/cb53fb6325dcf3d40f2b1d0457a25d55bfbae633c8e337bde8ec01a190eb/ty-0.0.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4790c3866f6c83a4f424fc7d09ebdb225c1f1131647ba8bdc6fcdc28f09ed0ff", size = 10412913, upload-time = "2026-01-27T00:57:38.834Z" }, - { url = "https://files.pythonhosted.org/packages/42/8f/f2f5202d725ed1e6a4e5ffaa32b190a1fe70c0b1a2503d38515da4130b4c/ty-0.0.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:950f320437f96d4ea9a2332bbfb5b68f1c1acd269ebfa4c09b6970cc1565bd9d", size = 9837608, upload-time = "2026-01-27T00:57:55.898Z" }, - { url = "https://files.pythonhosted.org/packages/f7/ba/59a2a0521640c489dafa2c546ae1f8465f92956fede18660653cce73b4c5/ty-0.0.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4a0ec3ee70d83887f86925bbc1c56f4628bd58a0f47f6f32ddfe04e1f05466df", size = 9884324, upload-time = "2026-01-27T00:57:46.786Z" }, - { url = "https://files.pythonhosted.org/packages/03/95/8d2a49880f47b638743212f011088552ecc454dd7a665ddcbdabea25772a/ty-0.0.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1a4e6b6da0c58b34415955279eff754d6206b35af56a18bb70eb519d8d139ef", size = 10033537, upload-time = "2026-01-27T00:58:01.149Z" }, - { url = "https://files.pythonhosted.org/packages/e9/40/4523b36f2ce69f92ccf783855a9e0ebbbd0f0bb5cdce6211ee1737159ed3/ty-0.0.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dc04384e874c5de4c5d743369c277c8aa73d1edea3c7fc646b2064b637db4db3", size = 10495910, upload-time = "2026-01-27T00:57:26.691Z" }, - { url = "https://files.pythonhosted.org/packages/08/d5/655beb51224d1bfd4f9ddc0bb209659bfe71ff141bcf05c418ab670698f0/ty-0.0.14-py3-none-win32.whl", hash = "sha256:b20e22cf54c66b3e37e87377635da412d9a552c9bf4ad9fc449fed8b2e19dad2", size = 9507626, upload-time = "2026-01-27T00:57:41.43Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d9/c569c9961760e20e0a4bc008eeb1415754564304fd53997a371b7cf3f864/ty-0.0.14-py3-none-win_amd64.whl", hash = "sha256:e312ff9475522d1a33186657fe74d1ec98e4a13e016d66f5758a452c90ff6409", size = 10437980, upload-time = "2026-01-27T00:57:36.422Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/186829654f5bfd9a028f6648e9caeb11271960a61de97484627d24443f91/ty-0.0.14-py3-none-win_arm64.whl", hash = "sha256:b6facdbe9b740cb2c15293a1d178e22ffc600653646452632541d01c36d5e378", size = 9885831, upload-time = "2026-01-27T00:57:49.747Z" }, +version = "0.0.74" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/0f/c767853e88567a2ec7e996dd95e3105b1bc62c95d103689311ef0f4a603c/ty-0.0.74.tar.gz", hash = "sha256:da14344fc8625fc9ff359bafb856ad575636ea86d9bb6a629b146bff27b380e6", size = 6786318, upload-time = "2026-08-22T15:05:54.054Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/95/6ded58bc97885c6d88fa1f9cd815031489200738f961cbf0466663213f80/ty-0.0.74-py3-none-linux_armv6l.whl", hash = "sha256:8969ef4e508debf00cf58f9ea85a539f799b1732c59cdfcecd037630b9755b30", size = 12790043, upload-time = "2026-08-22T15:05:05.015Z" }, + { url = "https://files.pythonhosted.org/packages/d9/8a/5e323603b6ab8731144421877ee8a0f8ac5a5511e67857127caa09f6730e/ty-0.0.74-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:51fb6cf5b98e1e1140825b2430943f78d744876a735231656eafbb4c3f7eca3c", size = 12371748, upload-time = "2026-08-22T15:05:08.609Z" }, + { url = "https://files.pythonhosted.org/packages/d0/44/ee72e08cb705281e8d8c42917dd577aa598a8a098008495fda5176ee3f6e/ty-0.0.74-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ebe60b1f0a948c793d6c77fc9e9ddda599e4f023c04ab16e8e03bcb428c3fa0", size = 12282403, upload-time = "2026-08-22T15:05:11.448Z" }, + { url = "https://files.pythonhosted.org/packages/da/b3/fd935b694ff68bc278af50f7ad04770b36ce6306399baef7e1847b553a9d/ty-0.0.74-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa97f407a695c890a53615966a663c7d2167e2cabe88db7ca1a24d62635cdfc8", size = 12345164, upload-time = "2026-08-22T15:05:14.19Z" }, + { url = "https://files.pythonhosted.org/packages/54/5c/5b5825268e029ebb164c909780103dbbae367f069801410068bf1cef29b3/ty-0.0.74-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:673ddb733d4a0db31385ba1ed9ff1f6bd9dc5565413ce57b1ca5ac4c7803da5d", size = 12556646, upload-time = "2026-08-22T15:05:16.994Z" }, + { url = "https://files.pythonhosted.org/packages/56/e7/515914e571d62ce0101744fed3f881936eeb1b30dc37beb72b4f7ca1e289/ty-0.0.74-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1028e7c6b4f6145e9704552f43a5fffdcd51b42263ffdcd9c9677762bc395a4a", size = 13311653, upload-time = "2026-08-22T15:05:20.254Z" }, + { url = "https://files.pythonhosted.org/packages/b0/07/d1452babb6f9266c2122cabc095180b70ed306fb770b2996753814d2237d/ty-0.0.74-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79841a8890493021fb308772474983316eb91f7b56cb227a6a05a06b262a36f0", size = 13768284, upload-time = "2026-08-22T15:05:23.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/60/8d4a2fc7842a47210a1cb0a16a187d9de39ad5d509a00fb74c1c073afcde/ty-0.0.74-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94859d321f3c6a6c8f7bfc3f40e8319cda7e6e012e613440f3dfd145d5010e2e", size = 13422306, upload-time = "2026-08-22T15:05:26.248Z" }, + { url = "https://files.pythonhosted.org/packages/de/76/ebbc269a8c4efcc4d44624993bd188145f20d60ebda9680b15aaec42cc50/ty-0.0.74-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:970a8b2c09ff3be04c8a1c6767332d861be4fce85efe7bb205e4ade7c8655274", size = 12970637, upload-time = "2026-08-22T15:05:29.15Z" }, + { url = "https://files.pythonhosted.org/packages/9e/dd/b99f7236acbf856780ca1779a48143d2d9f2c24d7f531a0ce15a022b8a87/ty-0.0.74-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:795f763b3ded85574c2c2846a6fb8acf2aa76e9e83d761143e92b1f0c7ffa2cd", size = 13344891, upload-time = "2026-08-22T15:05:32.033Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/9ff7449a4c7e6428f2c6f298e74cf24b70668f29d45c249507a723ff3782/ty-0.0.74-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:dc086db5367d912c31c0cc872deb7387290e779a4b9b54fcb944673a7cd52c7b", size = 12395272, upload-time = "2026-08-22T15:05:34.702Z" }, + { url = "https://files.pythonhosted.org/packages/b1/dd/b23a5b6b35d37df89dc8dc5daa09efd9245a668b50c4c81c25de21567dc1/ty-0.0.74-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0314d7b391cf684e47c2fa093d2ce4c597cfc9b01d9a315fe204aed6359b271b", size = 12573079, upload-time = "2026-08-22T15:05:37.683Z" }, + { url = "https://files.pythonhosted.org/packages/23/c5/ccba16239d6129533c8b3603458d0f4dd2ba69478e47059073968e74261d/ty-0.0.74-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4a45dd2e991e8bdae82ba78c8cd051b253f60bc71a6536598fa3ef580b4fc9b", size = 12832506, upload-time = "2026-08-22T15:05:40.505Z" }, + { url = "https://files.pythonhosted.org/packages/6d/1c/2390912634dff4f341f97b397f2aee341ff062be0a66cda37d59375454f2/ty-0.0.74-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:210e2eac6b018fb934e2b8dac3956a0ba076a3fb1fa6f135058c825e5b759b81", size = 13154752, upload-time = "2026-08-22T15:05:43.355Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/a8c12188227e6f74f91853a7374e01ed81d6ad21c16c8b70e92dbebfe46a/ty-0.0.74-py3-none-win32.whl", hash = "sha256:db0bb6a8f098ef9bd1be861f73b4f7c0320d40d4c05c7ae0a8677d4e7aa4f6e5", size = 12130002, upload-time = "2026-08-22T15:05:46.058Z" }, + { url = "https://files.pythonhosted.org/packages/21/5c/064f28ccb9c234cfce5a2f7aa69a256663d5ae5bb0290b3a9706cc4d1e4c/ty-0.0.74-py3-none-win_amd64.whl", hash = "sha256:bebff181515255b3c78bd2e7693ae66fab6064ad4feea2065c68bc01022aa678", size = 12771435, upload-time = "2026-08-22T15:05:48.811Z" }, + { url = "https://files.pythonhosted.org/packages/fe/06/d6becdaca0315346c26b6df97cb0eafa81de4f870945d6989e88704374ed/ty-0.0.74-py3-none-win_arm64.whl", hash = "sha256:1a3469eaaf8c85b1c0a15bede25d36daea4b09fce1d913e965b24e24b3f1d6c6", size = 12558299, upload-time = "2026-08-22T15:05:51.543Z" }, ] [[package]] From 8e2615741408a274fc91d88ebe8b41e1f7f2744b Mon Sep 17 00:00:00 2001 From: Patrick Ogenstad Date: Mon, 7 Sep 2026 10:35:21 +0200 Subject: [PATCH 2/3] chore(deps): suppress ty unresolved-import for the tomli fallback `tests/unit/test_packaging_metadata.py` landed on infrahub-develop after this branch was cut. It falls back to `import tomli as tomllib` below Python 3.11, the same pattern `infrahub_sdk/ctl/config.py` already uses, and carries a `# type: ignore[import-not-found]` for mypy. ty 0.0.14 read that bare mypy code as a blanket suppression, so the import error never surfaced. 0.0.25 stopped doing so, which is why the merge fails `ty check` while infrahub-develop is green. Verified by running both versions against the same tree: 0.0.14 passes, 0.0.74 reports the unresolved import. `tomli` is declared `python_version<'3.11'`, so it is genuinely absent from the 3.12 environment CI checks with; the import is unreachable there. Add the file to the existing `unresolved-import` override rather than annotate it inline. --- pyproject.toml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c2b16119e..27889eaa4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -217,10 +217,13 @@ no-matching-overload = "ignore" # 1 violation - `**filters` cannot be matched ag [[tool.ty.overrides]] -include = ["infrahub_sdk/ctl/config.py"] +# Both files fall back to `import tomli as tomllib` below Python 3.11. `tomli` is declared as a +# `python_version<'3.11'` dependency, so it is absent from the environment ty checks with and the +# import cannot resolve. Retire alongside Python 3.10 support. +include = ["infrahub_sdk/ctl/config.py", "tests/unit/test_packaging_metadata.py"] [tool.ty.overrides.rules] -unresolved-import = "ignore" # import tomli as tomllib when running on later versions of Python +unresolved-import = "ignore" [[tool.ty.overrides]] From 9cee5b950598f5ad1006161ec63819b87e707f22 Mon Sep 17 00:00:00 2001 From: Patrick Ogenstad Date: Mon, 7 Sep 2026 11:04:17 +0200 Subject: [PATCH 3/3] docs: clarify why the tomli import cannot resolve State the mechanism directly: the dependency marker keeps tomli out of site-packages on newer interpreters, which is what ty resolves against. --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 27889eaa4..72d7503df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -217,9 +217,9 @@ no-matching-overload = "ignore" # 1 violation - `**filters` cannot be matched ag [[tool.ty.overrides]] -# Both files fall back to `import tomli as tomllib` below Python 3.11. `tomli` is declared as a -# `python_version<'3.11'` dependency, so it is absent from the environment ty checks with and the -# import cannot resolve. Retire alongside Python 3.10 support. +# Both files fall back to `import tomli as tomllib` below Python 3.11. The `tomli` dependency is +# marked `python_version<'3.11'`, so on a newer interpreter it is absent from site-packages and ty +# cannot resolve the import. Retire alongside Python 3.10 support. include = ["infrahub_sdk/ctl/config.py", "tests/unit/test_packaging_metadata.py"] [tool.ty.overrides.rules]