Skip to content

Commit a9ee618

Browse files
meshyAlexWaygood
andauthored
Fix disappearing errors when re-running dmypy check (#14835)
This adds a commit which fixes issue #9655 wherein some types of error would be lost when a file was re-processed by dmypy. Regression tests are also included. This also fixes another error where sometimes files would not be re-processed by dmypy if the only error in the file was either "unused type ignore" or "ignore without code". <!-- If this pull request fixes an issue, add "Fixes #NNN" with the issue number. --> <!-- Checklist: - Read the [Contributing Guidelines](https://github.com/python/mypy/blob/master/CONTRIBUTING.md) - Add tests for all changed behaviour. - If you can't add a test, please explain why and how you verified your changes work. - Make sure CI passes. - Please do not force push to the PR once it has been reviewed. --> --------- Co-authored-by: AlexWaygood <[email protected]>
1 parent e21ddbf commit a9ee618

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

mypy/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,8 @@ def generate_unused_ignore_errors(self, file: str) -> None:
668668
False,
669669
False,
670670
False,
671+
origin=(self.file, [line]),
672+
target=self.target_module,
671673
)
672674
self._add_error_info(file, info)
673675

@@ -720,6 +722,8 @@ def generate_ignore_without_code_errors(
720722
False,
721723
False,
722724
False,
725+
origin=(self.file, [line]),
726+
target=self.target_module,
723727
)
724728
self._add_error_info(file, info)
725729

mypy/server/update.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ def restore(ids: list[str]) -> None:
667667
state.type_check_first_pass()
668668
state.type_check_second_pass()
669669
state.detect_possibly_undefined_vars()
670+
state.generate_unused_ignore_notes()
671+
state.generate_ignore_without_code_notes()
670672
t2 = time.time()
671673
state.finish_passes()
672674
t3 = time.time()
@@ -1027,6 +1029,10 @@ def key(node: FineGrainedDeferredNode) -> int:
10271029
if graph[module_id].type_checker().check_second_pass():
10281030
more = True
10291031

1032+
graph[module_id].detect_possibly_undefined_vars()
1033+
graph[module_id].generate_unused_ignore_notes()
1034+
graph[module_id].generate_ignore_without_code_notes()
1035+
10301036
if manager.options.export_types:
10311037
manager.all_types.update(graph[module_id].type_map())
10321038

test-data/unit/daemon.test

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,3 +522,92 @@ class A:
522522
x: int
523523
class B:
524524
x: int
525+
526+
[case testUnusedTypeIgnorePreservedOnRerun]
527+
-- Regression test for https://github.com/python/mypy/issues/9655
528+
$ dmypy start -- --warn-unused-ignores --no-error-summary
529+
Daemon started
530+
$ dmypy check -- bar.py
531+
bar.py:2: error: Unused "type: ignore" comment
532+
== Return code: 1
533+
$ dmypy check -- bar.py
534+
bar.py:2: error: Unused "type: ignore" comment
535+
== Return code: 1
536+
537+
[file foo/__init__.py]
538+
[file foo/empty.py]
539+
[file bar.py]
540+
from foo.empty import *
541+
a = 1 # type: ignore
542+
543+
[case testTypeIgnoreWithoutCodePreservedOnRerun]
544+
-- Regression test for https://github.com/python/mypy/issues/9655
545+
$ dmypy start -- --enable-error-code ignore-without-code --no-error-summary
546+
Daemon started
547+
$ dmypy check -- bar.py
548+
bar.py:2: error: "type: ignore" comment without error code [ignore-without-code]
549+
== Return code: 1
550+
$ dmypy check -- bar.py
551+
bar.py:2: error: "type: ignore" comment without error code [ignore-without-code]
552+
== Return code: 1
553+
554+
[file foo/__init__.py]
555+
[file foo/empty.py]
556+
[file bar.py]
557+
from foo.empty import *
558+
a = 1 # type: ignore
559+
560+
[case testUnusedTypeIgnorePreservedAfterChange]
561+
-- Regression test for https://github.com/python/mypy/issues/9655
562+
$ dmypy start -- --warn-unused-ignores --no-error-summary
563+
Daemon started
564+
$ dmypy check -- bar.py
565+
bar.py:2: error: Unused "type: ignore" comment
566+
== Return code: 1
567+
$ {python} -c "print('\n')" >> bar.py
568+
$ dmypy check -- bar.py
569+
bar.py:2: error: Unused "type: ignore" comment
570+
== Return code: 1
571+
572+
[file foo/__init__.py]
573+
[file foo/empty.py]
574+
[file bar.py]
575+
from foo.empty import *
576+
a = 1 # type: ignore
577+
578+
[case testTypeIgnoreWithoutCodePreservedAfterChange]
579+
-- Regression test for https://github.com/python/mypy/issues/9655
580+
$ dmypy start -- --enable-error-code ignore-without-code --no-error-summary
581+
Daemon started
582+
$ dmypy check -- bar.py
583+
bar.py:2: error: "type: ignore" comment without error code [ignore-without-code]
584+
== Return code: 1
585+
$ {python} -c "print('\n')" >> bar.py
586+
$ dmypy check -- bar.py
587+
bar.py:2: error: "type: ignore" comment without error code [ignore-without-code]
588+
== Return code: 1
589+
590+
[file foo/__init__.py]
591+
[file foo/empty.py]
592+
[file bar.py]
593+
from foo.empty import *
594+
a = 1 # type: ignore
595+
596+
[case testPossiblyUndefinedVarsPreservedAfterUpdate]
597+
-- Regression test for https://github.com/python/mypy/issues/9655
598+
$ dmypy start -- --enable-error-code possibly-undefined --no-error-summary
599+
Daemon started
600+
$ dmypy check -- bar.py
601+
bar.py:4: error: Name "a" may be undefined [possibly-undefined]
602+
== Return code: 1
603+
$ dmypy check -- bar.py
604+
bar.py:4: error: Name "a" may be undefined [possibly-undefined]
605+
== Return code: 1
606+
607+
[file foo/__init__.py]
608+
[file foo/empty.py]
609+
[file bar.py]
610+
from foo.empty import *
611+
if False:
612+
a = 1
613+
a

0 commit comments

Comments
 (0)