diff --git a/mypy/semanal.py b/mypy/semanal.py index 790c0c6d96d7..dfffaf4a71f1 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1109,7 +1109,8 @@ def analyze_namedtuple_classdef(self, defn: ClassDef) -> bool: # in the named tuple class body. is_named_tuple, info = True, defn.info # type: bool, Optional[TypeInfo] else: - is_named_tuple, info = self.named_tuple_analyzer.analyze_namedtuple_classdef(defn) + is_named_tuple, info = self.named_tuple_analyzer.analyze_namedtuple_classdef( + defn, self.is_stub_file) if is_named_tuple: if info is None: self.mark_incomplete(defn.name, defn) diff --git a/mypy/semanal_namedtuple.py b/mypy/semanal_namedtuple.py index e0ba44885cfa..da65f6f063d2 100644 --- a/mypy/semanal_namedtuple.py +++ b/mypy/semanal_namedtuple.py @@ -41,7 +41,8 @@ def __init__(self, options: Options, api: SemanticAnalyzerInterface) -> None: self.options = options self.api = api - def analyze_namedtuple_classdef(self, defn: ClassDef) -> Tuple[bool, Optional[TypeInfo]]: + def analyze_namedtuple_classdef(self, defn: ClassDef, is_stub_file: bool + ) -> Tuple[bool, Optional[TypeInfo]]: """Analyze if given class definition can be a named tuple definition. Return a tuple where first item indicates whether this can possibly be a named tuple, @@ -52,7 +53,7 @@ def analyze_namedtuple_classdef(self, defn: ClassDef) -> Tuple[bool, Optional[Ty if isinstance(base_expr, RefExpr): self.api.accept(base_expr) if base_expr.fullname == 'typing.NamedTuple': - result = self.check_namedtuple_classdef(defn) + result = self.check_namedtuple_classdef(defn, is_stub_file) if result is None: # This is a valid named tuple, but some types are incomplete. return True, None @@ -68,8 +69,10 @@ def analyze_namedtuple_classdef(self, defn: ClassDef) -> Tuple[bool, Optional[Ty # This can't be a valid named tuple. return False, None - def check_namedtuple_classdef( - self, defn: ClassDef) -> Optional[Tuple[List[str], List[Type], Dict[str, Expression]]]: + def check_namedtuple_classdef(self, defn: ClassDef, is_stub_file: bool + ) -> Optional[Tuple[List[str], + List[Type], + Dict[str, Expression]]]: """Parse and validate fields in named tuple class definition. Return a three tuple: @@ -78,7 +81,7 @@ def check_namedtuple_classdef( * field default values or None, if any of the types are not ready. """ - if self.options.python_version < (3, 6): + if self.options.python_version < (3, 6) and not is_stub_file: self.fail('NamedTuple class syntax is only supported in Python 3.6', defn) return [], [], {} if len(defn.base_type_exprs) > 1: diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 6d8626456403..c215fb7d7a97 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -44,6 +44,24 @@ x.x x.y x.z # E: "X" has no attribute "z" +[case testNamedTupleClassPython35] +# flags: --python-version 3.5 +from typing import NamedTuple + +class A(NamedTuple): + x = 3 # type: int +[out] +main:4: error: NamedTuple class syntax is only supported in Python 3.6 + +[case testNamedTupleClassInStubPython35] +# flags: --python-version 3.5 +import foo + +[file foo.pyi] +from typing import NamedTuple + +class A(NamedTuple): + x: int [case testNamedTupleAttributesAreReadOnly] from collections import namedtuple 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