Skip to content

Commit cb0ceb0

Browse files
authored
Allow strict in config, explicitly disallow inline (python#8192)
1 parent 310f9e3 commit cb0ceb0

File tree

5 files changed

+52
-13
lines changed

5 files changed

+52
-13
lines changed

mypy/config_parser.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import re
77
import sys
88

9-
from typing import Any, Dict, List, Mapping, Optional, Tuple, TextIO
9+
from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple, TextIO
1010
from typing_extensions import Final
1111

1212
from mypy import defaults
@@ -88,7 +88,8 @@ def split_and_match_files(paths: str) -> List[str]:
8888
} # type: Final
8989

9090

91-
def parse_config_file(options: Options, filename: Optional[str],
91+
def parse_config_file(options: Options, set_strict_flags: Callable[[], None],
92+
filename: Optional[str],
9293
stdout: Optional[TextIO] = None,
9394
stderr: Optional[TextIO] = None) -> None:
9495
"""Parse a config file into an Options object.
@@ -127,15 +128,16 @@ def parse_config_file(options: Options, filename: Optional[str],
127128
else:
128129
section = parser['mypy']
129130
prefix = '%s: [%s]: ' % (file_read, 'mypy')
130-
updates, report_dirs = parse_section(prefix, options, section, stderr)
131+
updates, report_dirs = parse_section(prefix, options, set_strict_flags, section, stderr)
131132
for k, v in updates.items():
132133
setattr(options, k, v)
133134
options.report_dirs.update(report_dirs)
134135

135136
for name, section in parser.items():
136137
if name.startswith('mypy-'):
137138
prefix = '%s: [%s]: ' % (file_read, name)
138-
updates, report_dirs = parse_section(prefix, options, section, stderr)
139+
updates, report_dirs = parse_section(
140+
prefix, options, set_strict_flags, section, stderr)
139141
if report_dirs:
140142
print("%sPer-module sections should not specify reports (%s)" %
141143
(prefix, ', '.join(s + '_report' for s in sorted(report_dirs))),
@@ -163,6 +165,7 @@ def parse_config_file(options: Options, filename: Optional[str],
163165

164166

165167
def parse_section(prefix: str, template: Options,
168+
set_strict_flags: Callable[[], None],
166169
section: Mapping[str, str],
167170
stderr: TextIO = sys.stderr
168171
) -> Tuple[Dict[str, object], Dict[str, str]]:
@@ -205,9 +208,7 @@ def parse_section(prefix: str, template: Options,
205208
options_key = key[3:]
206209
invert = True
207210
elif key == 'strict':
208-
print("%sStrict mode is not supported in configuration files: specify "
209-
"individual flags instead (see 'mypy -h' for the list of flags enabled "
210-
"in strict mode)" % prefix, file=stderr)
211+
set_strict_flags()
211212
else:
212213
print("%sUnrecognized option: %s = %s" % (prefix, key, section[key]),
213214
file=stderr)
@@ -330,10 +331,23 @@ def parse_mypy_comments(
330331
errors.extend((lineno, x) for x in parse_errors)
331332

332333
stderr = StringIO()
333-
new_sections, reports = parse_section('', template, parser['dummy'], stderr=stderr)
334+
strict_found = False
335+
336+
def set_strict_flags() -> None:
337+
nonlocal strict_found
338+
strict_found = True
339+
340+
new_sections, reports = parse_section(
341+
'', template, set_strict_flags, parser['dummy'], stderr=stderr)
334342
errors.extend((lineno, x) for x in stderr.getvalue().strip().split('\n') if x)
335343
if reports:
336344
errors.append((lineno, "Reports not supported in inline configuration"))
345+
if strict_found:
346+
errors.append((lineno,
347+
"Setting 'strict' not supported in inline configuration: specify it in "
348+
"a configuration file instead, or set individual inline flags "
349+
"(see 'mypy -h' for the list of flags enabled in strict mode)"))
350+
337351
sections.update(new_sections)
338352

339353
return sections, errors

mypy/main.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -806,15 +806,19 @@ def add_invertible_flag(flag: str,
806806
if config_file and not os.path.exists(config_file):
807807
parser.error("Cannot find config file '%s'" % config_file)
808808

809-
# Parse config file first, so command line can override.
810809
options = Options()
811-
parse_config_file(options, config_file, stdout, stderr)
810+
811+
def set_strict_flags() -> None:
812+
for dest, value in strict_flag_assignments:
813+
setattr(options, dest, value)
814+
815+
# Parse config file first, so command line can override.
816+
parse_config_file(options, set_strict_flags, config_file, stdout, stderr)
812817

813818
# Set strict flags before parsing (if strict mode enabled), so other command
814819
# line options can override.
815820
if getattr(dummy, 'special-opts:strict'): # noqa
816-
for dest, value in strict_flag_assignments:
817-
setattr(options, dest, value)
821+
set_strict_flags()
818822

819823
# Override cache_dir if provided in the environment
820824
environ_cache_dir = os.getenv('MYPY_CACHE_DIR', '')

mypy/test/testfinegrained.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def get_options(self,
193193

194194
for name, _ in testcase.files:
195195
if 'mypy.ini' in name:
196-
parse_config_file(options, name)
196+
parse_config_file(options, lambda: None, name)
197197
break
198198

199199
return options

test-data/unit/check-flags.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,22 @@ def f(c: A) -> None: # E: Missing type parameters for generic type "A"
11491149
pass
11501150
[out]
11511151

1152+
[case testStrictInConfigAnyGeneric]
1153+
# flags: --config-file tmp/mypy.ini
1154+
from typing import TypeVar, Generic
1155+
1156+
T = TypeVar('T')
1157+
1158+
class A(Generic[T]):
1159+
pass
1160+
1161+
def f(c: A) -> None: # E: Missing type parameters for generic type "A"
1162+
pass
1163+
[file mypy.ini]
1164+
\[mypy]
1165+
strict = True
1166+
[out]
1167+
11521168
[case testStrictAndStrictEquality]
11531169
# flags: --strict
11541170
x = 0

test-data/unit/check-inline-config.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,8 @@ main:4: error: Unterminated quote in configuration comment
157157
# mypy: skip-file
158158
[out]
159159
main:1: error: Unrecognized option: skip_file = True
160+
161+
[case testInlineStrict]
162+
# mypy: strict
163+
[out]
164+
main:1: error: Setting 'strict' not supported in inline configuration: specify it in a configuration file instead, or set individual inline flags (see 'mypy -h' for the list of flags enabled in strict mode)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy