123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- from __future__ import annotations
- import logging
- import typing as t
- from abc import ABC
- import pytest
- from traitlets import (
- Any,
- Bool,
- CInt,
- Dict,
- Enum,
- HasTraits,
- Instance,
- Int,
- List,
- Set,
- TCPAddress,
- Type,
- Unicode,
- Union,
- default,
- observe,
- validate,
- )
- from traitlets.config import Config
- if not t.TYPE_CHECKING:
- def reveal_type(*args: t.Any, **kwargs: t.Any) -> None:
- pass
- # mypy: disallow-untyped-calls
- class Foo:
- def __init__(self, c: t.Any) -> None:
- self.c = c
- @pytest.mark.mypy_testing
- def mypy_decorator_typing() -> None:
- class T(HasTraits):
- foo = Unicode("").tag(config=True)
- @default("foo")
- def _default_foo(self) -> str:
- return "hi"
- @observe("foo")
- def _foo_observer(self, change: t.Any) -> bool:
- return True
- @validate("foo")
- def _foo_validate(self, commit: t.Any) -> bool:
- return True
- t = T()
- reveal_type(t.foo) # R: builtins.str
- reveal_type(t._foo_observer) # R: Any
- reveal_type(t._foo_validate) # R: Any
- @pytest.mark.mypy_testing
- def mypy_config_typing() -> None:
- c = Config(
- {
- "ExtractOutputPreprocessor": {"enabled": True},
- }
- )
- reveal_type(c) # R: traitlets.config.loader.Config
- @pytest.mark.mypy_testing
- def mypy_union_typing() -> None:
- class T(HasTraits):
- style = Union(
- [Unicode("default"), Type(klass=object)],
- help="Name of the pygments style to use",
- default_value="hi",
- ).tag(config=True)
- t = T()
- reveal_type(Union("foo")) # R: traitlets.traitlets.Union
- reveal_type(Union("").tag(sync=True)) # R: traitlets.traitlets.Union
- reveal_type(Union(None, allow_none=True)) # R: traitlets.traitlets.Union
- reveal_type(Union(None, allow_none=True).tag(sync=True)) # R: traitlets.traitlets.Union
- reveal_type(T.style) # R: traitlets.traitlets.Union
- reveal_type(t.style) # R: Any
- @pytest.mark.mypy_testing
- def mypy_list_typing() -> None:
- class T(HasTraits):
- latex_command = List(
- ["xelatex", "{filename}", "-quiet"], help="Shell command used to compile latex."
- ).tag(config=True)
- t = T()
- reveal_type(List(["foo"])) # R: traitlets.traitlets.List[builtins.str]
- reveal_type(List([""]).tag(sync=True)) # R: traitlets.traitlets.List[builtins.str]
- reveal_type(List(None, allow_none=True)) # R: traitlets.traitlets.List[Never]
- reveal_type(
- List(None, allow_none=True).tag(sync=True) # R: traitlets.traitlets.List[Never]
- )
- reveal_type(T.latex_command) # R: traitlets.traitlets.List[builtins.str]
- reveal_type(t.latex_command) # R: builtins.list[builtins.str]
- @pytest.mark.mypy_testing
- def mypy_dict_typing() -> None:
- class T(HasTraits):
- foo = Dict({}, help="Shell command used to compile latex.").tag(config=True)
- t = T()
- reveal_type(Dict(None, allow_none=True)) # R: traitlets.traitlets.Dict[builtins.str, Any]
- reveal_type(
- Dict(None, allow_none=True).tag(sync=True) # R: traitlets.traitlets.Dict[builtins.str, Any]
- )
- reveal_type(T.foo) # R: traitlets.traitlets.Dict[builtins.str, Any]
- reveal_type(t.foo) # R: builtins.dict[builtins.str, Any]
- @pytest.mark.mypy_testing
- def mypy_type_typing() -> None:
- class KernelSpec:
- item = Unicode("foo")
- class KernelSpecSubclass(KernelSpec):
- other = Unicode("bar")
- class GatewayTokenRenewerBase(ABC):
- item = Unicode("foo")
- class KernelSpecManager(HasTraits):
- """A manager for kernel specs."""
- kernel_spec_class = Type(
- KernelSpec,
- config=True,
- help="""The kernel spec class. This is configurable to allow
- subclassing of the KernelSpecManager for customized behavior.
- """,
- )
- other_class = Type("foo.bar.baz")
- other_kernel_spec_class = Type(
- default_value=KernelSpecSubclass,
- klass=KernelSpec,
- config=True,
- )
- gateway_token_renewer_class = Type(
- klass=GatewayTokenRenewerBase,
- config=True,
- help="""The class to use for Gateway token renewal. (JUPYTER_GATEWAY_TOKEN_RENEWER_CLASS env var)""",
- )
- t = KernelSpecManager()
- reveal_type(t.kernel_spec_class) # R: def () -> tests.test_typing.KernelSpec@129
- reveal_type(t.kernel_spec_class()) # R: tests.test_typing.KernelSpec@129
- reveal_type(t.kernel_spec_class().item) # R: builtins.str
- reveal_type(t.other_class) # R: builtins.type
- reveal_type(t.other_class()) # R: Any
- reveal_type(t.other_kernel_spec_class) # R: def () -> tests.test_typing.KernelSpec@129
- reveal_type(t.other_kernel_spec_class()) # R: tests.test_typing.KernelSpec@129
- reveal_type(
- t.gateway_token_renewer_class # R: def () -> tests.test_typing.GatewayTokenRenewerBase@135
- )
- reveal_type(t.gateway_token_renewer_class()) # R: tests.test_typing.GatewayTokenRenewerBase@135
- @pytest.mark.mypy_testing
- def mypy_unicode_typing() -> None:
- class T(HasTraits):
- export_format = Unicode(
- allow_none=False,
- help="""The export format to be used, either one of the built-in formats
- or a dotted object name that represents the import path for an
- ``Exporter`` class""",
- ).tag(config=True)
- t = T()
- reveal_type(
- Unicode( # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
- "foo"
- )
- )
- reveal_type(
- Unicode( # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
- ""
- ).tag(sync=True)
- )
- reveal_type(
- Unicode( # R: traitlets.traitlets.Unicode[Union[builtins.str, None], Union[builtins.str, builtins.bytes, None]]
- None, allow_none=True
- )
- )
- reveal_type(
- Unicode( # R: traitlets.traitlets.Unicode[Union[builtins.str, None], Union[builtins.str, builtins.bytes, None]]
- None, allow_none=True
- ).tag(sync=True)
- )
- reveal_type(
- T.export_format # R: traitlets.traitlets.Unicode[builtins.str, Union[builtins.str, builtins.bytes]]
- )
- reveal_type(t.export_format) # R: builtins.str
- @pytest.mark.mypy_testing
- def mypy_enum_typing() -> None:
- class T(HasTraits):
- log_level = Enum(
- (0, 10, 20, 30, 40, 50),
- default_value=logging.WARN,
- help="Set the log level by value or name.",
- ).tag(config=True)
- t = T()
- reveal_type(
- Enum( # R: traitlets.traitlets.Enum[builtins.str]
- ("foo",)
- )
- )
- reveal_type(
- Enum( # R: traitlets.traitlets.Enum[builtins.str]
- [""]
- ).tag(sync=True)
- )
- reveal_type(
- Enum( # R: traitlets.traitlets.Enum[None]
- None, allow_none=True
- )
- )
- reveal_type(
- Enum( # R: traitlets.traitlets.Enum[None]
- None, allow_none=True
- ).tag(sync=True)
- )
- reveal_type(
- T.log_level # R: traitlets.traitlets.Enum[builtins.int]
- )
- reveal_type(t.log_level) # R: builtins.int
- @pytest.mark.mypy_testing
- def mypy_set_typing() -> None:
- class T(HasTraits):
- remove_cell_tags = Set(
- Unicode(),
- default_value=[],
- help=(
- "Tags indicating which cells are to be removed,"
- "matches tags in ``cell.metadata.tags``."
- ),
- ).tag(config=True)
- safe_output_keys = Set(
- config=True,
- default_value={
- "metadata", # Not a mimetype per-se, but expected and safe.
- "text/plain",
- "text/latex",
- "application/json",
- "image/png",
- "image/jpeg",
- },
- help="Cell output mimetypes to render without modification",
- )
- t = T()
- reveal_type(Set("foo")) # R: traitlets.traitlets.Set
- reveal_type(Set("").tag(sync=True)) # R: traitlets.traitlets.Set
- reveal_type(Set(None, allow_none=True)) # R: traitlets.traitlets.Set
- reveal_type(Set(None, allow_none=True).tag(sync=True)) # R: traitlets.traitlets.Set
- reveal_type(T.remove_cell_tags) # R: traitlets.traitlets.Set
- reveal_type(t.remove_cell_tags) # R: builtins.set[Any]
- reveal_type(T.safe_output_keys) # R: traitlets.traitlets.Set
- reveal_type(t.safe_output_keys) # R: builtins.set[Any]
- @pytest.mark.mypy_testing
- def mypy_any_typing() -> None:
- class T(HasTraits):
- attributes = Any(
- config=True,
- default_value={
- "a": ["href", "title"],
- "abbr": ["title"],
- "acronym": ["title"],
- },
- help="Allowed HTML tag attributes",
- )
- t = T()
- reveal_type(Any("foo")) # R: traitlets.traitlets.Any
- reveal_type(Any("").tag(sync=True)) # R: traitlets.traitlets.Any
- reveal_type(Any(None, allow_none=True)) # R: traitlets.traitlets.Any
- reveal_type(Any(None, allow_none=True).tag(sync=True)) # R: traitlets.traitlets.Any
- reveal_type(T.attributes) # R: traitlets.traitlets.Any
- reveal_type(t.attributes) # R: Any
- @pytest.mark.mypy_testing
- def mypy_bool_typing() -> None:
- class T(HasTraits):
- b = Bool(True).tag(sync=True)
- ob = Bool(None, allow_none=True).tag(sync=True)
- t = T()
- reveal_type(
- Bool(True) # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
- )
- reveal_type(
- Bool( # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
- True
- ).tag(sync=True)
- )
- reveal_type(
- Bool( # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
- None, allow_none=True
- )
- )
- reveal_type(
- Bool( # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
- None, allow_none=True
- ).tag(sync=True)
- )
- reveal_type(
- T.b # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
- )
- reveal_type(t.b) # R: builtins.bool
- reveal_type(t.ob) # R: Union[builtins.bool, None]
- reveal_type(
- T.b # R: traitlets.traitlets.Bool[builtins.bool, Union[builtins.bool, builtins.int]]
- )
- reveal_type(
- T.ob # R: traitlets.traitlets.Bool[Union[builtins.bool, None], Union[builtins.bool, builtins.int, None]]
- )
- # we would expect this to be Optional[Union[bool, int]], but...
- t.b = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Union[bool, int]") [assignment]
- t.b = None # E: Incompatible types in assignment (expression has type "None", variable has type "Union[bool, int]") [assignment]
- @pytest.mark.mypy_testing
- def mypy_int_typing() -> None:
- class T(HasTraits):
- i: Int[int, int] = Int(42).tag(sync=True)
- oi: Int[int | None, int | None] = Int(42, allow_none=True).tag(sync=True)
- t = T()
- reveal_type(Int(True)) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
- reveal_type(Int(True).tag(sync=True)) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
- reveal_type(
- Int( # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
- None, allow_none=True
- )
- )
- reveal_type(
- Int( # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
- None, allow_none=True
- ).tag(sync=True)
- )
- reveal_type(T.i) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
- reveal_type(t.i) # R: builtins.int
- reveal_type(t.oi) # R: Union[builtins.int, None]
- reveal_type(T.i) # R: traitlets.traitlets.Int[builtins.int, builtins.int]
- reveal_type(
- T.oi # R: traitlets.traitlets.Int[Union[builtins.int, None], Union[builtins.int, None]]
- )
- t.i = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
- t.i = None # E: Incompatible types in assignment (expression has type "None", variable has type "int") [assignment]
- t.i = 1.2 # E: Incompatible types in assignment (expression has type "float", variable has type "int") [assignment]
- @pytest.mark.mypy_testing
- def mypy_cint_typing() -> None:
- class T(HasTraits):
- i = CInt(42).tag(sync=True)
- oi = CInt(42, allow_none=True).tag(sync=True)
- t = T()
- reveal_type(CInt(42)) # R: traitlets.traitlets.CInt[builtins.int, Any]
- reveal_type(CInt(42).tag(sync=True)) # R: traitlets.traitlets.CInt[builtins.int, Any]
- reveal_type(
- CInt(None, allow_none=True) # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
- )
- reveal_type(
- CInt( # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
- None, allow_none=True
- ).tag(sync=True)
- )
- reveal_type(T.i) # R: traitlets.traitlets.CInt[builtins.int, Any]
- reveal_type(t.i) # R: builtins.int
- reveal_type(t.oi) # R: Union[builtins.int, None]
- reveal_type(T.i) # R: traitlets.traitlets.CInt[builtins.int, Any]
- reveal_type(T.oi) # R: traitlets.traitlets.CInt[Union[builtins.int, None], Any]
- @pytest.mark.mypy_testing
- def mypy_tcp_typing() -> None:
- class T(HasTraits):
- tcp = TCPAddress()
- otcp = TCPAddress(None, allow_none=True)
- t = T()
- reveal_type(t.tcp) # R: Tuple[builtins.str, builtins.int]
- reveal_type(
- T.tcp # R: traitlets.traitlets.TCPAddress[Tuple[builtins.str, builtins.int], Tuple[builtins.str, builtins.int]]
- )
- reveal_type(
- T.tcp.tag( # R:traitlets.traitlets.TCPAddress[Tuple[builtins.str, builtins.int], Tuple[builtins.str, builtins.int]]
- sync=True
- )
- )
- reveal_type(t.otcp) # R: Union[Tuple[builtins.str, builtins.int], None]
- reveal_type(
- T.otcp # R: traitlets.traitlets.TCPAddress[Union[Tuple[builtins.str, builtins.int], None], Union[Tuple[builtins.str, builtins.int], None]]
- )
- reveal_type(
- T.otcp.tag( # R: traitlets.traitlets.TCPAddress[Union[Tuple[builtins.str, builtins.int], None], Union[Tuple[builtins.str, builtins.int], None]]
- sync=True
- )
- )
- t.tcp = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Tuple[str, int]") [assignment]
- t.otcp = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Tuple[str, int]]") [assignment]
- t.tcp = None # E: Incompatible types in assignment (expression has type "None", variable has type "Tuple[str, int]") [assignment]
- @pytest.mark.mypy_testing
- def mypy_instance_typing() -> None:
- class T(HasTraits):
- inst = Instance(Foo)
- oinst = Instance(Foo, allow_none=True)
- oinst_string = Instance("Foo", allow_none=True)
- t = T()
- reveal_type(t.inst) # R: tests.test_typing.Foo
- reveal_type(T.inst) # R: traitlets.traitlets.Instance[tests.test_typing.Foo]
- reveal_type(T.inst.tag(sync=True)) # R: traitlets.traitlets.Instance[tests.test_typing.Foo]
- reveal_type(t.oinst) # R: Union[tests.test_typing.Foo, None]
- reveal_type(t.oinst_string) # R: Union[Any, None]
- reveal_type(T.oinst) # R: traitlets.traitlets.Instance[Union[tests.test_typing.Foo, None]]
- reveal_type(
- T.oinst.tag( # R: traitlets.traitlets.Instance[Union[tests.test_typing.Foo, None]]
- sync=True
- )
- )
- t.inst = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Foo") [assignment]
- t.oinst = "foo" # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Foo]") [assignment]
- t.inst = None # E: Incompatible types in assignment (expression has type "None", variable has type "Foo") [assignment]
|