From 3347847edd475e35b2f21b89ba436df37337db9d Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 22 Dec 2022 14:42:45 +0000 Subject: [PATCH] Optimization: Avoid a few uses of contextmanagers in semantic analyzer This helps mypyc. (Various small optimizations, including this, together netted a 6% performance improvement in self check.) --- mypy/semanal.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 916009702830..eceb96ca63ee 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -50,7 +50,7 @@ from __future__ import annotations -from contextlib import contextmanager, nullcontext +from contextlib import contextmanager from typing import Any, Callable, Collection, Iterable, Iterator, List, TypeVar, cast from typing_extensions import Final, TypeAlias as _TypeAlias @@ -2645,11 +2645,15 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None: # But we can't use a full visit because it may emit extra incomplete refs (namely # when analysing any type applications there) thus preventing the further analysis. # To break the tie, we first analyse rvalue partially, if it can be a type alias. - with self.basic_type_applications_set(s): - with self.allow_unbound_tvars_set() if self.can_possibly_be_index_alias( - s - ) else nullcontext(): + if self.can_possibly_be_index_alias(s): + old_basic_type_applications = self.basic_type_applications + self.basic_type_applications = True + with self.allow_unbound_tvars_set(): s.rvalue.accept(self) + self.basic_type_applications = old_basic_type_applications + else: + s.rvalue.accept(self) + if self.found_incomplete_ref(tag) or self.should_wait_rhs(s.rvalue): # Initializer couldn't be fully analyzed. Defer the current node and give up. # Make sure that if we skip the definition of some local names, they can't be @@ -2819,17 +2823,6 @@ def can_possibly_be_index_alias(self, s: AssignmentStmt) -> bool: # Something that looks like Foo = Bar[Baz, ...] return True - @contextmanager - def basic_type_applications_set(self, s: AssignmentStmt) -> Iterator[None]: - old = self.basic_type_applications - # As an optimization, only use the double visit logic if this - # can possibly be a recursive type alias. - self.basic_type_applications = self.can_possibly_be_index_alias(s) - try: - yield - finally: - self.basic_type_applications = old - def is_type_ref(self, rv: Expression, bare: bool = False) -> bool: """Does this expression refer to a type?