Respect file config comments for stale modules (#21444)

In mypy 1.19, re-running `mypy` with a saved cache and a file containing
an inline configuration comment (e.g. `# mypy:
disable-error-code="import-not-found"`) acted 'correctly', i.e. the same
behaviour on the first run vs subsequent runs.

In mypy 1.20 and newer, this is no longer the case. Running `mypy` with
a pre-existing cache fails to respect inline configuration comments for
stale modules, leading to confusing false-positive errors that can be
hard to debug.

This PR introduces a failing test as at current master, and then a fix
for the issue. I believe this is the right fix, though happy to change
as suggested by the maintainers, I'm not nearly as familiar with mypy
internals.

Notably also from L2376-80, it's by design that file-level comments
aren't cached:

```python
    # Note that the options we store in the cache are the options as
    # specified by the command line/config file and *don't* reflect
    # updates made by inline config directives in the file. This is
    # important, or otherwise the options would never match when
    # verifying the cache.
```

I believe that this regression was introduced in #20773

A

Co-authored-by: Adam Turner <turner@hudson-trading.com>
diff --git a/mypy/build.py b/mypy/build.py
index 21a5559..8d5db0b 100644
--- a/mypy/build.py
+++ b/mypy/build.py
@@ -4769,13 +4769,13 @@
 
     t2 = time.time()
     stale = scc
+    # Parse before verify_dependencies so that inline config comments
+    # (e.g. "# mypy: disable-error-code") are applied to options.
+    manager.parse_all([graph[id] for id in stale], post_parse=False)
     for id in stale:
         # Re-generate import errors in case this module was loaded from the cache.
         if graph[id].meta:
             graph[id].verify_dependencies(suppressed_only=True)
-    # We may already have parsed the modules, or not.
-    # If the former, parse_file() is a no-op.
-    manager.parse_all([graph[id] for id in stale], post_parse=False)
     if "typing" in scc:
         # For historical reasons we need to manually add typing aliases
         # for built-in generic collections, see docstring of
diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test
index 6911a35..db15b73 100644
--- a/test-data/unit/check-incremental.test
+++ b/test-data/unit/check-incremental.test
@@ -7995,3 +7995,19 @@
 [out2]
 main:2: error: Cannot find implementation or library stub for module named "mod"
 main:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
+
+[case testIncrementalFileConfigCommentsStale]
+-- When a dependency changes, the importing module becomes stale and is
+-- reprocessed via process_stale_scc. As inline config comments are not cached
+-- (by design), moving the order of processing the stale SCC can accidentally
+-- break file config comments on subsequent runs.
+# mypy: disable-error-code="import-not-found"
+import nonexistent
+import b
+[file b.py]
+x = 1
+[file b.py.2]
+x = "hello"
+[builtins fixtures/module.pyi]
+[stale b]
+[rechecked b]