From 4e81716c9246c171628612c90b0a7b60d9f11dc6 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 15:15:29 -1000 Subject: [PATCH 01/10] First draft of `decorated_type`. Needs more tests --- extensions/mypy_extensions.py | 5 +++++ mypy/checker.py | 10 ++++++++-- mypy/semanal.py | 14 ++++++++++++++ test-data/unit/check-functions.test | 19 +++++++++++++++++++ test-data/unit/lib-stub/mypy_extensions.pyi | 4 +++- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/extensions/mypy_extensions.py b/extensions/mypy_extensions.py index 26e568cc0a27..ef6c052f6121 100644 --- a/extensions/mypy_extensions.py +++ b/extensions/mypy_extensions.py @@ -95,3 +95,8 @@ class Point2D(TypedDict): # Return type that indicates a function does not return class NoReturn: pass + +def decorated_type(t): + """Declared the decorated type of a decorated item""" + # Return the identity function -- calling this should be a noop + return lambda __x: __x diff --git a/mypy/checker.py b/mypy/checker.py index 488f3185e897..6df5131685f7 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2216,8 +2216,14 @@ def visit_decorator(self, e: Decorator) -> None: sig, t2 = self.expr_checker.check_call(dec, [temp], [nodes.ARG_POS], e) sig = cast(FunctionLike, sig) - sig = set_callable_name(sig, e.func) - e.var.type = sig + if e.var.type is not None: + # We have a declared type, check it. + self.check_subtype(sig, e.var.type, e, + subtype_label="inferred decorated type", + supertype_label="decalred decorated type") + else: + e.var.type = sig + e.var.type = set_callable_name(e.var.type, e.func) e.var.is_ready = True if e.func.is_property: self.check_incompatible_property_override(e) diff --git a/mypy/semanal.py b/mypy/semanal.py index 9ce706d6c90e..76b46781df58 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2436,6 +2436,17 @@ def visit_decorator(self, dec: Decorator) -> None: elif refers_to_fullname(d, 'typing.no_type_check'): dec.var.type = AnyType() no_type_check = True + elif isinstance(d, CallExpr) and ( + refers_to_fullname(d.callee, 'typing.decorated_type') + or refers_to_fullname(d.callee, 'mypy_extensions.decorated_type')): + removed.append(i) + if i != 0: + self.fail('"decorated_type" must be the topmost decorator') + elif len(d.args) != 1: + self.fail('"decorated_type" takes exactly one argument') + else: + dec.var.type = self.expr_to_analyzed_type(d.args[0]) + print("Set type", dec.var.type) for i in reversed(removed): del dec.decorators[i] if not dec.is_overload or dec.var.is_property: @@ -3600,6 +3611,9 @@ def visit_decorator(self, dec: Decorator) -> None: engine just for decorators. """ super().visit_decorator(dec) + if dec.var.type is not None: + # We already have a declared type for this decorated thing. + return if dec.var.is_property: # Decorators are expected to have a callable type (it's a little odd). if dec.func.type is None: diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 33fc51d3b046..b58155c0c9e3 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -733,6 +733,25 @@ a = None # type: A a.f() a.f(None) # E: Too many arguments for "f" of "A" +[case testUntypedDecoratorWithDeclaredType] + +from typing import Callable +from mypy_extensions import decorated_type + +def dec(f): pass + +@decorated_type(Callable[[int], str]) +@dec +def f(): pass + +f("a") # E: Argument 1 to "f" has incompatible type "str"; expected "int" +x: str = f(1) +y: int = f(1) # E: Incompatible types in assignment (expression has type "str", variable has type "int") + +reveal_type(f) # E: Revealed type is 'def (builtins.int) -> builtins.str' + +[builtins fixtures/dict.pyi] + [case testNestedDecorators] from typing import Any, Callable def dec1(f: Callable[[Any], None]) -> Callable[[], None]: pass diff --git a/test-data/unit/lib-stub/mypy_extensions.pyi b/test-data/unit/lib-stub/mypy_extensions.pyi index 6e1e3b0ed285..87ba6e74f965 100644 --- a/test-data/unit/lib-stub/mypy_extensions.pyi +++ b/test-data/unit/lib-stub/mypy_extensions.pyi @@ -1,4 +1,4 @@ -from typing import Dict, Type, TypeVar +from typing import Dict, Type, TypeVar, Callable T = TypeVar('T') @@ -6,3 +6,5 @@ T = TypeVar('T') def TypedDict(typename: str, fields: Dict[str, Type[T]]) -> Type[dict]: pass class NoReturn: pass + +def decorated_type(t: Type) -> Callable[[T], T]: pass \ No newline at end of file From f15779a6e6c85e6110551fce1edd49b665b819f2 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 15:30:03 -1000 Subject: [PATCH 02/10] more tests --- mypy/semanal.py | 7 ++- test-data/unit/check-functions.test | 69 +++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 76b46781df58..0b4a5afb28e7 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2441,12 +2441,15 @@ def visit_decorator(self, dec: Decorator) -> None: or refers_to_fullname(d.callee, 'mypy_extensions.decorated_type')): removed.append(i) if i != 0: - self.fail('"decorated_type" must be the topmost decorator') + self.fail('"decorated_type" must be the topmost decorator', d) elif len(d.args) != 1: - self.fail('"decorated_type" takes exactly one argument') + self.fail('"decorated_type" takes exactly one argument', d) else: dec.var.type = self.expr_to_analyzed_type(d.args[0]) print("Set type", dec.var.type) + elif (refers_to_fullname(d, 'typing.decorated_type') or + refers_to_fullname(d, 'mypy_extensions.decorated_type')): + self.fail('"decorated_type" must have a type as an argument', d) for i in reversed(removed): del dec.decorators[i] if not dec.is_overload or dec.var.is_property: diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index b58155c0c9e3..006c807554fe 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -752,6 +752,75 @@ reveal_type(f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [builtins fixtures/dict.pyi] +[case testDecoratorWithDeclaredTypeBare] + +from typing import Callable +from mypy_extensions import decorated_type + +@decorated_type(Callable[[int], str]) +def f(x): pass + +f("a") # E: Argument 1 to "f" has incompatible type "str"; expected "int" +x: str = f(1) +y: int = f(1) # E: Incompatible types in assignment (expression has type "str", variable has type "int") +reveal_type(f) # E: Revealed type is 'def (builtins.int) -> builtins.str' + +[builtins fixtures/dict.pyi] + +[case testDecoratorWithDeclaredTypeIncompatible] + +from typing import Callable, TypeVar +from mypy_extensions import decorated_type + +T = TypeVar('T') + +def dec(f: T) -> T: pass + +@decorated_type(Callable[[int], str]) # E: Incompatible types (inferred decorated type Callable[[str], str], decalred decorated type Callable[[int], str]) +@dec +def f(x: str) -> str: pass + +[builtins fixtures/dict.pyi] + +[case testDecoratorWithDeclaredTypeNotTop] + +from typing import Callable +from mypy_extensions import decorated_type + +def dec(f): pass + +@dec +@decorated_type(Callable[[int], str]) # E: "decorated_type" must be the topmost decorator +def f(): pass + +[builtins fixtures/dict.pyi] + +[case testDecoratorWithDeclaredTypeNoArgs] + +from typing import Callable +from mypy_extensions import decorated_type + +def dec(f): pass + +@decorated_type() # E: "decorated_type" takes exactly one argument +@dec +def f(): pass + +[builtins fixtures/dict.pyi] + +[case testDecoratorWithDeclaredTypeNoCall] + +from typing import Callable +from mypy_extensions import decorated_type + +def dec(f): pass + +@decorated_type # E: "decorated_type" must have a type as an argument +@dec +def f(): pass + +[builtins fixtures/dict.pyi] + [case testNestedDecorators] from typing import Any, Callable def dec1(f: Callable[[Any], None]) -> Callable[[], None]: pass From 6af0979f17e6313a3e2e1ab60a3e644b0e07e617 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 15:48:07 -1000 Subject: [PATCH 03/10] Make first-stage generator inference give up on async coroutines --- mypy/semanal.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mypy/semanal.py b/mypy/semanal.py index 0b4a5afb28e7..1c5aa574cbf3 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -3617,6 +3617,10 @@ def visit_decorator(self, dec: Decorator) -> None: if dec.var.type is not None: # We already have a declared type for this decorated thing. return + if dec.func.is_awaitable_coroutine: + # The type here will be fixed up by checker.py, but we can't infer + # anything here. + return if dec.var.is_property: # Decorators are expected to have a callable type (it's a little odd). if dec.func.type is None: @@ -3655,6 +3659,7 @@ def visit_decorator(self, dec: Decorator) -> None: orig_sig = function_type(dec.func, self.builtin_type('function')) sig.name = orig_sig.items()[0].name dec.var.type = sig + print("Decorated var type of", dec.var.name(), "is now", dec.var.type) def visit_assignment_stmt(self, s: AssignmentStmt) -> None: self.analyze(s.type) From c739cefb935bddf0709d8da50f9c86c3c9839d24 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 15:50:00 -1000 Subject: [PATCH 04/10] lint --- extensions/mypy_extensions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/mypy_extensions.py b/extensions/mypy_extensions.py index ef6c052f6121..6db23af023d1 100644 --- a/extensions/mypy_extensions.py +++ b/extensions/mypy_extensions.py @@ -96,6 +96,7 @@ class Point2D(TypedDict): # Return type that indicates a function does not return class NoReturn: pass + def decorated_type(t): """Declared the decorated type of a decorated item""" # Return the identity function -- calling this should be a noop From f0f30f4f4d37cd4be85626eaee9d64508ceee251 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 21:57:51 -0700 Subject: [PATCH 05/10] typo --- mypy/checker.py | 2 +- test-data/unit/check-functions.test | 2 +- typeshed | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 6df5131685f7..a563189eaf08 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2220,7 +2220,7 @@ def visit_decorator(self, e: Decorator) -> None: # We have a declared type, check it. self.check_subtype(sig, e.var.type, e, subtype_label="inferred decorated type", - supertype_label="decalred decorated type") + supertype_label="declared decorated type") else: e.var.type = sig e.var.type = set_callable_name(e.var.type, e.func) diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 006c807554fe..4dbceb9b504a 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -776,7 +776,7 @@ T = TypeVar('T') def dec(f: T) -> T: pass -@decorated_type(Callable[[int], str]) # E: Incompatible types (inferred decorated type Callable[[str], str], decalred decorated type Callable[[int], str]) +@decorated_type(Callable[[int], str]) # E: Incompatible types (inferred decorated type Callable[[str], str], declared decorated type Callable[[int], str]) @dec def f(x: str) -> str: pass diff --git a/typeshed b/typeshed index c05570cf0069..1f6922d3aa8f 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit c05570cf00698c3f8942cc3c8de37fc4de6f17db +Subproject commit 1f6922d3aa8f0dc6b79c3052873b2ab02058b1fe From a5ebef76edfdf20f2a985b3c4a53f496263999e6 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 22:03:59 -0700 Subject: [PATCH 06/10] update typeshed --- typeshed | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typeshed b/typeshed index 1f6922d3aa8f..07280965417b 160000 --- a/typeshed +++ b/typeshed @@ -1 +1 @@ -Subproject commit 1f6922d3aa8f0dc6b79c3052873b2ab02058b1fe +Subproject commit 07280965417b0a9cbd5bd2d9a8a0c68208ab4210 From 7bba6100377a2509e72d35a24545f3e17fb6226c Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sun, 30 Apr 2017 22:13:12 -0700 Subject: [PATCH 07/10] Oops errant prints --- mypy/semanal.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 1c5aa574cbf3..663f03414b16 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2446,7 +2446,6 @@ def visit_decorator(self, dec: Decorator) -> None: self.fail('"decorated_type" takes exactly one argument', d) else: dec.var.type = self.expr_to_analyzed_type(d.args[0]) - print("Set type", dec.var.type) elif (refers_to_fullname(d, 'typing.decorated_type') or refers_to_fullname(d, 'mypy_extensions.decorated_type')): self.fail('"decorated_type" must have a type as an argument', d) @@ -3659,7 +3658,6 @@ def visit_decorator(self, dec: Decorator) -> None: orig_sig = function_type(dec.func, self.builtin_type('function')) sig.name = orig_sig.items()[0].name dec.var.type = sig - print("Decorated var type of", dec.var.name(), "is now", dec.var.type) def visit_assignment_stmt(self, s: AssignmentStmt) -> None: self.analyze(s.type) From 19a0964c1115042afc94fc16ec668fc29512b601 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Tue, 2 May 2017 14:17:47 -0700 Subject: [PATCH 08/10] More tests that Jukka asked for --- test-data/unit/check-functions.test | 94 +++++++++++++++++++++ test-data/unit/fixtures/dict.pyi | 4 + test-data/unit/lib-stub/mypy_extensions.pyi | 4 +- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 4dbceb9b504a..938d0ae973ac 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -733,6 +733,74 @@ a = None # type: A a.f() a.f(None) # E: Too many arguments for "f" of "A" +[case testMethodWithDeclaredDecoratedType] + +from typing import Callable, Any +from mypy_extensions import decorated_type + +def dec(f): pass + +# Note that the decorated type must account for the `self` argument -- It's applied pre-binding +class Foo: + @decorated_type(Callable[[Any, int], str]) + @dec + def f(self): pass + +foo = Foo() + +foo.f("a") # E: Argument 1 to "f" of "Foo" has incompatible type "str"; expected "int" +x: str = foo.f(1) +y: int = foo.f(1) # E: Incompatible types in assignment (expression has type "str", variable has type "int") + +reveal_type(foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' + +[builtins fixtures/dict.pyi] + +[case testClassMethodWithDeclaredDecoratedType] + +from typing import Callable, Any +from mypy_extensions import decorated_type + +def dec(f): pass + +# Note that the decorated type must account for the `cls` argument -- It's applied pre-binding +class Foo: + @decorated_type(Callable[[Any, int], str]) + @classmethod + @dec + def f(cls): pass + + +Foo.f("a") # E: Argument 1 to "f" of "Foo" has incompatible type "str"; expected "int" +x: str = Foo.f(1) +y: int = Foo.f(1) # E: Incompatible types in assignment (expression has type "str", variable has type "int") + +reveal_type(Foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' + +[builtins fixtures/dict.pyi] + +[case testStaticMethodWithDeclaredDecoratedType] + +from typing import Callable +from mypy_extensions import decorated_type + +def dec(f): pass + +class Foo: + @decorated_type(Callable[[int], str]) + @staticmethod + @dec + def f(): pass + + +Foo.f("a") # E: Argument 1 to "f" of "Foo" has incompatible type "str"; expected "int" +x: str = Foo.f(1) +y: int = Foo.f(1) # E: Incompatible types in assignment (expression has type "str", variable has type "int") + +reveal_type(Foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' + +[builtins fixtures/dict.pyi] + [case testUntypedDecoratorWithDeclaredType] from typing import Callable @@ -782,6 +850,25 @@ def f(x: str) -> str: pass [builtins fixtures/dict.pyi] +[case testDecoratorWithDeclaredTypeCompatible] + +from typing import Callable, TypeVar +from mypy_extensions import decorated_type + +T = TypeVar('T') + +def dec(f: T) -> T: pass + +class A: pass +class B(A): pass + +@decorated_type(Callable[[B], str]) +@dec +def f(x: A) -> str: pass + +reveal_type(f) # E: Revealed type is 'def (__main__.B) -> builtins.str' +[builtins fixtures/dict.pyi] + [case testDecoratorWithDeclaredTypeNotTop] from typing import Callable @@ -793,6 +880,8 @@ def dec(f): pass @decorated_type(Callable[[int], str]) # E: "decorated_type" must be the topmost decorator def f(): pass +reveal_type(f) # E: Revealed type is 'Any' + [builtins fixtures/dict.pyi] [case testDecoratorWithDeclaredTypeNoArgs] @@ -806,6 +895,8 @@ def dec(f): pass @dec def f(): pass +reveal_type(f) # E: Revealed type is 'Any' + [builtins fixtures/dict.pyi] [case testDecoratorWithDeclaredTypeNoCall] @@ -819,6 +910,9 @@ def dec(f): pass @dec def f(): pass +# NB: The revealed type below is technically correct, as weird as it looks +reveal_type(f) # E: Revealed type is 'def [T] (T`-1) -> T`-1' + [builtins fixtures/dict.pyi] [case testNestedDecorators] diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index dc89366c1133..424b7dd9bddb 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -40,3 +40,7 @@ class float: pass class bool: pass class BaseException: pass + +# Because all tests that use mypy_extensions need dict, this is easier. +classmethod = object() +staticmethod = object() \ No newline at end of file diff --git a/test-data/unit/lib-stub/mypy_extensions.pyi b/test-data/unit/lib-stub/mypy_extensions.pyi index 87ba6e74f965..092d57ee4b19 100644 --- a/test-data/unit/lib-stub/mypy_extensions.pyi +++ b/test-data/unit/lib-stub/mypy_extensions.pyi @@ -1,4 +1,4 @@ -from typing import Dict, Type, TypeVar, Callable +from typing import Dict, Type, TypeVar, Callable, Any T = TypeVar('T') @@ -7,4 +7,4 @@ def TypedDict(typename: str, fields: Dict[str, Type[T]]) -> Type[dict]: pass class NoReturn: pass -def decorated_type(t: Type) -> Callable[[T], T]: pass \ No newline at end of file +def decorated_type(t: Any) -> Callable[[T], T]: pass \ No newline at end of file From 8c803da339a90bc4f0464bfc27b608526c48ed2c Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Tue, 2 May 2017 14:22:37 -0700 Subject: [PATCH 09/10] Newline at end of file --- test-data/unit/fixtures/dict.pyi | 2 +- test-data/unit/lib-stub/mypy_extensions.pyi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-data/unit/fixtures/dict.pyi b/test-data/unit/fixtures/dict.pyi index 424b7dd9bddb..79389ef053eb 100644 --- a/test-data/unit/fixtures/dict.pyi +++ b/test-data/unit/fixtures/dict.pyi @@ -43,4 +43,4 @@ class BaseException: pass # Because all tests that use mypy_extensions need dict, this is easier. classmethod = object() -staticmethod = object() \ No newline at end of file +staticmethod = object() diff --git a/test-data/unit/lib-stub/mypy_extensions.pyi b/test-data/unit/lib-stub/mypy_extensions.pyi index 092d57ee4b19..756e40c0fff0 100644 --- a/test-data/unit/lib-stub/mypy_extensions.pyi +++ b/test-data/unit/lib-stub/mypy_extensions.pyi @@ -7,4 +7,4 @@ def TypedDict(typename: str, fields: Dict[str, Type[T]]) -> Type[dict]: pass class NoReturn: pass -def decorated_type(t: Any) -> Callable[[T], T]: pass \ No newline at end of file +def decorated_type(t: Any) -> Callable[[T], T]: pass From 145e38635d60fde4ec07ceb6df95b58ca24a919f Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 14 Jun 2017 21:35:54 -0700 Subject: [PATCH 10/10] Change decorated_type to declared_type --- extensions/mypy_extensions.py | 8 +++-- mypy/semanal.py | 14 ++++---- test-data/unit/check-functions.test | 40 ++++++++++----------- test-data/unit/lib-stub/mypy_extensions.pyi | 2 +- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/extensions/mypy_extensions.py b/extensions/mypy_extensions.py index 98f8e39df9cf..afc3fe9754f1 100644 --- a/extensions/mypy_extensions.py +++ b/extensions/mypy_extensions.py @@ -133,7 +133,11 @@ def KwArg(type=Any): class NoReturn: pass -def decorated_type(t): - """Declared the decorated type of a decorated item""" +def declared_type(t): + """Declare the type of a declaration. + + This is useful for declaring a more specific type for a decorated class or + function definition than the decorator provides as a return value. + """ # Return the identity function -- calling this should be a noop return lambda __x: __x diff --git a/mypy/semanal.py b/mypy/semanal.py index 90635469c106..29c55813c4dc 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2634,18 +2634,18 @@ def visit_decorator(self, dec: Decorator) -> None: dec.var.type = AnyType() no_type_check = True elif isinstance(d, CallExpr) and ( - refers_to_fullname(d.callee, 'typing.decorated_type') - or refers_to_fullname(d.callee, 'mypy_extensions.decorated_type')): + refers_to_fullname(d.callee, 'typing.declared_type') + or refers_to_fullname(d.callee, 'mypy_extensions.declared_type')): removed.append(i) if i != 0: - self.fail('"decorated_type" must be the topmost decorator', d) + self.fail('"declared_type" must be the topmost decorator', d) elif len(d.args) != 1: - self.fail('"decorated_type" takes exactly one argument', d) + self.fail('"declared_type" takes exactly one argument', d) else: dec.var.type = self.expr_to_analyzed_type(d.args[0]) - elif (refers_to_fullname(d, 'typing.decorated_type') or - refers_to_fullname(d, 'mypy_extensions.decorated_type')): - self.fail('"decorated_type" must have a type as an argument', d) + elif (refers_to_fullname(d, 'typing.declared_type') or + refers_to_fullname(d, 'mypy_extensions.declared_type')): + self.fail('"declared_type" must have a type as an argument', d) for i in reversed(removed): del dec.decorators[i] if not dec.is_overload or dec.var.is_property: diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 013cdde5e663..9e901af721c3 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -737,13 +737,13 @@ a.f(None) # E: Too many arguments for "f" of "A" [case testMethodWithDeclaredDecoratedType] from typing import Callable, Any -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass # Note that the decorated type must account for the `self` argument -- It's applied pre-binding class Foo: - @decorated_type(Callable[[Any, int], str]) + @declared_type(Callable[[Any, int], str]) @dec def f(self): pass @@ -760,13 +760,13 @@ reveal_type(foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [case testClassMethodWithDeclaredDecoratedType] from typing import Callable, Any -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass # Note that the decorated type must account for the `cls` argument -- It's applied pre-binding class Foo: - @decorated_type(Callable[[Any, int], str]) + @declared_type(Callable[[Any, int], str]) @classmethod @dec def f(cls): pass @@ -783,12 +783,12 @@ reveal_type(Foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [case testStaticMethodWithDeclaredDecoratedType] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass class Foo: - @decorated_type(Callable[[int], str]) + @declared_type(Callable[[int], str]) @staticmethod @dec def f(): pass @@ -805,11 +805,11 @@ reveal_type(Foo.f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [case testUntypedDecoratorWithDeclaredType] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass -@decorated_type(Callable[[int], str]) +@declared_type(Callable[[int], str]) @dec def f(): pass @@ -824,9 +824,9 @@ reveal_type(f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [case testDecoratorWithDeclaredTypeBare] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type -@decorated_type(Callable[[int], str]) +@declared_type(Callable[[int], str]) def f(x): pass f("a") # E: Argument 1 to "f" has incompatible type "str"; expected "int" @@ -839,13 +839,13 @@ reveal_type(f) # E: Revealed type is 'def (builtins.int) -> builtins.str' [case testDecoratorWithDeclaredTypeIncompatible] from typing import Callable, TypeVar -from mypy_extensions import decorated_type +from mypy_extensions import declared_type T = TypeVar('T') def dec(f: T) -> T: pass -@decorated_type(Callable[[int], str]) # E: Incompatible types (inferred decorated type Callable[[str], str], declared decorated type Callable[[int], str]) +@declared_type(Callable[[int], str]) # E: Incompatible types (inferred decorated type Callable[[str], str], declared decorated type Callable[[int], str]) @dec def f(x: str) -> str: pass @@ -854,7 +854,7 @@ def f(x: str) -> str: pass [case testDecoratorWithDeclaredTypeCompatible] from typing import Callable, TypeVar -from mypy_extensions import decorated_type +from mypy_extensions import declared_type T = TypeVar('T') @@ -863,7 +863,7 @@ def dec(f: T) -> T: pass class A: pass class B(A): pass -@decorated_type(Callable[[B], str]) +@declared_type(Callable[[B], str]) @dec def f(x: A) -> str: pass @@ -873,12 +873,12 @@ reveal_type(f) # E: Revealed type is 'def (__main__.B) -> builtins.str' [case testDecoratorWithDeclaredTypeNotTop] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass @dec -@decorated_type(Callable[[int], str]) # E: "decorated_type" must be the topmost decorator +@declared_type(Callable[[int], str]) # E: "declared_type" must be the topmost decorator def f(): pass reveal_type(f) # E: Revealed type is 'Any' @@ -888,11 +888,11 @@ reveal_type(f) # E: Revealed type is 'Any' [case testDecoratorWithDeclaredTypeNoArgs] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass -@decorated_type() # E: "decorated_type" takes exactly one argument +@declared_type() # E: "declared_type" takes exactly one argument @dec def f(): pass @@ -903,11 +903,11 @@ reveal_type(f) # E: Revealed type is 'Any' [case testDecoratorWithDeclaredTypeNoCall] from typing import Callable -from mypy_extensions import decorated_type +from mypy_extensions import declared_type def dec(f): pass -@decorated_type # E: "decorated_type" must have a type as an argument +@declared_type # E: "declared_type" must have a type as an argument @dec def f(): pass diff --git a/test-data/unit/lib-stub/mypy_extensions.pyi b/test-data/unit/lib-stub/mypy_extensions.pyi index 95b3d7ec0071..518686391d74 100644 --- a/test-data/unit/lib-stub/mypy_extensions.pyi +++ b/test-data/unit/lib-stub/mypy_extensions.pyi @@ -20,4 +20,4 @@ def TypedDict(typename: str, fields: Dict[str, Type[_T]]) -> Type[dict]: ... class NoReturn: pass -def decorated_type(t: Any) -> Callable[[T], T]: pass +def declared_type(t: Any) -> Callable[[T], T]: pass