Skip to content

Commit

Permalink
Optimization: Avoid a few uses of contextmanagers in semantic analyzer (
Browse files Browse the repository at this point in the history
#14360)

This helps mypyc.

(Various small optimizations, including this, together netted a 6%
performance improvement in self check.)
  • Loading branch information
JukkaL authored Dec 28, 2022
1 parent c29a414 commit 8e7e220
Showing 1 changed file with 9 additions and 16 deletions.
25 changes: 9 additions & 16 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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?
Expand Down

0 comments on commit 8e7e220

Please sign in to comment.