Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions tests/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,15 @@ class T(HasTraits):
@pytest.mark.mypy_testing
def mypy_set_typing() -> None:
class T(HasTraits):
remove_cell_tags = Set(
remove_cell_tags: Set[str] = Set(
Unicode(),
default_value=[],
help=(
"Tags indicating which cells are to be removed,"
"matches tags in ``cell.metadata.tags``."
"Tags indicating which cells are to be removed,matches tags in ``cell.metadata.tags``."
),
).tag(config=True)

safe_output_keys = Set(
safe_output_keys: Set[t.Any] = Set(
config=True,
default_value={
"metadata", # Not a mimetype per-se, but expected and safe.
Expand All @@ -272,13 +271,13 @@ class T(HasTraits):
)

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(Set({"foo"})) # R: traitlets.traitlets.Set[builtins.str]
reveal_type(Set({""}).tag(sync=True)) # R: traitlets.traitlets.Set[builtins.str]
reveal_type(Set(None, allow_none=True)) # R: traitlets.traitlets.Set[Never]
reveal_type(Set(None, allow_none=True).tag(sync=True)) # R: traitlets.traitlets.Set[Never]
reveal_type(T.remove_cell_tags) # R: traitlets.traitlets.Set[builtins.str]
reveal_type(t.remove_cell_tags) # R: builtins.set[builtins.str]
reveal_type(T.safe_output_keys) # R: traitlets.traitlets.Set[Any]
reveal_type(t.safe_output_keys) # R: builtins.set[Any]


Expand Down
24 changes: 11 additions & 13 deletions traitlets/traitlets.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ class TraitType(BaseDescriptor, t.Generic[G, S]):
default_value: t.Any = Undefined

def __init__(
self: TraitType[G, S],
self,
default_value: t.Any = Undefined,
allow_none: bool = False,
read_only: bool | None = None,
Expand Down Expand Up @@ -3580,7 +3580,7 @@ def item_from_string(self, s: str, index: int | None = None) -> T | str:
return s


class List(Container[t.List[T]]):
class List(Container[t.List[T]], t.Generic[T]):
"""An instance of a Python list."""

klass = list # type:ignore[assignment]
Expand Down Expand Up @@ -3645,7 +3645,7 @@ def set(self, obj: t.Any, value: t.Any) -> None:
return super().set(obj, value)


class Set(Container[t.Set[t.Any]]):
class Set(Container[t.Set[T]], t.Generic[T]):
"""An instance of a Python set."""

klass = set
Expand All @@ -3656,8 +3656,8 @@ class Set(Container[t.Set[t.Any]]):
# Redefine __init__ just to make the docstring more accurate.
def __init__(
self,
trait: t.Any = None,
default_value: t.Any = Undefined,
trait: TraitType[T, t.Any] | t.Iterable[T] | None = None,
default_value: set[T] | t.Any = Undefined,
minlen: int = 0,
maxlen: int = sys.maxsize,
**kwargs: t.Any,
Expand Down Expand Up @@ -3720,13 +3720,13 @@ def default_value_repr(self) -> str:
return "{" + list_repr[1:-1] + "}"


class Tuple(Container[t.Tuple[t.Any, ...]]):
class Tuple(Container[t.Tuple[T]], t.Generic[T]):
"""An instance of a Python tuple."""

klass = tuple
_cast_types = (list,)

def __init__(self, *traits: t.Any, **kwargs: t.Any) -> None:
def __init__(self, *traits: T, **kwargs: t.Any) -> None:
"""Create a tuple from a list, set, or tuple.

Create a fixed-type tuple with Traits:
Expand Down Expand Up @@ -3869,9 +3869,9 @@ class Dict(Instance["dict[K, V]"]):

def __init__(
self,
value_trait: TraitType[t.Any, t.Any] | dict[K, V] | Sentinel | None = None,
value_trait: TraitType[V, t.Any] | dict[K, V] | Sentinel | None = None,
per_key_traits: t.Any = None,
key_trait: TraitType[t.Any, t.Any] | None = None,
key_trait: TraitType[K, t.Any] | None = None,
default_value: dict[K, V] | Sentinel | None = Undefined,
**kwargs: t.Any,
) -> None:
Expand Down Expand Up @@ -4203,7 +4203,7 @@ def validate(self, obj: t.Any, value: t.Any) -> re.Pattern[t.Any] | None:
self.error(obj, value)


class UseEnum(TraitType[t.Any, t.Any]):
class UseEnum(TraitType[G, S], t.Generic[G, S]):
"""Use a Enum class as model for the data type description.
Note that if no default-value is provided, the first enum-value is used
as default-value.
Expand Down Expand Up @@ -4236,9 +4236,7 @@ class MyEntity(HasTraits):
default_value: enum.Enum | None = None
info_text = "Trait type adapter to a Enum class"

def __init__(
self, enum_class: type[t.Any], default_value: t.Any = None, **kwargs: t.Any
) -> None:
def __init__(self, enum_class: type[G], default_value: t.Any = None, **kwargs: t.Any) -> None:
assert issubclass(enum_class, enum.Enum), "REQUIRE: enum.Enum, but was: %r" % enum_class
allow_none = kwargs.get("allow_none", False)
if default_value is None and not allow_none:
Expand Down
Loading