From 0b99a75248b4e2df02f07fe9689ece7ea9390de7 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Tue, 7 May 2019 12:49:04 -0400 Subject: [PATCH 01/18] Make typshed submodules instructions more explicit to avoid first timers struggles. After clone the project I was not able to find the folder for typeshed because I was looking for it at the mypy repo folder but actually there is a second folder also called mypy where the typeshed folder will be, the right path is 'mypy/mypy/typeshed'. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f53a4186229f..1cccfe02b1b91 100644 --- a/README.md +++ b/README.md @@ -190,8 +190,7 @@ you need to pull in the typeshed repo as follows: $ git submodule init $ git submodule update -Either way you should now have a subdirectory `typeshed` inside your mypy repo, -your folders tree should be like `mypy/mypy/typeshed`, containing a +Either way you should now have a subdirectory `typeshed` inside your mypy repo, your folders tree should be like `mypy/mypy/typeshed`, containing a clone of the typeshed repo (`https://github.com/python/typeshed`). From the mypy directory, use pip to install mypy: From 0c883d60c3f608f002d13f011ea4cb0e8b5a2c27 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Tue, 7 May 2019 13:33:24 -0400 Subject: [PATCH 02/18] Split long line --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cccfe02b1b91..2f53a4186229f 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,8 @@ you need to pull in the typeshed repo as follows: $ git submodule init $ git submodule update -Either way you should now have a subdirectory `typeshed` inside your mypy repo, your folders tree should be like `mypy/mypy/typeshed`, containing a +Either way you should now have a subdirectory `typeshed` inside your mypy repo, +your folders tree should be like `mypy/mypy/typeshed`, containing a clone of the typeshed repo (`https://github.com/python/typeshed`). From the mypy directory, use pip to install mypy: From 8e6a9b8bf8c1d257146e99a2b7c1b7640d2d18a9 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 14:56:31 -0400 Subject: [PATCH 03/18] Fix the test for List variants error with more information --- mypy/checker.py | 8 +++++++- test-data/unit/check-basic.test | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index e25368a19d0c6..d625ae85f250e 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -36,7 +36,7 @@ is_optional, remove_optional ) from mypy.sametypes import is_same_type -from mypy.messages import MessageBuilder, make_inferred_type_note +from mypy.messages import MessageBuilder, make_inferred_type_note, append_invariance_notes import mypy.checkexpr from mypy.checkmember import ( map_type_from_supertype, bind_self, erase_to_bound, type_object_type, @@ -3569,6 +3569,7 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, return False extra_info = [] # type: List[str] note_msg = '' + notes = [] if subtype_label is not None or supertype_label is not None: subtype_str, supertype_str = self.msg.format_distinctly(subtype, supertype) if subtype_label is not None: @@ -3577,9 +3578,14 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, extra_info.append(supertype_label + ' ' + supertype_str) note_msg = make_inferred_type_note(context, subtype, supertype, supertype_str) + if msg == message_registry.INCOMPATIBLE_TYPES_IN_ASSIGNMENT: + notes = append_invariance_notes([], subtype, supertype) if extra_info: msg += ' (' + ', '.join(extra_info) + ')' self.fail(msg, context) + if notes: + for note in notes: + self.msg.note(note, context) if note_msg: self.note(note_msg, context) if (isinstance(supertype, Instance) and supertype.type.is_protocol and diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 629d6bf291d22..e362a4850d14c 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -372,3 +372,12 @@ none = None b = none.__bool__() reveal_type(b) # E: Revealed type is 'builtins.bool' [builtins fixtures/bool.pyi] + +[case testAssignmentInvariantNote] +from typing import List +x: List[int] +y: List[float] +y = x # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[float]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant +[builtins fixtures/list.pyi] From 08e370ad37edec0a037fde2c00231c0a4fd00ad5 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 16:03:06 -0400 Subject: [PATCH 04/18] adds type checking for notes --- mypy/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index d625ae85f250e..76e153e631c91 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3569,7 +3569,7 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, return False extra_info = [] # type: List[str] note_msg = '' - notes = [] + notes = [] # type: List[str] if subtype_label is not None or supertype_label is not None: subtype_str, supertype_str = self.msg.format_distinctly(subtype, supertype) if subtype_label is not None: From cc13124b424d5caa8fff29f5ae33428e4ad97dcf Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 16:06:57 -0400 Subject: [PATCH 05/18] remove unnecessary if --- mypy/checker.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 76e153e631c91..43dd7d71eb57c 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3583,9 +3583,8 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, if extra_info: msg += ' (' + ', '.join(extra_info) + ')' self.fail(msg, context) - if notes: - for note in notes: - self.msg.note(note, context) + for note in notes: + self.msg.note(note, context) if note_msg: self.note(note_msg, context) if (isinstance(supertype, Instance) and supertype.type.is_protocol and From 95a86e0d7662d16905f15a1876c4bcb0841adeef Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 16:07:24 -0400 Subject: [PATCH 06/18] Introduces a failing test for dict as well --- test-data/unit/check-basic.test | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index e362a4850d14c..f80dfa0f7a655 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -373,7 +373,7 @@ b = none.__bool__() reveal_type(b) # E: Revealed type is 'builtins.bool' [builtins fixtures/bool.pyi] -[case testAssignmentInvariantNote] +[case testAssignmentInvariantNoteForList] from typing import List x: List[int] y: List[float] @@ -381,3 +381,12 @@ y = x # E: Incompatible types in assignment (expression has type "List[int]", va # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] + +[case testAssignmentInvariantNoteForDict] +from typing import Dict +x: Dict[str, int] +y: Dict[str, float] +y = x # E: Incompatible types in assignment (expression has type "Dict[str, int]", variable has type "Dict[str, float]") \ + # N: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant +[builtins fixtures/dict.pyi] \ No newline at end of file From f943668e3b897be1d69e25c3016d334e79d45e4f Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 18:31:57 -0400 Subject: [PATCH 07/18] Fixing the suggest type recommemnd for Dictinary --- test-data/unit/check-basic.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index f80dfa0f7a655..9785fb90a8f88 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -388,5 +388,5 @@ x: Dict[str, int] y: Dict[str, float] y = x # E: Incompatible types in assignment (expression has type "Dict[str, int]", variable has type "Dict[str, float]") \ # N: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ - # N: Consider using "Sequence" instead, which is covariant + # N: Consider using "Mapping" instead, which is covariant [builtins fixtures/dict.pyi] \ No newline at end of file From 6fa2ae3addea8db62f3cbadac5b5186953417e91 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 18:53:45 -0400 Subject: [PATCH 08/18] just add notes if subtype and the supertype are Instances --- mypy/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 43dd7d71eb57c..49145d374cb38 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3578,7 +3578,7 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, extra_info.append(supertype_label + ' ' + supertype_str) note_msg = make_inferred_type_note(context, subtype, supertype, supertype_str) - if msg == message_registry.INCOMPATIBLE_TYPES_IN_ASSIGNMENT: + if isinstance(subtype, Instance) and isinstance(supertype, Instance): notes = append_invariance_notes([], subtype, supertype) if extra_info: msg += ' (' + ', '.join(extra_info) + ')' From a5b9af568409f9bf03031a1ce6e07de8f5b11e03 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:06:24 -0400 Subject: [PATCH 09/18] Fixes testAssignmentInvariantNoteForDict --- test-data/unit/check-basic.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 9785fb90a8f88..876fa797f218a 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -388,5 +388,5 @@ x: Dict[str, int] y: Dict[str, float] y = x # E: Incompatible types in assignment (expression has type "Dict[str, int]", variable has type "Dict[str, float]") \ # N: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ - # N: Consider using "Mapping" instead, which is covariant + # N: Consider using "Mapping" instead, which is covariant in the value type [builtins fixtures/dict.pyi] \ No newline at end of file From e23f794ee8432930dac2e6f02c9b460c44287b3b Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:24:22 -0400 Subject: [PATCH 10/18] Fixes testCallerVarargsAndComplexTypeInference --- test-data/unit/check-varargs.test | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test-data/unit/check-varargs.test b/test-data/unit/check-varargs.test index 357b0ed63a622..cad333eb27460 100644 --- a/test-data/unit/check-varargs.test +++ b/test-data/unit/check-varargs.test @@ -586,18 +586,29 @@ ab = None # type: List[B] if int(): a, aa = G().f(*[a]) \ # E: Incompatible types in assignment (expression has type "List[A]", variable has type "A") \ - # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") + # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant + if int(): aa, a = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "A") if int(): ab, aa = G().f(*[a]) \ # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant \ # E: Argument 1 to "f" of "G" has incompatible type "*List[A]"; expected "B" if int(): - ao, ao = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[object]") + ao, ao = G().f(*[a]) \ + # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[object]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant if int(): - aa, aa = G().f(*[a]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") + aa, aa = G().f(*[a]) \ + # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[A]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant class G(Generic[T]): def f(self, *a: S) -> Tuple[List[S], List[T]]: From 90d12d78770aa1c9c8a86e0159eafe3732d83c2c Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:31:51 -0400 Subject: [PATCH 11/18] Fixes test-data/unit/check-inference-context.test --- test-data/unit/check-inference-context.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-inference-context.test b/test-data/unit/check-inference-context.test index af3abab0ce239..e22f17f3a32d3 100644 --- a/test-data/unit/check-inference-context.test +++ b/test-data/unit/check-inference-context.test @@ -1339,7 +1339,10 @@ from typing import TypeVar, Optional, List T = TypeVar('T', bound=int) def f(x: Optional[T] = None) -> List[T]: ... -y: List[str] = f() # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[str]") +y: List[str] = f() \ + # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[str]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] [case testUseCovariantGenericOuterContext] From 58c11377e1e1e013b74162b442d74a36d59dfe75 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:37:28 -0400 Subject: [PATCH 12/18] Fixes testInferredTypeSubTypeOfReturnType --- test-data/unit/check-functions.test | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 0114e3d10eabf..9bcc09e28d8d4 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2364,12 +2364,16 @@ from typing import Union, Dict, List def f() -> List[Union[str, int]]: x = ['a'] return x # E: Incompatible return value type (got "List[str]", expected "List[Union[str, int]]") \ -# N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[str, int]]" + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant \ + # N: Perhaps you need a type annotation for "x"? Suggestion: "List[Union[str, int]]" def g() -> Dict[str, Union[str, int]]: x = {'a': 'a'} return x # E: Incompatible return value type (got "Dict[str, str]", expected "Dict[str, Union[str, int]]") \ -# N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[str, Union[str, int]]" + # N: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Mapping" instead, which is covariant in the value type \ + # N: Perhaps you need a type annotation for "x"? Suggestion: "Dict[str, Union[str, int]]" def h() -> Dict[Union[str, int], str]: x = {'a': 'a'} @@ -2378,7 +2382,9 @@ def h() -> Dict[Union[str, int], str]: def i() -> List[Union[int, float]]: x: List[int] = [1] - return x # E: Incompatible return value type (got "List[int]", expected "List[Union[int, float]]") + return x # E: Incompatible return value type (got "List[int]", expected "List[Union[int, float]]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/dict.pyi] From cdc8f7441d2b3c4377ad533f0c38173e7d1e61a4 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:43:20 -0400 Subject: [PATCH 13/18] fixes testCallGenericFunctionWithTypeVarValueRestrictionUsingContext --- test-data/unit/check-typevar-values.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-typevar-values.test b/test-data/unit/check-typevar-values.test index 9e9056845dfc8..69a54dc34bd9b 100644 --- a/test-data/unit/check-typevar-values.test +++ b/test-data/unit/check-typevar-values.test @@ -19,7 +19,10 @@ o = [object()] if int(): i = f(1) s = f('') - o = f(1) # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[object]") + o = f(1) \ + # E: Incompatible types in assignment (expression has type "List[int]", variable has type "List[object]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] [case testCallGenericFunctionWithTypeVarValueRestrictionAndAnyArgs] From ee873da2b069bebfd3e5185d577b63e9469baa84 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:45:07 -0400 Subject: [PATCH 14/18] Fixes testWideOuterContextEmptyError --- test-data/unit/check-inference-context.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-inference-context.test b/test-data/unit/check-inference-context.test index e22f17f3a32d3..58d561ffafb7a 100644 --- a/test-data/unit/check-inference-context.test +++ b/test-data/unit/check-inference-context.test @@ -1320,7 +1320,10 @@ T = TypeVar('T', bound=int) def f(x: List[T]) -> List[T]: ... # TODO: improve error message for such cases, see #3283 and #5706 -y: List[str] = f([]) # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[str]") +y: List[str] = f([]) \ + # E: Incompatible types in assignment (expression has type "List[]", variable has type "List[str]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] [case testWideOuterContextNoArgs] From 04687cf26413ada8c2c1e9af67a3a26ecfd66592 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:48:06 -0400 Subject: [PATCH 15/18] Fixes testListWithDucktypeCompatibilityAndTransitivity --- test-data/unit/check-inference.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 656c1b67f5ade..4f49d6bcc1054 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -1351,7 +1351,10 @@ if int(): if int(): a = x2 if int(): - a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") + a = x3 \ + # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] [typing fixtures/typing-full.pyi] From 62a6c672c8545399e7f3dec328b5a910e1dc5f26 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 19:50:31 -0400 Subject: [PATCH 16/18] fixes testListWithDucktypeCompatibility --- test-data/unit/check-inference.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 4f49d6bcc1054..9d7887d05ae97 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -1331,7 +1331,10 @@ if int(): if int(): a = x2 if int(): - a = x3 # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") + a = x3 \ + # E: Incompatible types in assignment (expression has type "List[B]", variable has type "List[A]") \ + # N: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ + # N: Consider using "Sequence" instead, which is covariant [builtins fixtures/list.pyi] [typing fixtures/typing-full.pyi] From ca9df1bb9d2695a6fbad7cb72c4769155c56b605 Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 20:22:50 -0400 Subject: [PATCH 17/18] fixes flake8 lint --- mypy/checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 49145d374cb38..ccbab33b7b967 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3579,7 +3579,7 @@ def check_subtype(self, subtype: Type, supertype: Type, context: Context, note_msg = make_inferred_type_note(context, subtype, supertype, supertype_str) if isinstance(subtype, Instance) and isinstance(supertype, Instance): - notes = append_invariance_notes([], subtype, supertype) + notes = append_invariance_notes([], subtype, supertype) if extra_info: msg += ' (' + ', '.join(extra_info) + ')' self.fail(msg, context) From 125510b9dc9f4215f13dc63be3bafecc5f36776b Mon Sep 17 00:00:00 2001 From: Felipe Morais Date: Wed, 8 May 2019 21:03:37 -0400 Subject: [PATCH 18/18] adds a line a the end of the file --- test-data/unit/check-basic.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 876fa797f218a..53797ada44e8e 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -389,4 +389,4 @@ y: Dict[str, float] y = x # E: Incompatible types in assignment (expression has type "Dict[str, int]", variable has type "Dict[str, float]") \ # N: "Dict" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance \ # N: Consider using "Mapping" instead, which is covariant in the value type -[builtins fixtures/dict.pyi] \ No newline at end of file +[builtins fixtures/dict.pyi]