-
Hello! I have a Python package with sync and async http adapters. I need correct type hints there. It there any better way except using a lot of import asyncio
from typing import Any, Coroutine, overload, TypeVar, Generic, Union
ClientT = TypeVar('ClientT', bound=Union['JenkinsClient', 'AsyncJenkinsClient'])
class Builds(Generic[ClientT]):
def __init__(self, jenkins: ClientT) -> None:
self.jenkins = jenkins
@overload
def get(self: 'Builds[JenkinsClient]', name: str) -> str:
...
@overload
def get(self: 'Builds[AsyncJenkinsClient]', name: str) -> Coroutine[Any, Any, str]:
...
def get(self, name: str) -> str | Coroutine[Any, Any, str]:
return self.jenkins._request(name)
class AsyncJenkinsClient:
def __init__(self) -> None:
self.builds = Builds(self)
async def _request(self, name: str) -> Any:
return name
class JenkinsClient:
def __init__(self) -> None:
self.builds = Builds(self)
def _request(self, name: str) -> Any:
return name
async def main() -> None:
async_client = AsyncJenkinsClient()
result = await async_client.builds.get('async')
print(result)
client = JenkinsClient()
result = client.builds.get('sync')
print(result)
asyncio.run(main()) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
For polymorphic functions like this, Here's another approach that reduces the redundancy but isn't quite as clean. Code sample in pyright playground import asyncio
from typing import Any, Coroutine, TypeVar, Generic, cast
R = TypeVar("R")
class Builds(Generic[R]):
def __init__(self, jenkins: "JenkinsClient | AsyncJenkinsClient") -> None:
self.jenkins = jenkins
def get(self, name: str) -> R:
return cast(R, self.jenkins._request(name))
class AsyncJenkinsClient:
def __init__(self) -> None:
self.builds = Builds[Coroutine[Any, Any, str]](self)
async def _request(self, name: str) -> Any:
return name
class JenkinsClient:
def __init__(self) -> None:
self.builds = Builds[str](self)
def _request(self, name: str) -> Any:
return name
async def main() -> None:
async_client = AsyncJenkinsClient()
result = await async_client.builds.get("async")
print(result)
client = JenkinsClient()
result = client.builds.get("sync")
print(result)
asyncio.run(main()) My only other suggestion is to rethink how you're abstracting this. It's a bit odd that you're passing in the client to the |
Beta Was this translation helpful? Give feedback.
-
But actual return types are hidden from docs for example, and when code reading |
Beta Was this translation helpful? Give feedback.
For polymorphic functions like this,
@overload
is the go-to solution.Here's another approach that reduces the redundancy but isn't quite as clean.
Code sample in pyright playground