Skip to content

Commit e88f4a4

Browse files
authored
[mypyc] Always emit warnings (#14451)
For example the warning for "treating generator comprehension as list" doesn't get printed unless there were errors too. This was due to the fact mypyc/build.py was only checking errors.num_errors to decide whether to print messages to STDOUT. To be honest, the generate_c() logic was pretty messy, so I broke out the message printing logic into a separate helper function and made liberal use of early exits. Fixes mypyc/mypyc#873 (comment).
1 parent e9f5858 commit e88f4a4

File tree

3 files changed

+35
-27
lines changed

3 files changed

+35
-27
lines changed

mypyc/build.py

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ def fail(message: str) -> NoReturn:
8585
sys.exit(message)
8686

8787

88+
def emit_messages(options: Options, messages: list[str], dt: float, serious: bool = False) -> None:
89+
# ... you know, just in case.
90+
if options.junit_xml:
91+
py_version = f"{options.python_version[0]}_{options.python_version[1]}"
92+
write_junit_xml(dt, serious, messages, options.junit_xml, py_version, options.platform)
93+
if messages:
94+
print("\n".join(messages))
95+
96+
8897
def get_mypy_config(
8998
mypy_options: list[str],
9099
only_compile_paths: Iterable[str] | None,
@@ -191,47 +200,35 @@ def generate_c(
191200
"""
192201
t0 = time.time()
193202

194-
# Do the actual work now
195-
serious = False
196-
result = None
197203
try:
198204
result = emitmodule.parse_and_typecheck(
199205
sources, options, compiler_options, groups, fscache
200206
)
201-
messages = result.errors
202207
except CompileError as e:
203-
messages = e.messages
204-
if not e.use_stdout:
205-
serious = True
208+
emit_messages(options, e.messages, time.time() - t0, serious=(not e.use_stdout))
209+
sys.exit(1)
206210

207211
t1 = time.time()
212+
if result.errors:
213+
emit_messages(options, result.errors, t1 - t0)
214+
sys.exit(1)
215+
208216
if compiler_options.verbose:
209217
print(f"Parsed and typechecked in {t1 - t0:.3f}s")
210218

211-
if not messages and result:
212-
errors = Errors()
213-
modules, ctext = emitmodule.compile_modules_to_c(
214-
result, compiler_options=compiler_options, errors=errors, groups=groups
215-
)
216-
217-
if errors.num_errors:
218-
messages.extend(errors.new_messages())
219-
219+
errors = Errors()
220+
modules, ctext = emitmodule.compile_modules_to_c(
221+
result, compiler_options=compiler_options, errors=errors, groups=groups
222+
)
220223
t2 = time.time()
224+
emit_messages(options, errors.new_messages(), t2 - t1)
225+
if errors.num_errors:
226+
# No need to stop the build if only warnings were emitted.
227+
sys.exit(1)
228+
221229
if compiler_options.verbose:
222230
print(f"Compiled to C in {t2 - t1:.3f}s")
223231

224-
# ... you know, just in case.
225-
if options.junit_xml:
226-
py_version = f"{options.python_version[0]}_{options.python_version[1]}"
227-
write_junit_xml(
228-
t2 - t0, serious, messages, options.junit_xml, py_version, options.platform
229-
)
230-
231-
if messages:
232-
print("\n".join(messages))
233-
sys.exit(1)
234-
235232
return ctext, "\n".join(format_modules(modules))
236233

237234

mypyc/test-data/commandline.test

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,9 @@ def h(arg: str) -> None:
223223
@a.register
224224
def i(arg: Foo) -> None:
225225
pass
226+
227+
[case testOnlyWarningOutput]
228+
# cmd: test.py
229+
230+
[file test.py]
231+
names = (str(v) for v in [1, 2, 3]) # W: Treating generator comprehension as list

mypyc/test/test_commandline.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
5858
)
5959
if "ErrorOutput" in testcase.name or cmd.returncode != 0:
6060
out += cmd.stdout
61+
elif "WarningOutput" in testcase.name:
62+
# Strip out setuptools build related output since we're only
63+
# interested in the messages emitted during compilation.
64+
messages, _, _ = cmd.stdout.partition(b"running build_ext")
65+
out += messages
6166

6267
if cmd.returncode == 0:
6368
# Run main program

0 commit comments

Comments
 (0)