From 9275c248abffa169f07d4a97e98fedf9decfa021 Mon Sep 17 00:00:00 2001 From: Kamil Turek Date: Fri, 5 Mar 2021 00:06:05 +0100 Subject: [PATCH] Skip checking class scope if decorator applied --- mypy/checker.py | 7 ++++++- test-data/unit/check-classes.test | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index fce7e7d7a08e..f18af81dd80e 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1720,7 +1720,10 @@ def visit_class_def(self, defn: ClassDef) -> None: self.binder = ConditionalTypeBinder() with self.binder.top_frame_context(): with self.scope.push_class(defn.info): - self.accept(defn.defs) + if not any(refers_to_fullname(decorator, + 'typing.no_type_check') + for decorator in defn.decorators): + self.accept(defn.defs) self.binder = old_binder if not (defn.info.typeddict_type or defn.info.tuple_type or defn.info.is_enum): # If it is not a normal class (not a special form) check class keywords. @@ -1733,6 +1736,8 @@ def visit_class_def(self, defn: ClassDef) -> None: sig = type_object_type(defn.info, self.named_type) # type: Type # Decorators are applied in reverse order. for decorator in reversed(defn.decorators): + if refers_to_fullname(decorator, 'typing.no_type_check'): + continue if (isinstance(decorator, CallExpr) and isinstance(decorator.analyzed, PromoteExpr)): # _promote is a special type checking related construct. diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 49e52c2102a5..248bcd589d0c 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -388,6 +388,15 @@ class A: class B(A): # E: Missing positional argument "x" in call to "__init_subclass__" of "A" def __init_subclass__(cls) -> None: pass +[case testNoTypeCheckDecoratorOnClass] +import typing + +@typing.no_type_check +class A: + def f(self) -> None: + 1 + 'x' +[typing fixtures/typing-medium.pyi] + [case testOverrideWithDecorator] from typing import Callable