Hey there. Question about Python typechecking: what tool should I use to check the types of classes with dynamically created methods?
Let us say we have a Client
class that is dynamically created with methods like this:
>>> client = Client(open_api_spec)
# Dynamically created method with dynamically added annotations
>>> client.get_example.__annotations__
{'return': MySchemaClass}
What tool should I use to analyse my code?
I could possibly solve this using code generation, where I would create a Client class with all of the methods and annotations as part of a pre-build step.
But code generation is a can of worms.
Dict[str, str]
be compatible with an argument that expects a function returning a Dict[str, Union[str, int]
? Here's the full code example:from typing import Callable, Dict, Union
class Foo:
def __init__(self, bar_fn: Callable[[int], Dict[str, Union[str, int]]]):
self.bar_fn = bar_fn
def get_dict(self) -> Dict[str, Union[str, int]]:
return self.bar_fn(1)
def fn_1(x: int) -> Dict[str, Union[str, int]]:
return {"key1": "value1", "key2": 2}
Foo(bar_fn=fn_1) # This works
def fn_2(x: int) -> Dict[str, str]:
return {"key": "value"}
Foo(bar_fn=fn_2) # This raises the following mypy error:
# [filename].py:23: error: Argument "bar_fn" to "Foo" has incompatible type "Callable[[int], Dict[str, str]]"; expected "Callable[[int], Dict[str, Union[str, int]]]"
None
and trio-stubs doesn't have that parameter hinted as Optional
. https://github.com/python-trio/trio/blob/d203b30f807e43dc9b101de2e52355ebd10b757a/trio/_core/_run.py#L1942 -- https://github.com/python-trio/trio-typing/blob/f32f17b0f242daf2d42407f383ca581d64b6c299/trio-stubs/lowlevel.pyi#L97 i guessed that maybe stubtest would catch this, but it doesn't seem to. is there another approach i should use to find similar cases? or perhaps there is a reason this "can't" be done?
https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-no-implicit-optional
Is this not what you need?
trio has a parameter defaulted to
None
and trio-stubs doesn't have that parameter hinted asOptional
In this context, would the problem be in trio, or in trio-stubs?
defaults
would lose its typing when used in inherited class? This only applies to an attribute with the name defaults
.
=None
and the stubs have : trio.abc.Clock = ...
. seems like it would be good to have some tool or another able to find this discrepancy.
mypy.nodes.TypeInfo
:]
) stubtest.
error: package.f is inconsistent, runtime argument "p" has a default value of type None, which is incompatible with stub argument type builtins.int
Stub: at line 1
def (p: builtins.int =)
Runtime: at line 1 in file /Users/shantanu/tmp/lol/package/__init__.py
def (p=None)