[med-svn] [Git][python-team/packages/mypy][upstream] New upstream version 1.14.1

Michael R. Crusoe (@crusoe) gitlab at salsa.debian.org
Thu Jan 2 05:01:51 GMT 2025



Michael R. Crusoe pushed to branch upstream at Debian Python Team / packages / mypy


Commits:
70f60e52 by Michael R. Crusoe at 2025-01-01T19:18:02-08:00
New upstream version 1.14.1
- - - - -


16 changed files:

- PKG-INFO
- mypy.egg-info/PKG-INFO
- mypy/typeops.py
- mypy/typeshed/stdlib/_asyncio.pyi
- mypy/typeshed/stdlib/builtins.pyi
- mypy/typeshed/stdlib/csv.pyi
- mypy/typeshed/stdlib/fileinput.pyi
- mypy/typeshed/stdlib/itertools.pyi
- mypy/typeshed/stdlib/multiprocessing/pool.pyi
- mypy/typeshed/stdlib/sqlite3/__init__.pyi
- mypy/version.py
- mypyc/lib-rt/getargs.c
- mypyc/test-data/run-classes.test
- test-data/unit/check-enum.test
- test-data/unit/fixtures/enum.pyi
- test-data/unit/pythoneval.test


Changes:

=====================================
PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: mypy
-Version: 1.14.0
+Version: 1.14.1
 Summary: Optional static typing for Python
 Author-email: Jukka Lehtosalo <jukka.lehtosalo at iki.fi>
 License: MIT


=====================================
mypy.egg-info/PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: mypy
-Version: 1.14.0
+Version: 1.14.1
 Summary: Optional static typing for Python
 Author-email: Jukka Lehtosalo <jukka.lehtosalo at iki.fi>
 License: MIT


