From 197973089d3721d63236f356c931e8c865b8aada Mon Sep 17 00:00:00 2001 From: Danny Weinberg Date: Wed, 20 Mar 2019 14:02:48 -0700 Subject: [PATCH 1/2] Don't resolve Callable NamedTuple fields to their return type `NamedTuple` fields are always marked an properties. In certain situations, this causes their type to be determined incorrectly when they hold `Callable`s, resolving to the `Callable`'s return type rather than the `Callable` itself. This prevents that and fixes https://github.com/python/mypy/issues/6575. --- mypy/subtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index f6a0b52b0028..6e1f99946594 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -622,7 +622,7 @@ def find_node_type(node: Union[Var, FuncBase], itype: Instance, subtype: Type) - if isinstance(node, FuncBase) or isinstance(typ, FunctionLike) and not node.is_staticmethod: assert isinstance(typ, FunctionLike) signature = bind_self(typ, subtype) - if node.is_property: + if node.is_property and not node.info.is_named_tuple: assert isinstance(signature, CallableType) typ = signature.ret_type else: From a25c96875e2c8bdf85eeed3868ac885e17787ee5 Mon Sep 17 00:00:00 2001 From: Danny Weinberg Date: Thu, 21 Mar 2019 11:43:03 -0700 Subject: [PATCH 2/2] Instead use `is_initialized_in_class` to skip the entire 'self' binding. Add tests. --- mypy/subtypes.py | 7 +++++-- test-data/unit/check-protocols.test | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 6e1f99946594..8c08ea873b6c 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -619,10 +619,13 @@ def find_node_type(node: Union[Var, FuncBase], itype: Instance, subtype: Type) - if typ is None: return AnyType(TypeOfAny.from_error) # We don't need to bind 'self' for static methods, since there is no 'self'. - if isinstance(node, FuncBase) or isinstance(typ, FunctionLike) and not node.is_staticmethod: + if (isinstance(node, FuncBase) + or (isinstance(typ, FunctionLike) + and node.is_initialized_in_class + and not node.is_staticmethod)): assert isinstance(typ, FunctionLike) signature = bind_self(typ, subtype) - if node.is_property and not node.info.is_named_tuple: + if node.is_property: assert isinstance(signature, CallableType) typ = signature.ret_type else: diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index 0456ab31bada..c4c37aaa5eec 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -2444,3 +2444,29 @@ class P(Protocol[T]): @alias def meth(self, arg: T) -> T: ... [out] + +[case testNamedTupleWithNoArgsCallableField] +from typing import Callable, NamedTuple, Protocol + +class N(NamedTuple): + func: Callable[[], str] + +class P(Protocol): + @property + def func(self) -> Callable[[], str]: ... + +p: P = N(lambda: 'foo') +[builtins fixtures/property.pyi] + +[case testNamedTupleWithManyArgsCallableField] +from typing import Callable, NamedTuple, Protocol + +class N(NamedTuple): + func: Callable[[str, str, str], str] + +class P(Protocol): + @property + def func(self) -> Callable[[str, str, str], str]: ... + +p: P = N(lambda a, b, c: 'foo') +[builtins fixtures/property.pyi] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy