diff --git a/.github/workflows/python-x402-a2a.yml b/.github/workflows/python-x402-a2a.yml index 8651a81..40369c0 100644 --- a/.github/workflows/python-x402-a2a.yml +++ b/.github/workflows/python-x402-a2a.yml @@ -33,3 +33,6 @@ jobs: - name: Format run: uvx ruff format --check . + + - name: Typecheck + run: uv run typecheck diff --git a/python/examples/adk-demo/client_agent/client_agent.py b/python/examples/adk-demo/client_agent/client_agent.py index 17057c7..afd48b1 100644 --- a/python/examples/adk-demo/client_agent/client_agent.py +++ b/python/examples/adk-demo/client_agent/client_agent.py @@ -36,7 +36,7 @@ from ._remote_agent_connection import RemoteAgentConnections, TaskUpdateCallback from .wallet import Wallet from x402_a2a.core.utils import x402Utils -from x402_a2a.types import PaymentStatus +from x402_a2a.type_defs import PaymentStatus logger = logging.getLogger(__name__) diff --git a/python/examples/adk-demo/client_agent/wallet.py b/python/examples/adk-demo/client_agent/wallet.py index 951015e..55d56b4 100644 --- a/python/examples/adk-demo/client_agent/wallet.py +++ b/python/examples/adk-demo/client_agent/wallet.py @@ -14,7 +14,7 @@ from abc import ABC, abstractmethod import eth_account -from x402_a2a.types import PaymentPayload, x402PaymentRequiredResponse +from x402_a2a.type_defs import PaymentPayload, x402PaymentRequiredResponse from x402_a2a.core.wallet import process_payment_required diff --git a/python/examples/adk-demo/server/agents/_adk_agent_executor.py b/python/examples/adk-demo/server/agents/_adk_agent_executor.py index 3dce97a..7ceb247 100644 --- a/python/examples/adk-demo/server/agents/_adk_agent_executor.py +++ b/python/examples/adk-demo/server/agents/_adk_agent_executor.py @@ -36,7 +36,7 @@ from google.genai import types from x402_a2a.core.utils import x402Utils -from x402_a2a.types import x402PaymentRequiredException +from x402_a2a.type_defs import x402PaymentRequiredException logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) diff --git a/python/examples/adk-demo/server/agents/adk_merchant_agent.py b/python/examples/adk-demo/server/agents/adk_merchant_agent.py index 8851af4..b7c7766 100644 --- a/python/examples/adk-demo/server/agents/adk_merchant_agent.py +++ b/python/examples/adk-demo/server/agents/adk_merchant_agent.py @@ -18,11 +18,11 @@ from google.adk.agents import LlmAgent from google.adk.agents.callback_context import CallbackContext from google.genai import types -from x402_a2a.types import PaymentRequirements +from x402_a2a.type_defs import PaymentRequirements # Import the custom exception and the base agent interface from .base_agent import BaseAgent -from x402_a2a.types import x402PaymentRequiredException +from x402_a2a.type_defs import x402PaymentRequiredException from x402_a2a import x402Utils, get_extension_declaration # This is the new, clean ADK Merchant Agent. diff --git a/python/examples/adk-demo/server/agents/mock_facilitator.py b/python/examples/adk-demo/server/agents/mock_facilitator.py index 756f9be..0c8d00a 100644 --- a/python/examples/adk-demo/server/agents/mock_facilitator.py +++ b/python/examples/adk-demo/server/agents/mock_facilitator.py @@ -14,7 +14,7 @@ import logging from typing import override -from x402_a2a.types import ( +from x402_a2a.type_defs import ( ExactPaymentPayload, PaymentPayload, PaymentRequirements, diff --git a/python/examples/adk-demo/server/agents/x402_merchant_executor.py b/python/examples/adk-demo/server/agents/x402_merchant_executor.py index 3a9b95d..3e34f37 100644 --- a/python/examples/adk-demo/server/agents/x402_merchant_executor.py +++ b/python/examples/adk-demo/server/agents/x402_merchant_executor.py @@ -20,7 +20,7 @@ from x402_a2a.executors import x402ServerExecutor from .mock_facilitator import MockFacilitator -from x402_a2a.types import ( +from x402_a2a.type_defs import ( PaymentPayload, PaymentRequirements, SettleResponse, diff --git a/python/examples/adk-demo/uv.lock b/python/examples/adk-demo/uv.lock index 5453fd8..7d54caf 100644 --- a/python/examples/adk-demo/uv.lock +++ b/python/examples/adk-demo/uv.lock @@ -60,7 +60,7 @@ requires-dist = [ { name = "uvicorn", specifier = ">=0.34.2" }, { name = "web3", specifier = ">=7.10.0" }, { name = "x402", specifier = ">=0.1.4" }, - { name = "x402-a2a", editable = "../../../python/x402_a2a" }, + { name = "x402-a2a", editable = "../../x402_a2a" }, ] [package.metadata.requires-dev] @@ -2714,7 +2714,7 @@ wheels = [ [[package]] name = "x402-a2a" version = "1.0.0" -source = { editable = "../../../python/x402_a2a" } +source = { editable = "../../x402_a2a" } dependencies = [ { name = "a2a-sdk" }, { name = "eth-account" }, @@ -2742,7 +2742,10 @@ dev = [ { name = "pytest-mock", specifier = ">=3.14.1" }, { name = "trio", specifier = ">=0.22.0" }, ] -lint = [{ name = "ruff", specifier = ">=0.13.1" }] +lint = [ + { name = "mypy", specifier = ">=1.8.0" }, + { name = "ruff", specifier = ">=0.13.1" }, +] [[package]] name = "yarl" diff --git a/python/x402_a2a/__init__.py b/python/x402_a2a/__init__.py index 8e7fd37..986f0c9 100644 --- a/python/x402_a2a/__init__.py +++ b/python/x402_a2a/__init__.py @@ -31,7 +31,7 @@ from x402.facilitator import FacilitatorConfig, FacilitatorClient # A2A Extension Types & Functions -from .types import ( +from .type_defs import ( # Extension Constants X402_EXTENSION_URI, # A2A-Specific Types diff --git a/python/x402_a2a/core/agent.py b/python/x402_a2a/core/agent.py index 93c3783..a092467 100644 --- a/python/x402_a2a/core/agent.py +++ b/python/x402_a2a/core/agent.py @@ -16,7 +16,7 @@ from typing import List, Optional from a2a.types import AgentCard, AgentCapabilities -from ..types import x402ExtensionConfig, get_extension_declaration +from ..type_defs import x402ExtensionConfig, get_extension_declaration def create_x402_agent_card( diff --git a/python/x402_a2a/core/helpers.py b/python/x402_a2a/core/helpers.py index e4c2d37..65469da 100644 --- a/python/x402_a2a/core/helpers.py +++ b/python/x402_a2a/core/helpers.py @@ -16,7 +16,7 @@ from typing import Union, Optional, List, Callable, Any from functools import wraps -from ..types import x402PaymentRequiredException, PaymentRequirements, TokenAmount +from ..type_defs import x402PaymentRequiredException, PaymentRequirements, TokenAmount from .merchant import create_payment_requirements diff --git a/python/x402_a2a/core/merchant.py b/python/x402_a2a/core/merchant.py index a41af5f..fdd88b3 100644 --- a/python/x402_a2a/core/merchant.py +++ b/python/x402_a2a/core/merchant.py @@ -16,7 +16,7 @@ from typing import Optional, Any, cast from x402.common import process_price_to_atomic_amount from x402.types import Price -from ..types import PaymentRequirements, SupportedNetworks +from ..type_defs import PaymentRequirements, SupportedNetworks def create_payment_requirements( diff --git a/python/x402_a2a/core/protocol.py b/python/x402_a2a/core/protocol.py index 738e75d..8e41bd9 100644 --- a/python/x402_a2a/core/protocol.py +++ b/python/x402_a2a/core/protocol.py @@ -15,7 +15,7 @@ from typing import Optional -from ..types import ( +from ..type_defs import ( PaymentPayload, PaymentRequirements, SettleResponse, diff --git a/python/x402_a2a/core/utils.py b/python/x402_a2a/core/utils.py index 45841a5..dd5e6ad 100644 --- a/python/x402_a2a/core/utils.py +++ b/python/x402_a2a/core/utils.py @@ -16,7 +16,7 @@ import logging import uuid from typing import Optional -from ..types import ( +from ..type_defs import ( Task, Message, PaymentStatus, @@ -181,7 +181,7 @@ def create_payment_required_task( # Ensure task has a status message for metadata if not hasattr(task.status, "message") or not task.status.message: - from ..types import Message + from ..type_defs import Message from a2a.types import TextPart task.status.message = Message( @@ -215,7 +215,7 @@ def record_payment_verified( """Record payment verification in task metadata.""" # Ensure task has a status message for metadata if not hasattr(task.status, "message") or not task.status.message: - from ..types import Message + from ..type_defs import Message from a2a.types import TextPart task.status.message = Message( @@ -243,7 +243,7 @@ def record_payment_success( """Record successful payment with settlement response.""" # Ensure task has a status message for metadata if not hasattr(task.status, "message") or not task.status.message: - from ..types import Message + from ..type_defs import Message from a2a.types import TextPart task.status.message = Message( @@ -280,7 +280,7 @@ def record_payment_failure( """Record payment failure with error details.""" # Ensure task has a status message for metadata if not hasattr(task.status, "message") or not task.status.message: - from ..types import Message + from ..type_defs import Message from a2a.types import TextPart task.status.message = Message( diff --git a/python/x402_a2a/core/wallet.py b/python/x402_a2a/core/wallet.py index 7fd87ae..73e260e 100644 --- a/python/x402_a2a/core/wallet.py +++ b/python/x402_a2a/core/wallet.py @@ -19,7 +19,7 @@ from x402.common import x402_VERSION from x402.exact import prepare_payment_header, sign_payment_header, decode_payment -from ..types import ( +from ..type_defs import ( PaymentRequirements, x402PaymentRequiredResponse, PaymentPayload, diff --git a/python/x402_a2a/executors/base.py b/python/x402_a2a/executors/base.py index 32b14a6..aa3bc2f 100644 --- a/python/x402_a2a/executors/base.py +++ b/python/x402_a2a/executors/base.py @@ -15,7 +15,7 @@ from abc import ABC, abstractmethod -from ..types import ( +from ..type_defs import ( AgentExecutor, RequestContext, EventQueue, diff --git a/python/x402_a2a/executors/client.py b/python/x402_a2a/executors/client.py index 5283dde..2466511 100644 --- a/python/x402_a2a/executors/client.py +++ b/python/x402_a2a/executors/client.py @@ -17,7 +17,7 @@ from eth_account import Account from .base import x402BaseExecutor -from ..types import ( +from ..type_defs import ( AgentExecutor, RequestContext, EventQueue, @@ -99,7 +99,7 @@ async def _auto_pay(self, task, event_queue: EventQueue): except Exception as e: # Payment processing failed - from ..types import SettleResponse, x402ErrorCode + from ..type_defs import SettleResponse, x402ErrorCode failure_response = SettleResponse( success=False, network="base", error_reason=f"Payment failed: {e}" diff --git a/python/x402_a2a/executors/server.py b/python/x402_a2a/executors/server.py index 7197f32..272e5c8 100644 --- a/python/x402_a2a/executors/server.py +++ b/python/x402_a2a/executors/server.py @@ -20,7 +20,7 @@ from a2a.server.tasks import TaskUpdater from .base import x402BaseExecutor -from ..types import ( +from ..type_defs import ( AgentExecutor, RequestContext, EventQueue, diff --git a/python/x402_a2a/extension.py b/python/x402_a2a/extension.py index 5b24b02..544718b 100644 --- a/python/x402_a2a/extension.py +++ b/python/x402_a2a/extension.py @@ -13,7 +13,7 @@ # limitations under the License. """Extension declaration and constants for A2A x402 protocol.""" -from .types.config import X402_EXTENSION_URI +from .type_defs.config import X402_EXTENSION_URI def get_extension_declaration( diff --git a/python/x402_a2a/pyproject.toml b/python/x402_a2a/pyproject.toml index c660f10..5ac1137 100644 --- a/python/x402_a2a/pyproject.toml +++ b/python/x402_a2a/pyproject.toml @@ -28,17 +28,19 @@ dev = [ ] lint = [ "ruff>=0.13.1", + "mypy>=1.8.0", ] [project.scripts] test = "pytest:main" +typecheck = "mypy.main:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -force-include = { "__init__.py" = "x402_a2a/__init__.py", "core" = "x402_a2a/core", "executors" = "x402_a2a/executors", "types" = "x402_a2a/types", "extension.py" = "x402_a2a/extension.py" } +force-include = { "__init__.py" = "x402_a2a/__init__.py", "core" = "x402_a2a/core", "executors" = "x402_a2a/executors", "type_defs" = "x402_a2a/type_defs", "extension.py" = "x402_a2a/extension.py" } [tool.hatch.metadata] allow-direct-references = true @@ -56,3 +58,6 @@ markers = [ [tool.ruff] target-version = "py311" + +[tool.mypy] +files = ["core", "executors", "*.py"] diff --git a/python/x402_a2a/tests/test_core.py b/python/x402_a2a/tests/test_core.py index 16001db..3d31ad7 100644 --- a/python/x402_a2a/tests/test_core.py +++ b/python/x402_a2a/tests/test_core.py @@ -16,7 +16,7 @@ from a2a.types import Task, Message, TaskState, TaskStatus, TextPart from x402_a2a.executors.server import x402ServerExecutor -from x402_a2a.types import ( +from x402_a2a.type_defs import ( PaymentStatus, x402Metadata, x402PaymentRequiredResponse, diff --git a/python/x402_a2a/types/__init__.py b/python/x402_a2a/type_defs/__init__.py similarity index 100% rename from python/x402_a2a/types/__init__.py rename to python/x402_a2a/type_defs/__init__.py diff --git a/python/x402_a2a/types/config.py b/python/x402_a2a/type_defs/config.py similarity index 100% rename from python/x402_a2a/types/config.py rename to python/x402_a2a/type_defs/config.py diff --git a/python/x402_a2a/types/errors.py b/python/x402_a2a/type_defs/errors.py similarity index 98% rename from python/x402_a2a/types/errors.py rename to python/x402_a2a/type_defs/errors.py index d079762..4e9f45b 100644 --- a/python/x402_a2a/types/errors.py +++ b/python/x402_a2a/type_defs/errors.py @@ -54,7 +54,7 @@ class x402PaymentRequiredException(x402Error): requirements instead of relying on static server configuration. Example: - from x402_a2a.types.errors import x402PaymentRequiredException + from x402_a2a.type_defs.errors import x402PaymentRequiredException from x402_a2a.core.merchant import create_payment_requirements # Single payment option diff --git a/python/x402_a2a/types/state.py b/python/x402_a2a/type_defs/state.py similarity index 100% rename from python/x402_a2a/types/state.py rename to python/x402_a2a/type_defs/state.py diff --git a/python/x402_a2a/uv.lock b/python/x402_a2a/uv.lock index 6b419ce..6223c06 100644 --- a/python/x402_a2a/uv.lock +++ b/python/x402_a2a/uv.lock @@ -1097,6 +1097,53 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/69/b547032297c7e63ba2af494edba695d781af8a0c6e89e4d06cf848b21d80/multidict-6.6.4-py3-none-any.whl", hash = "sha256:27d8f8e125c07cb954e54d75d04905a9bba8a439c1d84aca94949d4d03d8601c", size = 12313, upload-time = "2025-08-11T12:08:46.891Z" }, ] +[[package]] +name = "mypy" +version = "1.18.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/77/8f0d0001ffad290cef2f7f216f96c814866248a0b92a722365ed54648e7e/mypy-1.18.2.tar.gz", hash = "sha256:06a398102a5f203d7477b2923dda3634c36727fa5c237d8f859ef90c42a9924b", size = 3448846, upload-time = "2025-09-19T00:11:10.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/87/cafd3ae563f88f94eec33f35ff722d043e09832ea8530ef149ec1efbaf08/mypy-1.18.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:807d9315ab9d464125aa9fcf6d84fde6e1dc67da0b6f80e7405506b8ac72bc7f", size = 12731198, upload-time = "2025-09-19T00:09:44.857Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e0/1e96c3d4266a06d4b0197ace5356d67d937d8358e2ee3ffac71faa843724/mypy-1.18.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:776bb00de1778caf4db739c6e83919c1d85a448f71979b6a0edd774ea8399341", size = 11817879, upload-time = "2025-09-19T00:09:47.131Z" }, + { url = "https://files.pythonhosted.org/packages/72/ef/0c9ba89eb03453e76bdac5a78b08260a848c7bfc5d6603634774d9cd9525/mypy-1.18.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1379451880512ffce14505493bd9fe469e0697543717298242574882cf8cdb8d", size = 12427292, upload-time = "2025-09-19T00:10:22.472Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/ec4a061dd599eb8179d5411d99775bec2a20542505988f40fc2fee781068/mypy-1.18.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1331eb7fd110d60c24999893320967594ff84c38ac6d19e0a76c5fd809a84c86", size = 13163750, upload-time = "2025-09-19T00:09:51.472Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5f/2cf2ceb3b36372d51568f2208c021870fe7834cf3186b653ac6446511839/mypy-1.18.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ca30b50a51e7ba93b00422e486cbb124f1c56a535e20eff7b2d6ab72b3b2e37", size = 13351827, upload-time = "2025-09-19T00:09:58.311Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7d/2697b930179e7277529eaaec1513f8de622818696857f689e4a5432e5e27/mypy-1.18.2-cp311-cp311-win_amd64.whl", hash = "sha256:664dc726e67fa54e14536f6e1224bcfce1d9e5ac02426d2326e2bb4e081d1ce8", size = 9757983, upload-time = "2025-09-19T00:10:09.071Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/dfdd2bc60c66611dd8335f463818514733bc763e4760dee289dcc33df709/mypy-1.18.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33eca32dd124b29400c31d7cf784e795b050ace0e1f91b8dc035672725617e34", size = 12908273, upload-time = "2025-09-19T00:10:58.321Z" }, + { url = "https://files.pythonhosted.org/packages/81/14/6a9de6d13a122d5608e1a04130724caf9170333ac5a924e10f670687d3eb/mypy-1.18.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3c47adf30d65e89b2dcd2fa32f3aeb5e94ca970d2c15fcb25e297871c8e4764", size = 11920910, upload-time = "2025-09-19T00:10:20.043Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a9/b29de53e42f18e8cc547e38daa9dfa132ffdc64f7250e353f5c8cdd44bee/mypy-1.18.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d6c838e831a062f5f29d11c9057c6009f60cb294fea33a98422688181fe2893", size = 12465585, upload-time = "2025-09-19T00:10:33.005Z" }, + { url = "https://files.pythonhosted.org/packages/77/ae/6c3d2c7c61ff21f2bee938c917616c92ebf852f015fb55917fd6e2811db2/mypy-1.18.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01199871b6110a2ce984bde85acd481232d17413868c9807e95c1b0739a58914", size = 13348562, upload-time = "2025-09-19T00:10:11.51Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/aec68ab3b4aebdf8f36d191b0685d99faa899ab990753ca0fee60fb99511/mypy-1.18.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a2afc0fa0b0e91b4599ddfe0f91e2c26c2b5a5ab263737e998d6817874c5f7c8", size = 13533296, upload-time = "2025-09-19T00:10:06.568Z" }, + { url = "https://files.pythonhosted.org/packages/9f/83/abcb3ad9478fca3ebeb6a5358bb0b22c95ea42b43b7789c7fb1297ca44f4/mypy-1.18.2-cp312-cp312-win_amd64.whl", hash = "sha256:d8068d0afe682c7c4897c0f7ce84ea77f6de953262b12d07038f4d296d547074", size = 9828828, upload-time = "2025-09-19T00:10:28.203Z" }, + { url = "https://files.pythonhosted.org/packages/5f/04/7f462e6fbba87a72bc8097b93f6842499c428a6ff0c81dd46948d175afe8/mypy-1.18.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:07b8b0f580ca6d289e69209ec9d3911b4a26e5abfde32228a288eb79df129fcc", size = 12898728, upload-time = "2025-09-19T00:10:01.33Z" }, + { url = "https://files.pythonhosted.org/packages/99/5b/61ed4efb64f1871b41fd0b82d29a64640f3516078f6c7905b68ab1ad8b13/mypy-1.18.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ed4482847168439651d3feee5833ccedbf6657e964572706a2adb1f7fa4dfe2e", size = 11910758, upload-time = "2025-09-19T00:10:42.607Z" }, + { url = "https://files.pythonhosted.org/packages/3c/46/d297d4b683cc89a6e4108c4250a6a6b717f5fa96e1a30a7944a6da44da35/mypy-1.18.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3ad2afadd1e9fea5cf99a45a822346971ede8685cc581ed9cd4d42eaf940986", size = 12475342, upload-time = "2025-09-19T00:11:00.371Z" }, + { url = "https://files.pythonhosted.org/packages/83/45/4798f4d00df13eae3bfdf726c9244bcb495ab5bd588c0eed93a2f2dd67f3/mypy-1.18.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a431a6f1ef14cf8c144c6b14793a23ec4eae3db28277c358136e79d7d062f62d", size = 13338709, upload-time = "2025-09-19T00:11:03.358Z" }, + { url = "https://files.pythonhosted.org/packages/d7/09/479f7358d9625172521a87a9271ddd2441e1dab16a09708f056e97007207/mypy-1.18.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ab28cc197f1dd77a67e1c6f35cd1f8e8b73ed2217e4fc005f9e6a504e46e7ba", size = 13529806, upload-time = "2025-09-19T00:10:26.073Z" }, + { url = "https://files.pythonhosted.org/packages/71/cf/ac0f2c7e9d0ea3c75cd99dff7aec1c9df4a1376537cb90e4c882267ee7e9/mypy-1.18.2-cp313-cp313-win_amd64.whl", hash = "sha256:0e2785a84b34a72ba55fb5daf079a1003a34c05b22238da94fcae2bbe46f3544", size = 9833262, upload-time = "2025-09-19T00:10:40.035Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0c/7d5300883da16f0063ae53996358758b2a2df2a09c72a5061fa79a1f5006/mypy-1.18.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:62f0e1e988ad41c2a110edde6c398383a889d95b36b3e60bcf155f5164c4fdce", size = 12893775, upload-time = "2025-09-19T00:10:03.814Z" }, + { url = "https://files.pythonhosted.org/packages/50/df/2cffbf25737bdb236f60c973edf62e3e7b4ee1c25b6878629e88e2cde967/mypy-1.18.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8795a039bab805ff0c1dfdb8cd3344642c2b99b8e439d057aba30850b8d3423d", size = 11936852, upload-time = "2025-09-19T00:10:51.631Z" }, + { url = "https://files.pythonhosted.org/packages/be/50/34059de13dd269227fb4a03be1faee6e2a4b04a2051c82ac0a0b5a773c9a/mypy-1.18.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6ca1e64b24a700ab5ce10133f7ccd956a04715463d30498e64ea8715236f9c9c", size = 12480242, upload-time = "2025-09-19T00:11:07.955Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/040983fad5132d85914c874a2836252bbc57832065548885b5bb5b0d4359/mypy-1.18.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d924eef3795cc89fecf6bedc6ed32b33ac13e8321344f6ddbf8ee89f706c05cb", size = 13326683, upload-time = "2025-09-19T00:09:55.572Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ba/89b2901dd77414dd7a8c8729985832a5735053be15b744c18e4586e506ef/mypy-1.18.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20c02215a080e3a2be3aa50506c67242df1c151eaba0dcbc1e4e557922a26075", size = 13514749, upload-time = "2025-09-19T00:10:44.827Z" }, + { url = "https://files.pythonhosted.org/packages/25/bc/cc98767cffd6b2928ba680f3e5bc969c4152bf7c2d83f92f5a504b92b0eb/mypy-1.18.2-cp314-cp314-win_amd64.whl", hash = "sha256:749b5f83198f1ca64345603118a6f01a4e99ad4bf9d103ddc5a3200cc4614adf", size = 9982959, upload-time = "2025-09-19T00:10:37.344Z" }, + { url = "https://files.pythonhosted.org/packages/87/e3/be76d87158ebafa0309946c4a73831974d4d6ab4f4ef40c3b53a385a66fd/mypy-1.18.2-py3-none-any.whl", hash = "sha256:22a1748707dd62b58d2ae53562ffc4d7f8bcc727e8ac7cbc69c053ddc874d47e", size = 2352367, upload-time = "2025-09-19T00:10:15.489Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + [[package]] name = "outcome" version = "1.3.0.post0" @@ -1130,6 +1177,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/aa/0f/c8b64d9b54ea631fcad4e9e3c8dbe8c11bb32a623be94f22974c88e71eaf/parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f", size = 48427, upload-time = "2022-09-03T17:01:13.814Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -2196,6 +2252,7 @@ dev = [ { name = "trio" }, ] lint = [ + { name = "mypy" }, { name = "ruff" }, ] @@ -2216,7 +2273,10 @@ dev = [ { name = "pytest-mock", specifier = ">=3.14.1" }, { name = "trio", specifier = ">=0.22.0" }, ] -lint = [{ name = "ruff", specifier = ">=0.13.1" }] +lint = [ + { name = "mypy", specifier = ">=1.8.0" }, + { name = "ruff", specifier = ">=0.13.1" }, +] [[package]] name = "yarl"