Repository: python/mypy

Issue:
globl "type: ignore"  ignores too much
Structure:

`sample_proj/__init__.py`:
```python
from sample_proj.commons import some_const
from sample_proj.some_file import SomeClass
```

`sample_proj/comons.py`:
```python
some_const = 'qwe'
```

`sample_proj/some_file.py`:
```python
# type: ignore

from sample_proj.commons import some_const


class SomeClass:
    def fun(self, param=some_const):
        pass
```

```
$ mypy sample_proj
sample_proj/__init__.py:2: error: Module "sample_proj.some_file" has no attribute "SomeClass"
Found 1 error in 1 file (checked 3 source files)
```

 I think it's a bug.

Removing `# type: ignore[union-attr]` helps. I wanted this comment to ignore only this exact error in the whole file.

```
$ mypy --version
mypy 0.942
$ python3 --version
Python 3.10.5

```
documentation for module-level `# type: ignore` is unclear
My expectation of a module-level `# type: ignore` comment is that it will skip *typechecking* of everything in the module; i.e., everything would be given the type `Any`.

The description in the documentation such a comment "has the effect of ignoring the *entire* module.", is, I think, consistent with that impression, since what "ignoring" means earlier in the documentation has been basically skipping typechecking.

What it *actually* does, though, seems to be to cause mypy to quite literally ignore the module: it is just skipped entirely, with the result that you *can't import names defined in that module in another one*:

```
(.venv3) BenW ~ 02:10:35 $ cat foo/a.py
# type: ignore

class A(object):
    pass
cat(.venv3) BenW ~ 02:10:45 $ cat foo/b.py
from foo.a import A

def b(a):
    # type: (A) -> int
    return len(str(type(a)))

print(b(A()))
(.venv3) BenW ~ 02:10:47 $ mypy foo
foo/b.py:1: error: Module 'foo.a' has no attribute 'A'
Found 1 error in 1 file (checked 3 source files)
```

This makes the feature somewhat less useful IMO, but also, I think it could be clearer in the docs that that's what it does.


Discussion:
Duplicate of https://github.com/python/mypy/issues/12076
@hauntsaninja seems it's another bug. It's not about ignoring specific rule. Please reopen
@hauntsaninja I have checked. Yes, just global ignore line still reproduces the bug (and I edited the example). Who to trigger for this issue ?
I think this is just the documented behaviour? https://mypy.readthedocs.io/en/stable/common_issues.html#ignoring-a-whole-file
@hauntsaninja I think no:

![image](https://user-images.githubusercontent.com/1157412/184998461-e171ac38-fdc0-4e97-9596-224cf12c571b.png)


I understand as `has the effect of ignoring [all type errors in] the entire module.`

In my case, something different happens.

Yes, in your case mypy ignores that entire module.

You probably want the ignore_errors configuration: 
https://mypy.readthedocs.io/en/stable/config_file.html#confval-ignore_errors
You can do this inline using:
https://mypy.readthedocs.io/en/stable/inline_config.html

So something like `# mypy: ignore-errors` should do what you want.

I agree that this is confusing, but not sure how to change in a backward compatible manner. (I'm also here for fun and am not personally motivated to fix confusing mypy configuration)
OK I will try. But could you fix the documentation? I mean correcting the ambiguity of the phrase above.
The actual implementation is that mypy marks the entire module as *unreachable*... as if the whole thing were indented inside of an `if False:` block. This is a side-effect of that change that I hadn't considered, though.

Perhaps modules should grow something like an `is_ignored` flag, which is checked when errors are reported, similar to how the module's ignored lines are checked. That could also mean that we report these if `--warn-unused-ignores` is enabled and there are no errors in the file. We can then also handle the various cases arising where there are other ignored lines in the file as well.

If we agree that this is the correct path forward, I can work on this.
Mypy has the `ignore_errors` option. Maybe a top-level `# type: ignore` should turn it on for the module being type checked? This already works and allows names to be imported:

```py
# mypy: ignore-errors
x = 1 + ''  # No error reported
```
Agreed, they're functionally identical. I can take this.
I am also suffering from this bug; a file marked `# type: ignore[no-redef]` is being treated as if nothing is defined in it.

Resolving patch:
diff --git a/mypy/fastparse.py b/mypy/fastparse.py
--- a/mypy/fastparse.py
+++ b/mypy/fastparse.py
@@ -482,6 +482,16 @@ def translate_stmt_list(
             and self.type_ignores
             and min(self.type_ignores) < self.get_lineno(stmts[0])
         ):
+            if self.type_ignores[min(self.type_ignores)]:
+                self.fail(
+                    (
+                        "type ignore with error code is not supported for modules; "
+                        "use `# mypy: disable-error-code=...`"
+                    ),
+                    line=min(self.type_ignores),
+                    column=0,
+                    blocker=False,
+                )
             self.errors.used_ignored_lines[self.errors.file][min(self.type_ignores)].append(
                 codes.FILE.code
             )


Test patch:
diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test
--- a/test-data/unit/check-errorcodes.test
+++ b/test-data/unit/check-errorcodes.test
@@ -916,3 +916,8 @@ def f(d: D, s: str) -> None:
     d[s]  # type: ignore[literal-required]
 [builtins fixtures/dict.pyi]
 [typing fixtures/typing-typeddict.pyi]
+
+
+[case testRecommendErrorCode]
+# type: ignore[whatever]  # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code=...`  [syntax]
+1 + "asdf"