Skip to content

testing #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
853cb17
Import raw stubs from grpc-stubs package
shabbyrobe Dec 27, 2023
b3dd7ca
Format grpc stubs
shabbyrobe Dec 27, 2023
775a418
Fix ruff lints
shabbyrobe Dec 27, 2023
241b0e1
Migrate tests from grpc-stubs
shabbyrobe Dec 27, 2023
5eadd4f
Convert docstrings to comments
shabbyrobe Dec 27, 2023
1c09ab4
Default argument warnings, missing generics
shabbyrobe Dec 27, 2023
505d234
Add TypeAlias
shabbyrobe Dec 27, 2023
7a7cf61
Update typing.Callable to collections.abc.Callable
shabbyrobe Dec 27, 2023
0a228f8
Update more typings to collections.abcs
shabbyrobe Dec 27, 2023
1e31e62
Add underscore to typevars
shabbyrobe Dec 27, 2023
18b3d7d
Silence remaining typing failures
shabbyrobe Dec 27, 2023
15811e6
Paper over cracks in supplemental packages
shabbyrobe Dec 27, 2023
59fb630
Add ABC and ABCMeta to classes that declare it in the grpcio source
shabbyrobe Dec 27, 2023
0ac8415
Add check for alternate aio import
shabbyrobe Dec 28, 2023
82d02fb
Move grpc stubs into grpcio folder
shabbyrobe Dec 28, 2023
9993e8d
Add abstractmethod decorator to grpc.Call
shabbyrobe Dec 28, 2023
be40720
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 28, 2023
5b3e698
Fix a bunch of stubtest issues
shabbyrobe Dec 28, 2023
05e2e99
Merge branch 'main' into grpc-stubs
srittau Apr 14, 2024
811304e
Merge branch 'main' into grpc-stubs
JelleZijlstra Oct 2, 2024
8f9ae2a
Merge branch 'main' into grpc-stubs
Avasam Feb 14, 2025
177bd44
Remove unnecessary assertion
shabbyrobe Feb 22, 2025
4678c7c
Remove unnecessary assertion
shabbyrobe Feb 22, 2025
a75a853
Lint fixes
Avasam Feb 22, 2025
1290473
Merge pull request #1 from Avasam/grpc-stubs-lint-fixes
shabbyrobe Feb 24, 2025
4d8a9d5
resolve subtest issues
macro1 Mar 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyrightconfig.stricter.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"stubs/gdb",
"stubs/geopandas",
"stubs/google-cloud-ndb",
"stubs/grpcio/grpc/__init__.pyi",
"stubs/hdbcli/hdbcli/dbapi.pyi",
"stubs/html5lib",
"stubs/httplib2",
Expand Down
34 changes: 34 additions & 0 deletions stubs/grpcio/@tests/stubtest_allowlist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Error: is not present at runtime
# =============================
# Classes introduced in the typing library to provide interface structure.
grpc.Behaviour
grpc.CallFuture
grpc.CallIterator
grpc.CertificateChainPair
grpc.Interceptor
grpc.Metadata
grpc.RequestDeserializer
grpc.RequestSerializer
grpc.ResponseDeserializer
grpc.ResponseSerializer
grpc.RpcError.code
grpc.RpcError.details
grpc.RpcError.trailing_metadata
grpc.aio.DoneCallback
grpc.aio.DoneCallbackType
grpc.aio.EOFType
grpc.aio.InterceptedCall
grpc.aio.MetadataKey
grpc.aio.MetadataType
grpc.aio.MetadataValue
grpc.aio.MetadatumType
grpc.aio.RequestSerializer
grpc.aio.ResponseDeserializer
grpc_health.v1.health.SendResponseCallback
grpc_reflection.v1alpha.reflection.AnyServer
grpc_reflection.v1alpha.reflection.AnyServicerContext

# Error: is inconsistent
# =============================
# Stub class is incomplete.
grpc_reflection.v1alpha._base.BaseReflectionServicer.__init__
27 changes: 27 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_aio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import annotations

import typing
from typing_extensions import assert_type

import grpc.aio

