Skip to content

Commit 1dd8690

Browse files
committed
Make semanal's side faster
1 parent 806266c commit 1dd8690

1 file changed

Lines changed: 86 additions & 17 deletions

File tree

mypy/semanal.py

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ def __init__(
547547
self.transitive_submodule_imports: dict[str, set[str]] = {}
548548

549549
self.delayed_errors: dict[tuple[str, int, int], list[ErrorInfo]] = {}
550+
self.associated_node: Statement | None = None
550551

551552
# mypyc doesn't properly handle implementing an abstractproperty
552553
# with a regular attribute so we make them properties
@@ -7554,7 +7555,7 @@ def fail(
75547555
if code is None:
75557556
code = msg.code
75567557
msg = msg.value
7557-
self.errors.report(
7558+
err_info = self.create_error_info(
75587559
ctx.line,
75597560
ctx.column,
75607561
msg,
@@ -7563,11 +7564,86 @@ def fail(
75637564
end_line=ctx.end_line,
75647565
end_column=ctx.end_column,
75657566
)
7567+
if self.errors._filter_error(self.errors.file, err_info):
7568+
return
7569+
7570+
if self.associated_node is None or self.options.semantic_analysis_only:
7571+
self.errors.add_error_info(err_info)
7572+
else:
7573+
node = self.associated_node
7574+
assign_to = (self.cur_mod_id, node.line, node.column)
7575+
self.delayed_errors.setdefault(assign_to, [])
7576+
self.delayed_errors[assign_to].append(err_info)
75667577

75677578
def note(self, msg: str, ctx: Context, code: ErrorCode | None = None) -> None:
75687579
if not self.in_checked_function():
75697580
return
7570-
self.errors.report(ctx.line, ctx.column, msg, severity="note", code=code)
7581+
err_info = self.create_error_info(ctx.line, ctx.column, msg, severity="note", code=code)
7582+
if self.errors._filter_error(self.errors.file, err_info):
7583+
return
7584+
7585+
if self.associated_node is None or self.options.semantic_analysis_only:
7586+
self.errors.add_error_info(err_info)
7587+
else:
7588+
node = self.associated_node
7589+
assign_to = (self.cur_mod_id, node.line, node.column)
7590+
self.delayed_errors.setdefault(assign_to, [])
7591+
self.delayed_errors[assign_to].append(err_info)
7592+
7593+
def create_error_info(
7594+
self,
7595+
line: int,
7596+
column: int | None,
7597+
message: str,
7598+
code: ErrorCode | None = None,
7599+
*,
7600+
blocker: bool = False,
7601+
severity: str = "error",
7602+
end_line: int | None = None,
7603+
end_column: int | None = None,
7604+
) -> ErrorInfo:
7605+
# TODO: move this into `errors.py`, probably
7606+
if self.errors.scope:
7607+
type = self.errors.scope.current_type_name()
7608+
if self.errors.scope.ignored > 0:
7609+
type = None # Omit type context if nested function
7610+
function = self.errors.scope.current_function_name()
7611+
else:
7612+
type = None
7613+
function = None
7614+
7615+
if column is None:
7616+
column = -1
7617+
if end_column is None:
7618+
if column == -1:
7619+
end_column = -1
7620+
else:
7621+
end_column = column + 1
7622+
7623+
if end_line is None:
7624+
end_line = line
7625+
7626+
code = code or (codes.MISC if not blocker else None)
7627+
7628+
return ErrorInfo(
7629+
import_ctx=self.errors.import_context(),
7630+
file=self.errors.file,
7631+
module=self.errors.current_module(),
7632+
typ=type,
7633+
function_or_member=function,
7634+
line=line,
7635+
column=column,
7636+
end_line=end_line,
7637+
end_column=end_column,
7638+
severity=severity,
7639+
message=message,
7640+
code=code,
7641+
blocker=blocker,
7642+
only_once=False,
7643+
origin=(self.errors.file, [line]),
7644+
target=self.errors.current_target(),
7645+
parent_error=None,
7646+
)
75717647

75727648
def incomplete_feature_enabled(self, feature: str, ctx: Context) -> bool:
75737649
if feature not in self.options.enable_incomplete_feature:
@@ -7579,21 +7655,14 @@ def incomplete_feature_enabled(self, feature: str, ctx: Context) -> bool:
75797655
return False
75807656
return True
75817657

7582-
def accept_delaying_errors(self, node: Node) -> None:
7583-
should_filter = isinstance(node, Statement) and not self.options.semantic_analysis_only
7584-
if should_filter:
7585-
filter_errors: bool | Callable[[str, ErrorInfo], bool] = lambda _, e: not e.blocker
7586-
else:
7587-
filter_errors = False
7588-
with self.msg.filter_errors(filter_errors=filter_errors, save_filtered_errors=True) as msg:
7589-
self.accept(node)
7590-
7591-
errors = msg.filtered_errors()
7592-
if errors:
7593-
# since nodes don't implement hash(), carry things through values
7594-
assign_to = (self.cur_mod_id, node.line, node.column)
7595-
self.delayed_errors.setdefault(assign_to, [])
7596-
self.delayed_errors[assign_to].extend(errors)
7658+
def accept_delaying_errors(self, node: Statement) -> None:
7659+
previously_associated = self.associated_node
7660+
self.associated_node = node
7661+
try:
7662+
node.accept(self)
7663+
except Exception as err:
7664+
report_internal_error(err, self.errors.file, node.line, self.errors, self.options)
7665+
self.associated_node = previously_associated
75977666

75987667
def accept(self, node: Node) -> None:
75997668
try:

0 commit comments

Comments
 (0)