From 29a1fdb19a604b2ee3212e92cac1f4976e9d0c4a Mon Sep 17 00:00:00 2001 From: worldmozara Date: Thu, 9 Jul 2026 18:34:24 +0800 Subject: [PATCH] feat/stubgen: make type hints more specific --- pyproject.toml | 2 -- src/capnp_stubgen/gen_interface.py | 8 +++----- src/capnp_stubgen/gen_struct.py | 21 +++++++++++++++------ src/capnp_stubgen/type_resolver.py | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2006584..46fde8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,8 +44,6 @@ reportImportCycles = "hint" # Downgraded to hint for capnp to_dict() dynamic data patterns reportUnknownVariableType = "hint" -reportUnknownArgumentType = "hint" reportUnknownMemberType = "hint" -reportUnknownParameterType = "hint" reportAny = "hint" reportExplicitAny = "hint" diff --git a/src/capnp_stubgen/gen_interface.py b/src/capnp_stubgen/gen_interface.py index 80d73f0..835872f 100644 --- a/src/capnp_stubgen/gen_interface.py +++ b/src/capnp_stubgen/gen_interface.py @@ -74,8 +74,6 @@ def generate_interface( "result_info": result_info, }) - emitter.add_typing_import("Any") - # ── Main interface class ─────────────────────────────────────────── emitter.begin_class(name) @@ -106,7 +104,7 @@ def generate_interface( emitter.begin_class(client_name, bases=[name]) emitter.add_method( "_new_client", - params=["self", "server: Any"], + params=["self", f"server: {name}Server"], return_type=client_name, ) emitter.end_class() @@ -121,8 +119,8 @@ def generate_interface( emitter.add_method( mname, - params=["self", f"_params: {param_type}", "_context: Any"], - return_type=None, + params=["self", f"_params: {param_type}", "_context: object"], + return_type="None", ) emitter.end_class() diff --git a/src/capnp_stubgen/gen_struct.py b/src/capnp_stubgen/gen_struct.py index 04dbbdc..7798f1e 100644 --- a/src/capnp_stubgen/gen_struct.py +++ b/src/capnp_stubgen/gen_struct.py @@ -123,7 +123,8 @@ def generate_struct( _generate_union_methods(emitter, union_fields) # Factory methods + to_dict - _generate_factory_methods(emitter, qbuilder, qreader) + _generate_factory_methods(emitter, qbuilder, qreader, non_union_fields) + emitter.add_typing_import("Any") emitter.add_method("to_dict", params=["self"], return_type="dict[str, Any]") emitter.end_class() @@ -242,15 +243,23 @@ def _generate_union_methods( def _generate_factory_methods( - emitter: Emitter, qbuilder: str, qreader: str + emitter: Emitter, + qbuilder: str, + qreader: str, + non_union_fields: list[tuple[str, str]], ) -> None: - emitter.add_typing_import("Any") emitter.add_typing_import("Generator", "collections.abc") emitter.add_typing_import("contextmanager", "contextlib") emitter.add_blank_line() + # Typed kwargs: name: str = ..., age: int = ... + if non_union_fields: + kwargs = [f"{name}: {typ} = ..." for name, typ in non_union_fields] + else: + emitter.add_typing_import("Any") + kwargs = ["**kwargs: Any"] emitter.add_static_method( - "new_message", params=["**kwargs: Any"], return_type=qbuilder, + "new_message", params=kwargs, return_type=qbuilder, ) emitter.add_blank_line() @@ -298,6 +307,6 @@ def _generate_builder_methods( emitter.add_blank_line() emitter.add_typing_import("IO", "typing") - emitter.add_static_method("write", params=["file: IO[bytes]"]) + emitter.add_static_method("write", params=["file: IO[bytes]"], return_type="None") emitter.add_blank_line() - emitter.add_static_method("write_packed", params=["file: IO[bytes]"]) + emitter.add_static_method("write_packed", params=["file: IO[bytes]"], return_type="None") diff --git a/src/capnp_stubgen/type_resolver.py b/src/capnp_stubgen/type_resolver.py index 9131bdb..013d539 100644 --- a/src/capnp_stubgen/type_resolver.py +++ b/src/capnp_stubgen/type_resolver.py @@ -132,7 +132,7 @@ def _resolve_any_pointer( if "parameter" in ap_dict: # Look up the generic parameter name from the parent scope scope_id = type_id_to_int(ap_dict["parameter"]["scopeId"]) - param_index = ap_dict["parameter"]["parameterIndex"] + param_index: int = ap_dict["parameter"]["parameterIndex"] info = registry.get(scope_id) if info is not None and param_index < len(info.generic_params): return PythonType(name=info.generic_params[param_index])