assert_type(grpc.aio.Server(), grpc.aio.Server) # type: ignore[abstract]

# Interceptor casts
client_interceptors = [typing.cast(grpc.aio.ClientInterceptor, "interceptor")]
grpc.aio.insecure_channel("target", interceptors=client_interceptors)

server_interceptors = [typing.cast(grpc.aio.ServerInterceptor[typing.Any, typing.Any], "interceptor")]
grpc.aio.server(interceptors=server_interceptors)


# Metadata
async def metadata() -> None:
metadata = await typing.cast(grpc.aio.Call, None).initial_metadata()
assert_type(metadata["foo"], grpc.aio.MetadataValue)
for k in metadata:
assert_type(k, str)

for k, v in metadata.items():
assert_type(k, str)
assert_type(v, grpc.aio.MetadataValue)
37 changes: 37 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_aio_multi_callable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations

import typing
from typing_extensions import assert_type

import grpc.aio


class DummyRequest:
pass


class DummyReply:
pass


class DummyServiceStub(typing.Protocol):
UnaryUnary: grpc.aio.UnaryUnaryMultiCallable[DummyRequest, DummyReply]
UnaryStream: grpc.aio.UnaryStreamMultiCallable[DummyRequest, DummyReply]
StreamUnary: grpc.aio.StreamUnaryMultiCallable[DummyRequest, DummyReply]
StreamStream: grpc.aio.StreamStreamMultiCallable[DummyRequest, DummyReply]


stub: DummyServiceStub = typing.cast(typing.Any, None)
req = DummyRequest()


async def async_context() -> None:
assert_type(await stub.UnaryUnary(req), DummyReply)

async for resp in stub.UnaryStream(req):
assert_type(resp, DummyReply)

assert_type(await stub.StreamUnary(iter([req])), DummyReply)

async for resp in stub.StreamStream(iter([req])):
assert_type(resp, DummyReply)
8 changes: 8 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_aio_via_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from __future__ import annotations

from typing_extensions import assert_type

# Both import methods work, see the comment in grpc/__init__.py.
from grpc import aio

assert_type(aio.Server(), aio.Server) # type: ignore[abstract]
46 changes: 46 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from __future__ import annotations

import typing
from typing_extensions import assert_type

import grpc

# Channel options:
assert_type(grpc.insecure_channel("target", ()), grpc.Channel)
assert_type(grpc.insecure_channel("target", (("a", "b"),)), grpc.Channel)
assert_type(grpc.insecure_channel("target", (("a", "b"), ("c", "d"))), grpc.Channel)

# Local channel credentials:
creds = grpc.local_channel_credentials(grpc.LocalConnectionType.LOCAL_TCP)
assert_type(creds, grpc.ChannelCredentials)

# Other credential types:
assert_type(grpc.alts_channel_credentials(), grpc.ChannelCredentials)
assert_type(grpc.alts_server_credentials(), grpc.ServerCredentials)
assert_type(grpc.compute_engine_channel_credentials(typing.cast(typing.Any, None)), grpc.ChannelCredentials)
assert_type(grpc.insecure_server_credentials(), grpc.ServerCredentials)

# XDS credentials:
assert_type(
grpc.xds_channel_credentials(grpc.local_channel_credentials(grpc.LocalConnectionType.LOCAL_TCP)), grpc.ChannelCredentials
)
assert_type(grpc.xds_server_credentials(grpc.insecure_server_credentials()), grpc.ServerCredentials)

# Channel ready future
channel = grpc.insecure_channel("target", ())
assert_type(grpc.channel_ready_future(channel).result(), None)

# Channel options supports list:
assert_type(grpc.insecure_channel("target", []), grpc.Channel)
assert_type(grpc.insecure_channel("target", [("a", "b")]), grpc.Channel)
assert_type(grpc.insecure_channel("target", [("a", "b"), ("c", "d")]), grpc.Channel)

# Client call details optionals:
call_details = grpc.ClientCallDetails()
assert_type(call_details.method, str)
assert_type(call_details.timeout, typing.Optional[float])

