From 5ad39cd3b29a0a907617d8c159482ba121bb96ce Mon Sep 17 00:00:00 2001 From: chiri Date: Sat, 14 Mar 2026 23:12:54 +0300 Subject: [PATCH 1/4] add support for `mypy.toml` and `.mypy.toml` configuration files --- docs/source/command_line.rst | 7 +-- docs/source/config_file.rst | 56 +++++++++++++++++++++-- mypy/config_parser.py | 79 ++++++++++++++++++++++++--------- mypy/defaults.py | 2 +- mypy/test/test_config_parser.py | 19 +++++++- mypy/test/testcmdline.py | 8 +++- 6 files changed, 140 insertions(+), 31 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index b1505d7d96687..6312e3fe675f1 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -114,9 +114,10 @@ Config file This flag makes mypy read configuration settings from the given file. - By default settings are read from ``mypy.ini``, ``.mypy.ini``, ``pyproject.toml``, or ``setup.cfg`` - in the current directory. Settings override mypy's built-in defaults and - command line flags can override settings. + By default settings are read from ``mypy.ini``, ``.mypy.ini``, ``mypy.toml``, + ``.mypy.toml``, ``pyproject.toml``, or ``setup.cfg`` in the current + directory. Settings override mypy's built-in defaults and command line + flags can override settings. Specifying :option:`--config-file= <--config-file>` (with no filename) will ignore *all* config files. diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 50f0da62de986..9cfb2a55f4804 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -14,8 +14,10 @@ the following configuration files (in this order): 1. ``mypy.ini`` 2. ``.mypy.ini`` - 3. ``pyproject.toml`` (containing a ``[tool.mypy]`` section) - 4. ``setup.cfg`` (containing a ``[mypy]`` section) + 3. ``mypy.toml`` + 4. ``.mypy.toml`` + 5. ``pyproject.toml`` (containing a ``[tool.mypy]`` section) + 6. ``setup.cfg`` (containing a ``[mypy]`` section) If no configuration file is found by this method, mypy will then look for configuration files in the following locations (in this order): @@ -49,8 +51,15 @@ The configuration file format is the usual section names in square brackets and flag settings of the form `NAME = VALUE`. Comments start with ``#`` characters. -- A section named ``[mypy]`` must be present. This specifies - the global flags. +Mypy also supports TOML configuration in two forms: + +* ``pyproject.toml`` with options under ``[tool.mypy]`` and per-module + overrides under ``[[tool.mypy.overrides]]`` +* ``mypy.toml`` or ``.mypy.toml`` with options at the top level and + per-module overrides under ``[[mypy.overrides]]`` + +- In INI-based config files, a section named ``[mypy]`` must be present. + This specifies the global flags. - Additional sections named ``[mypy-PATTERN1,PATTERN2,...]`` may be present, where ``PATTERN1``, ``PATTERN2``, etc., are comma-separated @@ -1280,6 +1289,45 @@ of your repo (or append it to the end of an existing ``pyproject.toml`` file) an ] ignore_missing_imports = true +Using a mypy.toml file +********************** + +``mypy.toml`` and ``.mypy.toml`` are also supported. They use the same +TOML value rules as ``pyproject.toml``, but the mypy options live at the +top level instead of under ``[tool.mypy]``. + +Example ``mypy.toml`` +********************* + +.. code-block:: toml + + # mypy global options: + + python_version = "3.9" + warn_return_any = true + warn_unused_configs = true + exclude = [ + '^file1\.py$', # TOML literal string (single-quotes, no escaping necessary) + "^file2\\.py$", # TOML basic string (double-quotes, backslash and other characters need escaping) + ] + + # mypy per-module options: + + [[mypy.overrides]] + module = "mycode.foo.*" + disallow_untyped_defs = true + + [[mypy.overrides]] + module = "mycode.bar" + warn_return_any = false + + [[mypy.overrides]] + module = [ + "somelibrary", + "some_other_library" + ] + ignore_missing_imports = true + .. _lxml: https://pypi.org/project/lxml/ .. _SQLite: https://www.sqlite.org/ .. _PEP 518: https://www.python.org/dev/peps/pep-0518/ diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 747981916960d..ba8927142aaff 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -245,12 +245,10 @@ def _parse_individual_file( if is_toml(config_file): with open(config_file, "rb") as f: toml_data = tomllib.load(f) - # Filter down to just mypy relevant toml keys - toml_data = toml_data.get("tool", {}) - if "mypy" not in toml_data: + toml_data = get_mypy_toml_data(config_file, toml_data) + if toml_data is None: return None - toml_data = {"mypy": toml_data["mypy"]} - parser = destructure_overrides(toml_data) + parser = destructure_overrides(toml_data, config_file) config_types = toml_config_types else: parser = configparser.RawConfigParser() @@ -397,20 +395,48 @@ def is_toml(filename: str) -> bool: return filename.lower().endswith(".toml") -def destructure_overrides(toml_data: dict[str, Any]) -> dict[str, Any]: - """Take the new [[tool.mypy.overrides]] section array in the pyproject.toml file, - and convert it back to a flatter structure that the existing config_parser can handle. +def is_pyproject(filename: str) -> bool: + return os.path.basename(filename) == "pyproject.toml" - E.g. the following pyproject.toml file: - [[tool.mypy.overrides]] +def get_mypy_toml_data( + config_file: str, + toml_data: dict[str, Any], +) -> dict[str, Any] | None: + if is_pyproject(config_file): + toml_data = toml_data.get("tool", {}) + if "mypy" not in toml_data: + return None + return {"mypy": toml_data["mypy"]} + + if "mypy" in toml_data: + return toml_data + + return {"mypy": toml_data} + + +def _toml_module_error(config_file: str, message: str) -> str: + if is_pyproject(config_file): + return message.format(prefix="tool.mypy", override="[[tool.mypy.overrides]]") + return message.format(prefix="mypy", override="[[mypy.overrides]]") + + +def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[str, Any]: + """Convert TOML overrides sections into the flatter ini-style structure. + + ``pyproject.toml`` uses ``[[tool.mypy.overrides]]``. + ``mypy.toml`` and ``.mypy.toml`` use ``[[mypy.overrides]]``. + + E.g. the following TOML file: + + [[mypy.overrides]] module = [ "a.b", "b.*" ] disallow_untyped_defs = true - [[tool.mypy.overrides]] + [[mypy.overrides]] module = 'c' disallow_untyped_defs = false @@ -434,16 +460,22 @@ def destructure_overrides(toml_data: dict[str, Any]) -> dict[str, Any]: if not isinstance(toml_data["mypy"]["overrides"], list): raise ConfigTOMLValueError( - "tool.mypy.overrides sections must be an array. Please make " - "sure you are using double brackets like so: [[tool.mypy.overrides]]" + _toml_module_error( + config_file, + "{prefix}.overrides sections must be an array. Please make " + "sure you are using double brackets like so: {override}", + ), ) result = toml_data.copy() for override in result["mypy"]["overrides"]: if "module" not in override: raise ConfigTOMLValueError( - "toml config file contains a [[tool.mypy.overrides]] " - "section, but no module to override was specified." + _toml_module_error( + config_file, + "toml config file contains a {override} section, but no module to " + "override was specified.", + ), ) if isinstance(override["module"], str): @@ -452,9 +484,11 @@ def destructure_overrides(toml_data: dict[str, Any]) -> dict[str, Any]: modules = override["module"] else: raise ConfigTOMLValueError( - "toml config file contains a [[tool.mypy.overrides]] " - "section with a module value that is not a string or a list of " - "strings" + _toml_module_error( + config_file, + "toml config file contains a {override} section with a module value " + "that is not a string or a list of strings", + ), ) for module in modules: @@ -470,9 +504,12 @@ def destructure_overrides(toml_data: dict[str, Any]) -> dict[str, Any]: and result[old_config_name][new_key] != new_value ): raise ConfigTOMLValueError( - "toml config file contains " - "[[tool.mypy.overrides]] sections with conflicting " - f"values. Module '{module}' has two different values for '{new_key}'" + _toml_module_error( + config_file, + "toml config file contains {override} sections with " + f"conflicting values. Module '{module}' has " + f"two different values for '{new_key}'", + ), ) result[old_config_name][new_key] = new_value diff --git a/mypy/defaults.py b/mypy/defaults.py index a39a577d03ac6..35ef2c9b442e6 100644 --- a/mypy/defaults.py +++ b/mypy/defaults.py @@ -14,7 +14,7 @@ CACHE_DIR: Final = ".mypy_cache" -CONFIG_NAMES: Final = ["mypy.ini", ".mypy.ini"] +CONFIG_NAMES: Final = ["mypy.ini", ".mypy.ini", "mypy.toml", ".mypy.toml"] SHARED_CONFIG_NAMES: Final = ["pyproject.toml", "setup.cfg"] USER_CONFIG_FILES: list[str] = ["~/.config/mypy/config", "~/.mypy.ini"] diff --git a/mypy/test/test_config_parser.py b/mypy/test/test_config_parser.py index 597143738f23c..7f934f65dc474 100644 --- a/mypy/test/test_config_parser.py +++ b/mypy/test/test_config_parser.py @@ -25,7 +25,10 @@ def chdir(target: Path) -> Iterator[None]: def write_config(path: Path, content: str | None = None) -> None: if path.suffix == ".toml": if content is None: - content = "[tool.mypy]\nstrict = true" + if path.name == "pyproject.toml": + content = "[tool.mypy]\nstrict = true" + else: + content = "strict = true" path.write_text(content) else: if content is None: @@ -82,6 +85,8 @@ def test_precedence(self) -> None: setup_cfg = tmpdir / "setup.cfg" mypy_ini = tmpdir / "mypy.ini" dot_mypy = tmpdir / ".mypy.ini" + mypy_toml = tmpdir / "mypy.toml" + dot_mypy_toml = tmpdir / ".mypy.toml" child = tmpdir / "child" child.mkdir() @@ -91,6 +96,8 @@ def test_precedence(self) -> None: write_config(setup_cfg) write_config(mypy_ini) write_config(dot_mypy) + write_config(mypy_toml) + write_config(dot_mypy_toml) with chdir(cwd): result = _find_config_file() @@ -105,6 +112,16 @@ def test_precedence(self) -> None: dot_mypy.unlink() result = _find_config_file() assert result is not None + assert os.path.basename(result[2]) == "mypy.toml" + + mypy_toml.unlink() + result = _find_config_file() + assert result is not None + assert os.path.basename(result[2]) == ".mypy.toml" + + dot_mypy_toml.unlink() + result = _find_config_file() + assert result is not None assert os.path.basename(result[2]) == "pyproject.toml" pyproject.unlink() diff --git a/mypy/test/testcmdline.py b/mypy/test/testcmdline.py index 450f5abc14c34..5f5dadf58b87c 100644 --- a/mypy/test/testcmdline.py +++ b/mypy/test/testcmdline.py @@ -35,7 +35,13 @@ python3_path = sys.executable # Files containing test case descriptions. -cmdline_files = ["cmdline.test", "cmdline.pyproject.test", "reports.test", "envvars.test"] +cmdline_files = [ + "cmdline.test", + "cmdline.pyproject.test", + "cmdline.mypy_toml.test", + "reports.test", + "envvars.test", +] class PythonCmdlineSuite(DataSuite): From 2b2ffabfa4e8fe7b051c1792e6697b58ab6e63ba Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:15:21 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/config_parser.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/mypy/config_parser.py b/mypy/config_parser.py index ba8927142aaff..41b988ea93078 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -399,10 +399,7 @@ def is_pyproject(filename: str) -> bool: return os.path.basename(filename) == "pyproject.toml" -def get_mypy_toml_data( - config_file: str, - toml_data: dict[str, Any], -) -> dict[str, Any] | None: +def get_mypy_toml_data(config_file: str, toml_data: dict[str, Any]) -> dict[str, Any] | None: if is_pyproject(config_file): toml_data = toml_data.get("tool", {}) if "mypy" not in toml_data: @@ -464,7 +461,7 @@ def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[s config_file, "{prefix}.overrides sections must be an array. Please make " "sure you are using double brackets like so: {override}", - ), + ) ) result = toml_data.copy() @@ -475,7 +472,7 @@ def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[s config_file, "toml config file contains a {override} section, but no module to " "override was specified.", - ), + ) ) if isinstance(override["module"], str): @@ -488,7 +485,7 @@ def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[s config_file, "toml config file contains a {override} section with a module value " "that is not a string or a list of strings", - ), + ) ) for module in modules: @@ -509,7 +506,7 @@ def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[s "toml config file contains {override} sections with " f"conflicting values. Module '{module}' has " f"two different values for '{new_key}'", - ), + ) ) result[old_config_name][new_key] = new_value From fb20096d4e61f8b3031cbb80257f1f40ea83446f Mon Sep 17 00:00:00 2001 From: chiri Date: Sat, 14 Mar 2026 23:28:03 +0300 Subject: [PATCH 3/4] add test cases for `mypy.toml` and `.mypy.toml` parsing --- test-data/unit/cmdline.mypy_toml.test | 198 ++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 test-data/unit/cmdline.mypy_toml.test diff --git a/test-data/unit/cmdline.mypy_toml.test b/test-data/unit/cmdline.mypy_toml.test new file mode 100644 index 0000000000000..0a47d6a40dcd2 --- /dev/null +++ b/test-data/unit/cmdline.mypy_toml.test @@ -0,0 +1,198 @@ +-- Tests for mypy.toml / .mypy.toml parsing +-- ---------------------------------------- + +[case testNonArrayOverridesMypyTOML] +# cmd: mypy x.py +[file mypy.toml] +\[mypy.overrides] +module = "x" +disallow_untyped_defs = false +[file x.py] +def f(a): + pass +def g(a: int) -> int: + return f(a) +[out] +mypy.toml: mypy.overrides sections must be an array. Please make sure you are using double brackets like so: [[mypy.overrides]] +== Return code: 0 + +[case testNoModuleInOverrideMypyTOML] +# cmd: mypy x.py +[file mypy.toml] +\[[mypy.overrides]] +disallow_untyped_defs = false +[file x.py] +def f(a): + pass +def g(a: int) -> int: + return f(a) +[out] +mypy.toml: toml config file contains a [[mypy.overrides]] section, but no module to override was specified. +== Return code: 0 + +[case testInvalidModuleInOverrideMypyTOML] +# cmd: mypy x.py +[file mypy.toml] +\[[mypy.overrides]] +module = 0 +disallow_untyped_defs = false +[file x.py] +def f(a): + pass +def g(a: int) -> int: + return f(a) +[out] +mypy.toml: toml config file contains a [[mypy.overrides]] section with a module value that is not a string or a list of strings +== Return code: 0 + +[case testConflictingModuleInOverridesMypyTOML] +# cmd: mypy x.py +[file mypy.toml] +\[[mypy.overrides]] +module = 'x' +disallow_untyped_defs = false +\[[mypy.overrides]] +module = ['x'] +disallow_untyped_defs = true +[file x.py] +def f(a): + pass +def g(a: int) -> int: + return f(a) +[out] +mypy.toml: toml config file contains [[mypy.overrides]] sections with conflicting values. Module 'x' has two different values for 'disallow_untyped_defs' +== Return code: 0 + +[case testMultilineLiteralExcludeMypyTOML] +# cmd: mypy x +[file mypy.toml] +exclude = '''(?x)( + (^|/)[^/]*skipme_\.py$ + |(^|/)_skipme[^/]*\.py$ +)''' +[file x/__init__.py] +i: int = 0 +[file x/_skipme_please.py] +This isn't even syntactically valid! +[file x/please_skipme_.py] +Neither is this! + +[case testMultilineBasicExcludeMypyTOML] +# cmd: mypy x +[file mypy.toml] +exclude = """(?x)( + (^|/)[^/]*skipme_\\.py$ + |(^|/)_skipme[^/]*\\.py$ +)""" +[file x/__init__.py] +i: int = 0 +[file x/_skipme_please.py] +This isn't even syntactically valid! +[file x/please_skipme_.py] +Neither is this! + +[case testSequenceExcludeMypyTOML] +# cmd: mypy x +[file mypy.toml] +exclude = [ + '(^|/)[^/]*skipme_\.py$', # literal (no escaping) + "(^|/)_skipme[^/]*\\.py$", # basic (backslash needs escaping) +] +[file x/__init__.py] +i: int = 0 +[file x/_skipme_please.py] +This isn't even syntactically valid! +[file x/please_skipme_.py] +Neither is this! + +[case testMypyTOMLFilesTrailingComma] +# cmd: mypy +[file mypy.toml] +# We combine multiple tests in a single one here, because these tests are slow. +files = """ + a.py, + b.py, +""" +always_true = """ + FLAG_A1, + FLAG_B1, +""" +always_false = """ + FLAG_A2, + FLAG_B2, +""" +[file a.py] +x: str = 'x' # ok' + +# --always-true +FLAG_A1 = False +FLAG_B1 = False +if not FLAG_A1: # unreachable + x: int = 'x' +if not FLAG_B1: # unreachable + y: int = 'y' +[file b.py] +y: int = 'y' # E: Incompatible types in assignment (expression has type "str", variable has type "int") +[file c.py] +# This should not trigger any errors, because it is not included: +z: int = 'z' +[out] + +[case testMypyTOMLModulesTrailingComma] +# cmd: mypy +[file mypy.toml] +# We combine multiple tests in a single one here, because these tests are slow. +modules = """ + a, + b, +""" +disable_error_code = """ + operator, + import, +""" +enable_error_code = """ + redundant-expr, + ignore-without-code, +""" +[file a.py] +x: str = 'x' # ok + +# --enable-error-code +a: int = 'a' # type: ignore + +# --disable-error-code +'a' + 1 +[file b.py] +y: int = 'y' +[file c.py] +# This should not trigger any errors, because it is not included: +z: int = 'z' +[out] +b.py:1: error: Incompatible types in assignment (expression has type "str", variable has type "int") +a.py:4: error: "type: ignore" comment without error code (consider "type: ignore[assignment]" instead) + +[case testMypyTOMLPackagesTrailingComma] +# cmd: mypy +[file mypy.toml] +packages = """ + a, + b, +""" +[file a/__init__.py] +x: str = 'x' # ok +[file b/__init__.py] +y: int = 'y' # E: Incompatible types in assignment (expression has type "str", variable has type "int") +[file c/__init__.py] +# This should not trigger any errors, because it is not included: +z: int = 'z' +[out] + +[case testMypyTOMLSettingOfWrongType] +# cmd: mypy a.py +[file mypy.toml] +enable_error_code = true +[file a.py] +x: int = 1 +[out] +mypy.toml: [mypy]: enable_error_code: Expected a list or a stringified version thereof, but got: 'True', of type bool. +== Return code: 0 From 6f4977eb4f88965e81cef5172d18117e8633351c Mon Sep 17 00:00:00 2001 From: chiri Date: Sat, 14 Mar 2026 23:57:17 +0300 Subject: [PATCH 4/4] update `mypy.toml` parsing to use `[[overrides]]` instead of `[[mypy.overrides]]` --- docs/source/config_file.rst | 8 ++++---- mypy/config_parser.py | 14 +++++++------- test-data/unit/cmdline.mypy_toml.test | 18 +++++++++--------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 9cfb2a55f4804..550bccf607654 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -56,7 +56,7 @@ Mypy also supports TOML configuration in two forms: * ``pyproject.toml`` with options under ``[tool.mypy]`` and per-module overrides under ``[[tool.mypy.overrides]]`` * ``mypy.toml`` or ``.mypy.toml`` with options at the top level and - per-module overrides under ``[[mypy.overrides]]`` + per-module overrides under ``[[overrides]]`` - In INI-based config files, a section named ``[mypy]`` must be present. This specifies the global flags. @@ -1313,15 +1313,15 @@ Example ``mypy.toml`` # mypy per-module options: - [[mypy.overrides]] + [[overrides]] module = "mycode.foo.*" disallow_untyped_defs = true - [[mypy.overrides]] + [[overrides]] module = "mycode.bar" warn_return_any = false - [[mypy.overrides]] + [[overrides]] module = [ "somelibrary", "some_other_library" diff --git a/mypy/config_parser.py b/mypy/config_parser.py index 41b988ea93078..9457df3565938 100644 --- a/mypy/config_parser.py +++ b/mypy/config_parser.py @@ -414,26 +414,26 @@ def get_mypy_toml_data(config_file: str, toml_data: dict[str, Any]) -> dict[str, def _toml_module_error(config_file: str, message: str) -> str: if is_pyproject(config_file): - return message.format(prefix="tool.mypy", override="[[tool.mypy.overrides]]") - return message.format(prefix="mypy", override="[[mypy.overrides]]") + return message.format(overrides="tool.mypy.overrides", override="[[tool.mypy.overrides]]") + return message.format(overrides="overrides", override="[[overrides]]") def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[str, Any]: """Convert TOML overrides sections into the flatter ini-style structure. ``pyproject.toml`` uses ``[[tool.mypy.overrides]]``. - ``mypy.toml`` and ``.mypy.toml`` use ``[[mypy.overrides]]``. + ``mypy.toml`` and ``.mypy.toml`` use ``[[overrides]]``. E.g. the following TOML file: - [[mypy.overrides]] + [[overrides]] module = [ "a.b", "b.*" ] disallow_untyped_defs = true - [[mypy.overrides]] + [[overrides]] module = 'c' disallow_untyped_defs = false @@ -459,8 +459,8 @@ def destructure_overrides(toml_data: dict[str, Any], config_file: str) -> dict[s raise ConfigTOMLValueError( _toml_module_error( config_file, - "{prefix}.overrides sections must be an array. Please make " - "sure you are using double brackets like so: {override}", + "{overrides} sections must be an array. Please make sure you are " + "using double brackets like so: {override}", ) ) diff --git a/test-data/unit/cmdline.mypy_toml.test b/test-data/unit/cmdline.mypy_toml.test index 0a47d6a40dcd2..ce1e6fa773ad6 100644 --- a/test-data/unit/cmdline.mypy_toml.test +++ b/test-data/unit/cmdline.mypy_toml.test @@ -4,7 +4,7 @@ [case testNonArrayOverridesMypyTOML] # cmd: mypy x.py [file mypy.toml] -\[mypy.overrides] +\[overrides] module = "x" disallow_untyped_defs = false [file x.py] @@ -13,13 +13,13 @@ def f(a): def g(a: int) -> int: return f(a) [out] -mypy.toml: mypy.overrides sections must be an array. Please make sure you are using double brackets like so: [[mypy.overrides]] +mypy.toml: overrides sections must be an array. Please make sure you are using double brackets like so: [[overrides]] == Return code: 0 [case testNoModuleInOverrideMypyTOML] # cmd: mypy x.py [file mypy.toml] -\[[mypy.overrides]] +\[[overrides]] disallow_untyped_defs = false [file x.py] def f(a): @@ -27,13 +27,13 @@ def f(a): def g(a: int) -> int: return f(a) [out] -mypy.toml: toml config file contains a [[mypy.overrides]] section, but no module to override was specified. +mypy.toml: toml config file contains a [[overrides]] section, but no module to override was specified. == Return code: 0 [case testInvalidModuleInOverrideMypyTOML] # cmd: mypy x.py [file mypy.toml] -\[[mypy.overrides]] +\[[overrides]] module = 0 disallow_untyped_defs = false [file x.py] @@ -42,16 +42,16 @@ def f(a): def g(a: int) -> int: return f(a) [out] -mypy.toml: toml config file contains a [[mypy.overrides]] section with a module value that is not a string or a list of strings +mypy.toml: toml config file contains a [[overrides]] section with a module value that is not a string or a list of strings == Return code: 0 [case testConflictingModuleInOverridesMypyTOML] # cmd: mypy x.py [file mypy.toml] -\[[mypy.overrides]] +\[[overrides]] module = 'x' disallow_untyped_defs = false -\[[mypy.overrides]] +\[[overrides]] module = ['x'] disallow_untyped_defs = true [file x.py] @@ -60,7 +60,7 @@ def f(a): def g(a: int) -> int: return f(a) [out] -mypy.toml: toml config file contains [[mypy.overrides]] sections with conflicting values. Module 'x' has two different values for 'disallow_untyped_defs' +mypy.toml: toml config file contains [[overrides]] sections with conflicting values. Module 'x' has two different values for 'disallow_untyped_defs' == Return code: 0 [case testMultilineLiteralExcludeMypyTOML]