=====================================
mypy/typeops.py
=====================================
@@ -647,9 +647,7 @@ def _remove_redundant_union_items(items: list[Type], keep_erased: bool) -> list[
     return items
 
 
-def _get_type_method_ret_type(t: Type, *, name: str) -> Type | None:
-    t = get_proper_type(t)
-
+def _get_type_method_ret_type(t: ProperType, *, name: str) -> Type | None:
     # For Enum literals the ret_type can change based on the Enum
     # we need to check the type of the enum rather than the literal
     if isinstance(t, LiteralType) and t.is_enum_literal():
@@ -657,9 +655,6 @@ def _get_type_method_ret_type(t: Type, *, name: str) -> Type | None:
 
     if isinstance(t, Instance):
         sym = t.type.get(name)
-        # Fallback to the metaclass for the lookup when necessary
-        if not sym and (m := t.type.metaclass_type):
-            sym = m.type.get(name)
         if sym:
             sym_type = get_proper_type(sym.type)
             if isinstance(sym_type, CallableType):
@@ -732,7 +727,10 @@ def false_only(t: Type) -> ProperType:
         if ret_type:
             if not ret_type.can_be_false:
                 return UninhabitedType(line=t.line)
-        elif isinstance(t, Instance) and t.type.is_final:
+        elif isinstance(t, Instance):
+            if t.type.is_final or t.type.is_enum:
+                return UninhabitedType(line=t.line)
+        elif isinstance(t, LiteralType) and t.is_enum_literal():
             return UninhabitedType(line=t.line)
 
         new_t = copy_type(t)


=====================================
mypy/typeshed/stdlib/_asyncio.pyi
=====================================
@@ -1,6 +1,6 @@
 import sys
 from asyncio.events import AbstractEventLoop
-from collections.abc import Awaitable, Callable, Coroutine, Generator
+from collections.abc import Awaitable, Callable, Coroutine, Generator, Iterable
 from contextvars import Context
 from types import FrameType
 from typing import Any, Literal, TextIO, TypeVar
@@ -13,7 +13,7 @@ _T = TypeVar("_T")
 _T_co = TypeVar("_T_co", covariant=True)
 _TaskYieldType: TypeAlias = Future[object] | None
 
-class Future(Awaitable[_T]):
+class Future(Awaitable[_T], Iterable[_T]):
     _state: str
     @property
     def _exception(self) -> BaseException | None: ...


=====================================
mypy/typeshed/stdlib/builtins.pyi
=====================================
@@ -1130,7 +1130,7 @@ class frozenset(AbstractSet[_T_co]):
     if sys.version_info >= (3, 9):
         def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
 
-class enumerate(Generic[_T]):
+class enumerate(Iterator[tuple[int, _T]]):
     def __new__(cls, iterable: Iterable[_T], start: int = 0) -> Self: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> tuple[int, _T]: ...
@@ -1322,7 +1322,7 @@ else:
 
 def exit(code: sys._ExitCode = None) -> NoReturn: ...
 
-class filter(Generic[_T]):
+class filter(Iterator[_T]):
     @overload
     def __new__(cls, function: None, iterable: Iterable[_T | None], /) -> Self: ...
     @overload
@@ -1383,7 +1383,7 @@ def len(obj: Sized, /) -> int: ...
 def license() -> None: ...
 def locals() -> dict[str, Any]: ...
 
-class map(Generic[_S]):
+class map(Iterator[_S]):
     @overload
     def __new__(cls, func: Callable[[_T1], _S], iter1: Iterable[_T1], /) -> Self: ...
     @overload
@@ -1625,7 +1625,7 @@ def pow(base: _SupportsSomeKindOfPow, exp: float, mod: None = None) -> Any: ...
 def pow(base: _SupportsSomeKindOfPow, exp: complex, mod: None = None) -> complex: ...
 def quit(code: sys._ExitCode = None) -> NoReturn: ...
 
-class reversed(Generic[_T]):
+class reversed(Iterator[_T]):
     @overload
     def __new__(cls, sequence: Reversible[_T], /) -> Iterator[_T]: ...  # type: ignore[misc]
     @overload
@@ -1686,7 +1686,7 @@ def vars(object: type, /) -> types.MappingProxyType[str, Any]: ...
 @overload
 def vars(object: Any = ..., /) -> dict[str, Any]: ...
 
-class zip(Generic[_T_co]):
+class zip(Iterator[_T_co]):
     if sys.version_info >= (3, 10):
         @overload
         def __new__(cls, *, strict: bool = ...) -> zip[Any]: ...


=====================================
mypy/typeshed/stdlib/csv.pyi
=====================================
@@ -25,7 +25,7 @@ else:
     from _csv import _reader as Reader, _writer as Writer
 
 from _typeshed import SupportsWrite
-from collections.abc import Collection, Iterable, Mapping, Sequence
+from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence
 from typing import Any, Generic, Literal, TypeVar, overload
 from typing_extensions import Self
 
@@ -75,7 +75,7 @@ class excel(Dialect): ...
 class excel_tab(excel): ...
 class unix_dialect(Dialect): ...
 
-class DictReader(Generic[_T]):
+class DictReader(Iterator[dict[_T | Any, str | Any]], Generic[_T]):
     fieldnames: Sequence[_T] | None
     restkey: _T | None
     restval: str | Any | None


=====================================
mypy/typeshed/stdlib/fileinput.pyi
=====================================
@@ -1,8 +1,8 @@
 import sys
 from _typeshed import AnyStr_co, StrOrBytesPath
-from collections.abc import Callable, Iterable
+from collections.abc import Callable, Iterable, Iterator
 from types import TracebackType
-from typing import IO, Any, AnyStr, Generic, Literal, Protocol, overload
+from typing import IO, Any, AnyStr, Literal, Protocol, overload
 from typing_extensions import Self, TypeAlias
 
 if sys.version_info >= (3, 9):
@@ -107,7 +107,7 @@ def fileno() -> int: ...
 def isfirstline() -> bool: ...
 def isstdin() -> bool: ...
 
-class FileInput(Generic[AnyStr]):
+class FileInput(Iterator[AnyStr]):
     if sys.version_info >= (3, 10):
         # encoding and errors are added
         @overload


=====================================
mypy/typeshed/stdlib/itertools.pyi
=====================================
@@ -29,7 +29,7 @@ _Predicate: TypeAlias = Callable[[_T], object]
 
 # Technically count can take anything that implements a number protocol and has an add method
 # but we can't enforce the add method
-class count(Generic[_N]):
+class count(Iterator[_N]):
     @overload
     def __new__(cls) -> count[int]: ...
     @overload
@@ -39,12 +39,12 @@ class count(Generic[_N]):
     def __next__(self) -> _N: ...
     def __iter__(self) -> Self: ...
 
-class cycle(Generic[_T]):
+class cycle(Iterator[_T]):
     def __init__(self, iterable: Iterable[_T], /) -> None: ...
     def __next__(self) -> _T: ...
     def __iter__(self) -> Self: ...
 
-class repeat(Generic[_T]):
+class repeat(Iterator[_T]):
     @overload
     def __init__(self, object: _T) -> None: ...
     @overload
@@ -53,7 +53,7 @@ class repeat(Generic[_T]):
     def __iter__(self) -> Self: ...
     def __length_hint__(self) -> int: ...
 
-class accumulate(Generic[_T]):
+class accumulate(Iterator[_T]):
     @overload
     def __init__(self, iterable: Iterable[_T], func: None = None, *, initial: _T | None = ...) -> None: ...
     @overload
@@ -61,7 +61,7 @@ class accumulate(Generic[_T]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
-class chain(Generic[_T]):
+class chain(Iterator[_T]):
     def __init__(self, *iterables: Iterable[_T]) -> None: ...
     def __next__(self) -> _T: ...
     def __iter__(self) -> Self: ...
@@ -71,22 +71,22 @@ class chain(Generic[_T]):
     if sys.version_info >= (3, 9):
         def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
 
-class compress(Generic[_T]):
+class compress(Iterator[_T]):
     def __init__(self, data: Iterable[_T], selectors: Iterable[Any]) -> None: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
-class dropwhile(Generic[_T]):
+class dropwhile(Iterator[_T]):
     def __init__(self, predicate: _Predicate[_T], iterable: Iterable[_T], /) -> None: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
-class filterfalse(Generic[_T]):
+class filterfalse(Iterator[_T]):
     def __init__(self, predicate: _Predicate[_T] | None, iterable: Iterable[_T], /) -> None: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
-class groupby(Generic[_T_co, _S_co]):
+class groupby(Iterator[tuple[_T_co, Iterator[_S_co]]], Generic[_T_co, _S_co]):
     @overload
     def __new__(cls, iterable: Iterable[_T1], key: None = None) -> groupby[_T1, _T1]: ...
     @overload
@@ -94,7 +94,7 @@ class groupby(Generic[_T_co, _S_co]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> tuple[_T_co, Iterator[_S_co]]: ...
 
-class islice(Generic[_T]):
+class islice(Iterator[_T]):
     @overload
     def __init__(self, iterable: Iterable[_T], stop: int | None, /) -> None: ...
     @overload
@@ -102,19 +102,19 @@ class islice(Generic[_T]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
-class starmap(Generic[_T_co]):
+class starmap(Iterator[_T_co]):
     def __new__(cls, function: Callable[..., _T], iterable: Iterable[Iterable[Any]], /) -> starmap[_T]: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T_co: ...
 
-class takewhile(Generic[_T]):
+class takewhile(Iterator[_T]):
     def __init__(self, predicate: _Predicate[_T], iterable: Iterable[_T], /) -> None: ...
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T: ...
 
 def tee(iterable: Iterable[_T], n: int = 2, /) -> tuple[Iterator[_T], ...]: ...
 
-class zip_longest(Generic[_T_co]):
+class zip_longest(Iterator[_T_co]):
     # one iterable (fillvalue doesn't matter)
     @overload
     def __new__(cls, iter1: Iterable[_T1], /, *, fillvalue: object = ...) -> zip_longest[tuple[_T1]]: ...
@@ -192,7 +192,7 @@ class zip_longest(Generic[_T_co]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T_co: ...
 
-class product(Generic[_T_co]):
+class product(Iterator[_T_co]):
     @overload
     def __new__(cls, iter1: Iterable[_T1], /) -> product[tuple[_T1]]: ...
     @overload
@@ -277,7 +277,7 @@ class product(Generic[_T_co]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T_co: ...
 
-class permutations(Generic[_T_co]):
+class permutations(Iterator[_T_co]):
     @overload
     def __new__(cls, iterable: Iterable[_T], r: Literal[2]) -> permutations[tuple[_T, _T]]: ...
     @overload
@@ -291,7 +291,7 @@ class permutations(Generic[_T_co]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T_co: ...
 
-class combinations(Generic[_T_co]):
+class combinations(Iterator[_T_co]):
     @overload
     def __new__(cls, iterable: Iterable[_T], r: Literal[2]) -> combinations[tuple[_T, _T]]: ...
     @overload
@@ -305,7 +305,7 @@ class combinations(Generic[_T_co]):
     def __iter__(self) -> Self: ...
     def __next__(self) -> _T_co: ...
 
-class combinations_with_replacement(Generic[_T_co]):
+class combinations_with_replacement(Iterator[_T_co]):
     @overload
     def __new__(cls, iterable: Iterable[_T], r: Literal[2]) -> combinations_with_replacement[tuple[_T, _T]]: ...
     @overload
@@ -320,13 +320,13 @@ class combinations_with_replacement(Generic[_T_co]):
     def __next__(self) -> _T_co: ...
 
 if sys.version_info >= (3, 10):
-    class pairwise(Generic[_T_co]):
+    class pairwise(Iterator[_T_co]):
         def __new__(cls, iterable: Iterable[_T], /) -> pairwise[tuple[_T, _T]]: ...
         def __iter__(self) -> Self: ...
         def __next__(self) -> _T_co: ...
 
 if sys.version_info >= (3, 12):
-    class batched(Generic[_T_co]):
+    class batched(Iterator[tuple[_T_co, ...]], Generic[_T_co]):
         if sys.version_info >= (3, 13):
             def __new__(cls, iterable: Iterable[_T_co], n: int, *, strict: bool = False) -> Self: ...
         else:


=====================================
mypy/typeshed/stdlib/multiprocessing/pool.pyi
=====================================
@@ -1,5 +1,5 @@
 import sys
-from collections.abc import Callable, Iterable, Mapping
+from collections.abc import Callable, Iterable, Iterator, Mapping
 from types import TracebackType
 from typing import Any, Final, Generic, TypeVar
 from typing_extensions import Self
@@ -36,7 +36,7 @@ class MapResult(ApplyResult[list[_T]]):
         error_callback: Callable[[BaseException], object] | None,
     ) -> None: ...
 
-class IMapIterator(Generic[_T]):
+class IMapIterator(Iterator[_T]):
     def __init__(self, pool: Pool) -> None: ...
     def __iter__(self) -> Self: ...
     def next(self, timeout: float | None = None) -> _T: ...


=====================================
mypy/typeshed/stdlib/sqlite3/__init__.pyi
=====================================
@@ -397,7 +397,7 @@ class Connection:
         self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None, /
     ) -> Literal[False]: ...
 
-class Cursor:
+class Cursor(Iterator[Any]):
     arraysize: int
     @property
     def connection(self) -> Connection: ...


=====================================
mypy/version.py
=====================================
@@ -8,7 +8,7 @@ from mypy import git
 # - Release versions have the form "1.2.3".
 # - Dev versions have the form "1.2.3+dev" (PLUS sign to conform to PEP 440).
 # - Before 1.0 we had the form "0.NNN".
-__version__ = "1.14.0"
+__version__ = "1.14.1"
 base_version = __version__
 
 mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))


=====================================
mypyc/lib-rt/getargs.c
=====================================
@@ -250,13 +250,12 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
                 current_arg = Py_NewRef(PyTuple_GET_ITEM(args, i));
             }
             else if (nkwargs && i >= pos) {
-                int res = PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg);
-                if (res == 1) {
-                    --nkwargs;
-                }
-                else if (res == -1) {
+                if (unlikely(PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg) < 0)) {
                     return 0;
                 }
+                if (current_arg) {
+                    --nkwargs;
+                }
             }
             else {
                 current_arg = NULL;
@@ -371,11 +370,12 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
         Py_ssize_t j;
         /* make sure there are no arguments given by name and position */
         for (i = pos; i < bound_pos_args && i < len; i++) {
-            int res = PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg);
-            if (res == 1) {
-                Py_DECREF(current_arg);
+            PyObject *current_arg;
+            if (unlikely(PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg) < 0)) {
+                goto latefail;
             }
-            else if (unlikely(res == 0)) {
+            if (unlikely(current_arg != NULL)) {
+                Py_DECREF(current_arg);
                 /* arg present in tuple and in dict */
                 PyErr_Format(PyExc_TypeError,
                              "argument for %.200s%s given by name ('%s') "
@@ -385,9 +385,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
                              kwlist[i], i+1);
                 goto latefail;
             }
-            else if (unlikely(res == -1)) {
-                goto latefail;
-            }
         }
         /* make sure there are no extraneous keyword arguments */
         j = 0;


=====================================
mypyc/test-data/run-classes.test
=====================================
@@ -467,6 +467,21 @@ a = A(10)
 assert a.foo() == 11
 assert foo() == 21
 
+[case testClassKwargs]
+class X:
+    def __init__(self, msg: str, **variables: int) -> None:
+         pass
+[file driver.py]
+import traceback
+from native import X
+X('hello', a=0)
+try:
+    X('hello', msg='hello')
+except TypeError as e:
+    print(f"{type(e).__name__}: {e}")
+[out]
+TypeError: argument for __init__() given by name ('msg') and position (1)
+
 [case testGenericClass]
 from typing import TypeVar, Generic, Sequence
 T = TypeVar('T')


=====================================
test-data/unit/check-enum.test
=====================================
@@ -181,27 +181,100 @@ def infer_truth(truth: Truth) -> None:
 [case testEnumTruthyness]
 # mypy: warn-unreachable
 import enum
+from typing_extensions import Literal
+
 class E(enum.Enum):
-    x = 0
-if not E.x:
-    "noop"
+    zero = 0
+    one = 1
+
+def print(s: str) -> None: ...
+
+if E.zero:
+    print("zero is true")
+if not E.zero:
+    print("zero is false")  # E: Statement is unreachable
+
+if E.one:
+    print("one is true")
+if not E.one:
+    print("one is false")  # E: Statement is unreachable
+
+def main(zero: Literal[E.zero], one: Literal[E.one]) -> None:
+    if zero:
+        print("zero is true")
+    if not zero:
+        print("zero is false")  # E: Statement is unreachable
+    if one:
+        print("one is true")
+    if not one:
+        print("one is false")  # E: Statement is unreachable
 [builtins fixtures/tuple.pyi]
-[out]
-main:6: error: Statement is unreachable
 
 [case testEnumTruthynessCustomDunderBool]
 # mypy: warn-unreachable
 import enum
 from typing_extensions import Literal
+
 class E(enum.Enum):
-    x = 0
+    zero = 0
+    one = 1
     def __bool__(self) -> Literal[False]:
         return False
-if E.x:
-    "noop"
+
+def print(s: str) -> None: ...
+
+if E.zero:
+    print("zero is true")  # E: Statement is unreachable
+if not E.zero:
+    print("zero is false")
+
+if E.one:
+    print("one is true")  # E: Statement is unreachable
+if not E.one:
+    print("one is false")
+
+def main(zero: Literal[E.zero], one: Literal[E.one]) -> None:
+    if zero:
+        print("zero is true")  # E: Statement is unreachable
+    if not zero:
+        print("zero is false")
+    if one:
+        print("one is true")  # E: Statement is unreachable
+    if not one:
+        print("one is false")
+[builtins fixtures/enum.pyi]
+
+[case testEnumTruthynessStrEnum]
+# mypy: warn-unreachable
+import enum
+from typing_extensions import Literal
+
+class E(enum.StrEnum):
+    empty = ""
+    not_empty = "asdf"
+
+def print(s: str) -> None: ...
+
+if E.empty:
+    print("empty is true")
+if not E.empty:
+    print("empty is false")
+
+if E.not_empty:
+    print("not_empty is true")
+if not E.not_empty:
+    print("not_empty is false")
+
+def main(empty: Literal[E.empty], not_empty: Literal[E.not_empty]) -> None:
+    if empty:
+        print("empty is true")
+    if not empty:
+        print("empty is false")
+    if not_empty:
+        print("not_empty is true")
+    if not not_empty:
+        print("not_empty is false")
 [builtins fixtures/enum.pyi]
-[out]
-main:9: error: Statement is unreachable
 
 [case testEnumUnique]
 import enum


=====================================
test-data/unit/fixtures/enum.pyi
=====================================
@@ -11,6 +11,8 @@ class tuple(Generic[T]):
     def __getitem__(self, x: int) -> T: pass
 
 class int: pass
-class str: pass
+class str:
+    def __len__(self) -> int: pass
+
 class dict: pass
 class ellipsis: pass


=====================================
test-data/unit/pythoneval.test
=====================================
@@ -2181,3 +2181,13 @@ class Status(Enum):
 
 def imperfect(status: Status) -> str:
     return status.name.lower()
+
+[case testUnpackIteratorBuiltins]
+# Regression test for https://github.com/python/mypy/issues/18320
+# Caused by https://github.com/python/typeshed/pull/12851
+x = [1, 2]
+reveal_type([*reversed(x)])
+reveal_type([*map(str, x)])
+[out]
+_testUnpackIteratorBuiltins.py:4: note: Revealed type is "builtins.list[builtins.int]"
+_testUnpackIteratorBuiltins.py:5: note: Revealed type is "builtins.list[builtins.str]"



View it on GitLab: https://salsa.debian.org/python-team/packages/mypy/-/commit/70f60e52d2f05f50a9ff4c856a067d37a1a05858

-- 
View it on GitLab: https://salsa.debian.org/python-team/packages/mypy/-/commit/70f60e52d2f05f50a9ff4c856a067d37a1a05858
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20250102/e3c05c62/attachment-0001.htm>


More information about the debian-med-commit mailing list