Skip to content

Commit a6bfb2e

Browse files
wyattscarpentersterliakovhauntsaninja
authored
Fix crash when using enable_error_code value of wrong type in pyproject.toml (#19494)
Fixes #19491 If you give a string in toml, you get Invalid error code(s): whatever. However, if you give a value that doesn't mean a string in toml, you get a crash like TypeError: 'int' object is not iterable. I suspect this would also apply to many other pyproject.toml values if you set them wrong, because we pass many of them immediately into try_split, which tries to iterate them. I have added a (fairly minimal) test for this behavior. --------- Co-authored-by: Stanislav Terliakov <[email protected]> Co-authored-by: Shantanu <[email protected]>
1 parent db67fac commit a6bfb2e

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

mypy/config_parser.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717

1818
from collections.abc import Mapping, MutableMapping, Sequence
1919
from typing import Any, Callable, Final, TextIO, Union
20-
from typing_extensions import TypeAlias as _TypeAlias
20+
from typing_extensions import Never, TypeAlias
2121

2222
from mypy import defaults
2323
from mypy.options import PER_MODULE_OPTIONS, Options
2424

25-
_CONFIG_VALUE_TYPES: _TypeAlias = Union[
25+
_CONFIG_VALUE_TYPES: TypeAlias = Union[
2626
str, bool, int, float, dict[str, str], list[str], tuple[int, int]
2727
]
28-
_INI_PARSER_CALLABLE: _TypeAlias = Callable[[Any], _CONFIG_VALUE_TYPES]
28+
_INI_PARSER_CALLABLE: TypeAlias = Callable[[Any], _CONFIG_VALUE_TYPES]
2929

3030

3131
class VersionTypeError(argparse.ArgumentTypeError):
@@ -60,14 +60,31 @@ def parse_version(v: str | float) -> tuple[int, int]:
6060
return major, minor
6161

6262

63-
def try_split(v: str | Sequence[str], split_regex: str = "[,]") -> list[str]:
64-
"""Split and trim a str or list of str into a list of str"""
63+
def try_split(v: str | Sequence[str] | object, split_regex: str = ",") -> list[str]:
64+
"""Split and trim a str or sequence (eg: list) of str into a list of str.
65+
If an element of the input is not str, a type error will be raised."""
66+
67+
def complain(x: object, additional_info: str = "") -> Never:
68+
raise argparse.ArgumentTypeError(
69+
f"Expected a list or a stringified version thereof, but got: '{x}', of type {type(x).__name__}.{additional_info}"
70+
)
71+
6572
if isinstance(v, str):
6673
items = [p.strip() for p in re.split(split_regex, v)]
6774
if items and items[-1] == "":
6875
items.pop(-1)
6976
return items
70-
return [p.strip() for p in v]
77+
elif isinstance(v, Sequence):
78+
return [
79+
(
80+
p.strip()
81+
if isinstance(p, str)
82+
else complain(p, additional_info=" (As an element of the list.)")
83+
)
84+
for p in v
85+
]
86+
else:
87+
complain(v)
7188

7289

7390
def validate_codes(codes: list[str]) -> list[str]:

test-data/unit/cmdline.pyproject.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,14 @@ y: int = 'y' # E: Incompatible types in assignment (expression has type "str",
226226
# This should not trigger any errors, because it is not included:
227227
z: int = 'z'
228228
[out]
229+
230+
[case testPyprojectTOMLSettingOfWrongType]
231+
# cmd: mypy a.py
232+
[file pyproject.toml]
233+
\[tool.mypy]
234+
enable_error_code = true
235+
[file a.py]
236+
x: int = 1
237+
[out]
238+
pyproject.toml: [mypy]: enable_error_code: Expected a list or a stringified version thereof, but got: 'True', of type bool.
239+
== Return code: 0

0 commit comments

Comments
 (0)