-
Dear all, Is there some way to statically test the type inferences? For example, assume that we have a function def foo(type_, is_list):
if type_ == "str":
if is_list:
return ["foo", "bar"]
else:
return "foo"
elif type_ == "int":
if is_list:
return [42, 43]
else:
return 42
... (It's ridiculous, but just a toy example.) As a library author, I write type annotations on it to support the library users as below: @overload
def foo(type_: Literal["str"], is_list: Literal[True]) -> list[str]:
...
@overload
def foo(type_: Literal["str"], is_list: Literal[False]) -> str:
... So, next I want to write tests to check the type annotations are working as expected like below. # This is pseudo code
assert return_type_of(foo("str", True)) is list[str]
assert return_type_of(foo("str", False)) is str To do it, for now, I define a following helper class, from typing import Generic, TypeVar
T = TypeVar('T')
class is_(Generic[T]):
def __init__(self, arg: T) -> None:
pass use it in the test code as below, is_[list[str]](foo("str", True))
is_[str](foo("str", False)) and check it with mypy. My question is, is there any standard/authentic way to do such a thing? FYI, In other words, I want to write tests like the TypeScript DefinitelyTyped, for example this, where there are assertions on the static types |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 20 replies
-
I don't think there is a standard way to do this. In fact, in typeshed issue python/typeshed#1339 has been open for quite a while. While we have other tests in typeshed, we still miss the ability to test complex corner cases directly. But @sobolevn mentioned pytest-mypy-plugins in that thread, maybe this is something to look into? |
Beta Was this translation helpful? Give feedback.
-
Thank you so much! |
Beta Was this translation helpful? Give feedback.
-
Thank you, but I found Its features such as parameterization or capability to assert type-check errors look great, but it's too hard for me to bootstrap the typing tests with it. Thank you again, and it was nice I could know that there is no standard way to test the static type inferences - then I will start with a my own minimum helper class just for my own case. FYI: from typing import Generic, TypeVar, Optional
from streamlit_webrtc import webrtc_streamer, VideoProcessorBase # My library
T = TypeVar('T')
# My helper class for type assertion
class is_(Generic[T]):
def __init__(self, arg: T) -> None:
pass
def test() -> None:
class VideoProcessor(VideoProcessorBase):
foo: int = 42
def recv(self, frame):
return frame
ctx = webrtc_streamer(key="foo", video_processor_factory=VideoProcessor)
# I want to test whether the generic class and its type inference work as expected
is_[Optional[VideoProcessor]](ctx.video_processor)
is_[None](ctx.audio_processor)
if ctx.video_processor:
is_[int](ctx.video_processor.foo) The [mypy]
python_version = 3.8
ignore_missing_imports = True I wrote a test case with - case: test
main: |
from streamlit_webrtc import webrtc_streamer, VideoProcessorBase
class VideoProcessor(VideoProcessorBase):
foo: int = 42
def recv(self, frame):
return frame
ctx = webrtc_streamer(key="foo", video_processor_factory=VideoProcessor)
reveal_type(ctx.video_processor) # N: Revealed type is 'VideoProcessor' but encountered the following massive errors - doesn't it work correctly when the dependencies do not have type definitions? E pytest_mypy_plugins.utils.TypecheckAssertionError: Invalid output:
E Actual:
E ../../../../../../path/to/streamlit-webrtc/.venv/lib/python3.8/site-packages/_pytest/_argcomplete:103: error: Cannot find implementation or library stub for module named "argcomplete.completers" (diff)
E ../../../../../../path/to/streamlit-webrtc/.venv/lib/python3.8/site-packages/_pytest/_argcomplete:103: error: Cannot find implementation or library stub for module named "argcomplete" (diff)
E ../../../../../../path/to/streamlit-webrtc/.venv/lib/python3.8/site-packages/_pytest/_code/code:33: error: Skipping analyzing "pluggy": module is installed, but missing library stubs or py.typed marker (diff)
E ../../../../../../path/to/streamlit-webrtc/.venv/lib/python3.8/site-packages/_pytest/_io/terminalwriter:70: error: Cannot find implementation or library stub for module named "colorama" (diff)
(...a lot of lines)
E ../../../../../../path/to/streamlit-webrtc/streamlit_webrtc/receive:8: error: Skipping analyzing "aiortc.mediastreams": module is installed, but missing library stubs or py.typed marker (diff)
E ../../../../../../path/to/streamlit-webrtc/streamlit_webrtc/relay:1: error: Skipping analyzing "aiortc.contrib.media": module is installed, but missing library stubs or py.typed marker (diff)
E ../../../../../../path/to/streamlit-webrtc/streamlit_webrtc/webrtc:16: error: Skipping analyzing "aiortc": module is installed, but missing library stubs or py.typed marker (diff)
E ../../../../../../path/to/streamlit-webrtc/streamlit_webrtc/webrtc:17: error: Skipping analyzing "aiortc.contrib.media": module is installed, but missing library stubs or py.typed marker (diff)
E ../../../../../../path/to/streamlit-webrtc/streamlit_webrtc/webrtc:18: error: Skipping analyzing "aiortc.mediastreams": module is installed, but missing library stubs or py.typed marker (diff) |
Beta Was this translation helpful? Give feedback.
-
For what it's worth, pytype has separate |
Beta Was this translation helpful? Give feedback.
-
incidentally, from a dev rather than a user perspective
to
|
Beta Was this translation helpful? Give feedback.
-
For those coming to this discussion mypy now has native support for from typing_extensions import assert_type
assert_type([1], list[int]) # OK
assert_type([1], list[str]) # Error |
Beta Was this translation helpful? Give feedback.
For those coming to this discussion mypy now has native support for
assert_type
https://mypy.readthedocs.io/en/stable/error_code_list.html#check-types-in-assert-type-assert-type