Repository: python/mypy

Issue:
Support package and module in config files
**Feature**

Allow listing modules/packages to check, within the MyPy config files.

**Pitch**

Today, it is possible to use the `files` config item (in mypy.ini, pyproject.toml, etc.) to tell MyPy what files to check.  You can also do this on the command-line, by simply listing the files.

If you want MyPy to check an entire module or package, you can do so on the command line (with `-m` or `-p`), but there is no way to do this in a config file.  Since it is possible to set `files` in config files, I think it should also be possible to set `module` and `package`.  (I am suggesting not-plural names "module" and "package" to match the command-line arguments).

One question you might ask is "Why don't you just list the directory containing your modules/packages?"  In my case, doing so gives me an error like this:

```
src/namespace1/namespace2/package1/file.py: error: Source file found twice under different module names: `package2` and `namespace1.namespace2.package2`
```

… or an error like this:

```
src/namespace1/namespace2/package1/__init.py__:NN: error: Skipping analyzing "namespace1": found module but no type hints of library stubs
```

All of my code is in the `src` directory.  In my `pyproject.toml`, I have `namespace_packages = true` and `mypy_path = ["src"]`.  The above error only happens if I try to specify a file or directory to check.  If instead I use `-p namespace1` (or `-p namespace1.namespace2`), everything is located, loaded, and typechecked successfully.


Discussion:
Reasonable feature request.
(Note for namespace package file listing, I think using `--explicit-package-bases` can solve that issue, see https://mypy.readthedocs.io/en/latest/running_mypy.html#mapping-file-paths-to-modules)

Resolving patch:
diff --git a/mypy/config_parser.py b/mypy/config_parser.py
--- a/mypy/config_parser.py
+++ b/mypy/config_parser.py
@@ -161,6 +161,8 @@ def check_follow_imports(choice: str) -> str:
     "python_executable": expand_path,
     "strict": bool,
     "exclude": lambda s: [s.strip()],
+    "packages": try_split,
+    "modules": try_split,
 }
 
 # Reuse the ini_config_types and overwrite the diff
@@ -178,6 +180,8 @@ def check_follow_imports(choice: str) -> str:
         "enable_error_code": lambda s: validate_codes(try_split(s)),
         "package_root": try_split,
         "exclude": str_or_array_as_list,
+        "packages": try_split,
+        "modules": try_split,
     }
 )
 
diff --git a/mypy/main.py b/mypy/main.py
--- a/mypy/main.py
+++ b/mypy/main.py
@@ -1222,8 +1222,13 @@ def set_strict_flags() -> None:
 
     # Paths listed in the config file will be ignored if any paths, modules or packages
     # are passed on the command line.
-    if options.files and not (special_opts.files or special_opts.packages or special_opts.modules):
-        special_opts.files = options.files
+    if not (special_opts.files or special_opts.packages or special_opts.modules):
+        if options.files:
+            special_opts.files = options.files
+        if options.packages:
+            special_opts.packages = options.packages
+        if options.modules:
+            special_opts.modules = options.modules
 
     # Check for invalid argument combinations.
     if require_targets:
diff --git a/mypy/options.py b/mypy/options.py
--- a/mypy/options.py
+++ b/mypy/options.py
@@ -215,6 +215,12 @@ def __init__(self) -> None:
         # supports globbing
         self.files: list[str] | None = None
 
+        # A list of packages for mypy to type check
+        self.packages: list[str] | None = None
+
+        # A list of modules for mypy to type check
+        self.modules: list[str] | None = None
+
         # Write junit.xml to given file
         self.junit_xml: str | None = None
 


Test patch: