Skip to content

Commit

Permalink
Make Counter generic over the value
Browse files Browse the repository at this point in the history
Closes: python#3438
  • Loading branch information
srittau committed Mar 20, 2024
1 parent 3f2ff5b commit e7e430a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
7 changes: 4 additions & 3 deletions stdlib/collections/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ _KT = TypeVar("_KT")
_VT = TypeVar("_VT")
_KT_co = TypeVar("_KT_co", covariant=True)
_VT_co = TypeVar("_VT_co", covariant=True)
_C = TypeVar("_C", default=int)

# namedtuple is special-cased in the type checker; the initializer is ignored.
def namedtuple(
Expand Down Expand Up @@ -261,13 +262,13 @@ class deque(MutableSequence[_T]):
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

class Counter(dict[_T, int], Generic[_T]):
class Counter(dict[_T, _C]):
@overload
def __init__(self, iterable: None = None, /) -> None: ...
@overload
def __init__(self: Counter[str], iterable: None = None, /, **kwargs: int) -> None: ...
def __init__(self: Counter[str, _C], iterable: None = None, /, **kwargs: _C) -> None: ...
@overload
def __init__(self, mapping: SupportsKeysAndGetItem[_T, int], /) -> None: ...
def __init__(self: Counter[_T, _C], mapping: SupportsKeysAndGetItem[_T, _C], /) -> None: ...
@overload
def __init__(self, iterable: Iterable[_T], /) -> None: ...
def copy(self) -> Self: ...
Expand Down
31 changes: 31 additions & 0 deletions test_cases/stdlib/collections/check_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from collections import Counter
from typing_extensions import assert_type, Never


class Foo: ...


# Test the constructor
assert_type(Counter(), Counter[Never, int])
assert_type(Counter(foo=42.2), Counter[str, float])
assert_type(Counter({42: "bar"}), Counter[int, str])
assert_type(Counter([1, 2, 3]), Counter[int, int])

int_c: Counter[str] = Counter()
assert_type(int_c, Counter[str, int])
int_c["a"] = 1
int_c["a"] += 3
int_c["a"] += 3.5 # type: ignore

float_c = Counter(foo=42.2)
assert_type(float_c, Counter[str, float])
float_c["a"] = 1.0
float_c["a"] += 3.0
float_c["a"] += 42
float_c["a"] += "42" # type: ignore

custom_c: Counter[str, Foo] = Counter()
assert_type(custom_c, Counter[str, Foo])
custom_c["a"] = Foo()
custom_c["a"] += Foo() # type: ignore
custom_c["a"] += 42 # type: ignore

0 comments on commit e7e430a

Please sign in to comment.