tox
tox copied to clipboard
tox4: typing error when add_config's of_type is Optional[...]
With the following code:
class MyConfigSet(ConfigSet):
def register_config(self) -> None:
self.add_config(
keys=["key"],
of_type=Optional[str],
default=None,
desc="desc",
)
I get the following mypy error:
error: Argument "of_type" to "add_config" of "ConfigSet" has incompatible type "object"; expected "Type[None]"
if I change the default to any string (eg ""
), the error changes to:
error: Argument "of_type" to "add_config" of "ConfigSet" has incompatible type "object"; expected "Type[str]"
The problem removed from the tox part, get this to work:
from typing import Optional, Type, TypeVar
V = TypeVar("V")
def call(of_type: Type[V], default: V) -> None:
assert default is not None
assert of_type is not None
call(str, "str") # works
call(int, 1) # works
call(Optional[str], None) # Argument 1 to "call" has incompatible type "object"; expected "Type[None]"
call(Optional[str], "") # Argument 1 to "call" has incompatible type "object"; expected "Type[str]"
So seems for mypy Optional[str]
is not a type; you'd need to define the type as type('', (type(None), str), {})
instead:
class MyConfigSet(ConfigSet):
def register_config(self) -> None:
self.add_config(
keys=["key"],
of_type=type("", (type(None), str), {}),
default=None,
desc="desc",
)
Which while makes it work is not trivial or easy to guess. In light of this our options are:
- Document using
type("", (type(None), str), {})
- Disable type checking here
- Add a mypy plugin that handles this
- First 2 and then later 3
I'm tempted to say to do option 4. @asottile @jugmac00 @dcrosta opinions?
Seems no opinions, so I recommend disabling the type checker in these lines.