Open DanielWarloch opened 1 year ago
Thanks for bug report. I need time to investigate it.
It's probably because one code base for both sync and async adapters, but function signatures are same.
If you have some good solution or idea your PR is welcome!
I will try to use overloads and approach described here https://github.com/microsoft/pyright/discussions/5629#discussioncomment-6621771
Original problem:
import asyncio
from typing import Any
class Builds:
def __init__(self, jenkins) -> None:
self.jenkins = jenkins
def get(self, name: str) -> str:
return self.jenkins._request(name)
class Jenkins:
def __init__(self) -> None:
self.builds = Builds(self)
class AsyncJenkinsClient(Jenkins):
async def _request(self, name: str) -> Any:
return name
class JenkinsClient(Jenkins):
def _request(self, name: str) -> Any:
return name
async def main():
client = AsyncJenkinsClient()
result = await client.builds.get('async')
print(result)
client = JenkinsClient()
result = client.builds.get('sync')
print(result)
asyncio.run(main())
I suggest to use .pyi
files for function signatures with @propery
to prevent less code readability.
https://github.com/microsoft/pyright/discussions/6424
PoC with correct types:
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())
Can ujenkins better support return types(mostly for async staff)? When I use
AsyncJenkinsClient
and call for examplehw_jenkins.builds.get_artifact()
the return type isBytes
so when Iawait
for that then pyright will returnerror: "bytes" is not awaitable (reportGeneralTypeIssues)
. To resolve these issues it is required to do casting on each function callcast(Awaitable[bytes], hw_jenkins.builds.get_artifact())
.