Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/source/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ characters.
separated by commas. These sections specify additional flags that
only apply to *modules* whose name matches at least one of the patterns.

.. note::

The ``warn_unused_configs`` flag may be useful to debug misspelled
section names.

Global flags
************

Expand Down Expand Up @@ -72,6 +77,10 @@ The following global flags may only be set in the global section
- ``warn_unused_ignores`` (Boolean, default False) warns about
unneeded ``# type: ignore`` comments.

- ``warn_unused_configs`` (Boolean, default False) warns about
per-module sections in the config file that didn't match any
files processed in the current run.

- ``strict_optional`` (Boolean, default False) enables experimental
strict Optional checks.

Expand Down
8 changes: 8 additions & 0 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ def main(script_path: Optional[str], args: Optional[List[str]] = None) -> None:
a = e.messages
if not e.use_stdout:
serious = True
if options.warn_unused_configs and options.unused_configs:
print("Warning: unused section(s) in %s: %s" %
(options.config_file,
", ".join("[mypy-%s]" % glob for glob in options.unused_configs.values())),
file=sys.stderr)
if options.junit_xml:
t1 = time.time()
util.write_junit_xml(t1 - t0, serious, a, options.junit_xml)
Expand Down Expand Up @@ -280,6 +285,8 @@ def add_invertible_flag(flag: str,
" from non-Any typed functions")
add_invertible_flag('--warn-unused-ignores', default=False, strict_flag=True,
help="warn about unneeded '# type: ignore' comments")
add_invertible_flag('--warn-unused-configs', default=False, strict_flag=True,
help="warn about unnused '[mypy-<pattern>]' config sections")
add_invertible_flag('--show-error-context', default=False,
dest='show_error_context',
help='Precede errors with "note:" messages explaining context')
Expand Down Expand Up @@ -694,6 +701,7 @@ def parse_config_file(options: Options, filename: Optional[str]) -> None:
glob = glob.replace(os.altsep, '.')
pattern = re.compile(fnmatch.translate(glob))
options.per_module_options[pattern] = updates
options.unused_configs[pattern] = glob


def parse_section(prefix: str, template: Options,
Expand Down
9 changes: 8 additions & 1 deletion mypy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pprint
import sys

from typing import Mapping, MutableMapping, Optional, Tuple, List, Pattern, Dict
from typing import Dict, List, Mapping, MutableMapping, Optional, Pattern, Set, Tuple

from mypy import defaults

Expand Down Expand Up @@ -87,6 +87,9 @@ def __init__(self) -> None:
# Warn about unused '# type: ignore' comments
self.warn_unused_ignores = False

# Warn about unused '[mypy-<pattern>] config sections
self.warn_unused_configs = False

# Files in which to ignore all non-fatal errors
self.ignore_errors = False

Expand Down Expand Up @@ -131,6 +134,8 @@ def __init__(self) -> None:
# Per-module options (raw)
pm_opts = OrderedDict() # type: OrderedDict[Pattern[str], Dict[str, object]]
self.per_module_options = pm_opts
# Map pattern back to glob
self.unused_configs = OrderedDict() # type: OrderedDict[Pattern[str], str]

# -- development options --
self.verbosity = 0 # More verbose messages (for troubleshooting)
Expand Down Expand Up @@ -164,6 +169,8 @@ def clone_for_module(self, module: str) -> 'Options':
updates = {}
for pattern in self.per_module_options:
if self.module_matches_pattern(module, pattern):
if pattern in self.unused_configs:
del self.unused_configs[pattern]
updates.update(self.per_module_options[pattern])
if not updates:
return self
Expand Down