# Call iterator
call_iter: grpc.CallIterator[str] = typing.cast(typing.Any, None)
for call in call_iter:
assert_type(call, str)
36 changes: 36 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_handler_inheritance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from __future__ import annotations

import typing
from typing_extensions import assert_type

import grpc


class Request:
pass


class Response:
pass


def unary_unary_call(rq: Request, ctx: grpc.ServicerContext) -> Response:
assert_type(rq, Request)
return Response()


class ServiceHandler(grpc.ServiceRpcHandler[Request, Response]):
def service_name(self) -> str:
return "hello"

def service(self, handler_call_details: grpc.HandlerCallDetails) -> grpc.RpcMethodHandler[Request, Response] | None:
rpc = grpc.RpcMethodHandler[Request, Response]()
rpc.unary_unary = unary_unary_call
return rpc


h = ServiceHandler()
ctx = typing.cast(grpc.ServicerContext, None)
svc = h.service(grpc.HandlerCallDetails())
if svc is not None and svc.unary_unary is not None:
svc.unary_unary(Request(), ctx)
35 changes: 35 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_multi_callable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

import typing
from typing_extensions import assert_type

import grpc


class DummyRequest:
pass


class DummyReply:
pass


class DummyServiceStub(typing.Protocol):
UnaryUnary: grpc.UnaryUnaryMultiCallable[DummyRequest, DummyReply]
UnaryStream: grpc.UnaryStreamMultiCallable[DummyRequest, DummyReply]
StreamUnary: grpc.StreamUnaryMultiCallable[DummyRequest, DummyReply]
StreamStream: grpc.StreamStreamMultiCallable[DummyRequest, DummyReply]


stub: DummyServiceStub = typing.cast(typing.Any, None)
req = DummyRequest()

assert_type(stub.UnaryUnary(req), DummyReply)

for resp in stub.UnaryStream(req):
assert_type(resp, DummyReply)

assert_type(stub.StreamUnary(iter([req])), DummyReply)

for resp in stub.StreamStream(iter([req])):
assert_type(resp, DummyReply)
9 changes: 9 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_reflection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from __future__ import annotations

import typing

import grpc
from grpc_reflection.v1alpha.reflection import enable_server_reflection

server = typing.cast(grpc.Server, None)
enable_server_reflection(["foo"], server, None)
9 changes: 9 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_reflection_aio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from __future__ import annotations

import typing

import grpc.aio
from grpc_reflection.v1alpha.reflection import enable_server_reflection

server = typing.cast(grpc.aio.Server, None)
enable_server_reflection(["foo"], server, None)
14 changes: 14 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_register.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from __future__ import annotations

import typing

import grpc


@grpc.Call.register
class CallProxy:
def __init__(self, target: grpc.Call) -> None:
self._target = target

def __getattr__(self, name: str) -> typing.Any:
return getattr(self._target, name)
22 changes: 22 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_server_interceptor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from __future__ import annotations

import typing

import grpc


class Request:
pass


class Response:
pass


class NoopInterceptor(grpc.ServerInterceptor[Request, Response]):
def intercept_service(
self,
continuation: typing.Callable[[grpc.HandlerCallDetails], grpc.RpcMethodHandler[Request, Response] | None],
handler_call_details: grpc.HandlerCallDetails,
) -> grpc.RpcMethodHandler[Request, Response] | None:
return continuation(handler_call_details)
8 changes: 8 additions & 0 deletions stubs/grpcio/@tests/test_cases/check_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from __future__ import annotations

from grpc import Status
from grpc_status import to_status

# XXX: to_status actually expects a "google.rpc.status.Status",
# but the stubs for that aren't present yet.
status: Status = to_status(None)
15 changes: 15 additions & 0 deletions stubs/grpcio/METADATA.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version = "1.*"
upstream_repository = "https://github.com/grpc/grpc"
partial_stub = true
requires = [
"types-protobuf",
]

[tool.stubtest]
ignore_missing_stub = true
stubtest_requirements = [
"grpcio-channelz",
"grpcio-health-checking",
"grpcio-reflection",
"grpcio-status",
]
Loading