8000 Exit with code 2 on blocking errors by msullivan · Pull Request #4443 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Exit with code 2 on blocking errors #4443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 9, 2018
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
8000
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ def flush_errors(a: List[str], serious: bool) -> None:
f.write(m + '\n')
f.flush()
except BrokenPipeError:
sys.exit(1)
sys.exit(2)

serious = False
blockers = False
try:
type_check_only(sources, bin_dir, options, flush_errors)
except CompileError as e:
blockers = True
if not e.use_stdout:
serious = True
if options.warn_unused_configs and options.unused_configs:
Expand All @@ -89,7 +91,8 @@ def flush_errors(a: List[str], serious: bool) -> None:
t1 = time.time()
util.write_junit_xml(t1 - t0, serious, messages, options.junit_xml)
if messages:
sys.exit(1)
code = 2 if blockers else 1
sys.exit(code)


def find_bin_directory(script_path: str) -> str:
Expand Down
4 changes: 4 additions & 0 deletions mypy/test/testcmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def test_python_cmdline(testcase: DataDrivenTestCase) -> None:
outb = process.stdout.read()
# Split output into lines.
out = [s.rstrip('\n\r') for s in str(outb, 'utf8').splitlines()]
result = process.wait()
# Remove temp file.
os.remove(program_path)
# Compare actual output to expected.
Expand All @@ -78,6 +79,9 @@ def test_python_cmdline(testcase: DataDrivenTestCase) -> None:
path))
else:
out = normalize_error_messages(out)
obvious_result = 1 if out else 0
if obvious_result != result:
out.append('== Return code: {}'.format(result))
assert_string_arrays_equal(testcase.output, out,
'Invalid output ({}, line {})'.format(
testcase.file, testcase.line))
Expand Down
40 changes: 39 additions & 1 deletion test-data/unit/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
-- The initial line specifies the command line, in the format
--
-- # cmd: mypy <options>

--
-- '== Return code: <value>' is added to the output when the process return code
-- is "nonobvious" -- that is, when it is something other than 0 if there are no
-- messages and 1 if there are.

-- Directories/packages on the command line
-- ----------------------------------------
Expand Down Expand Up @@ -89,6 +92,7 @@ sub.pkg is not a valid Python package name
# coding: uft-8
[out]
mypy: can't decode file 'a.py': unknown encoding: uft-8
== Return code: 2

[case testCannotIgnoreDuplicateModule]
# cmd: mypy one/mod/__init__.py two/mod/__init__.py
Expand All @@ -98,6 +102,7 @@ mypy: can't decode file 'a.py': unknown encoding: uft-8
# type: ignore
[out]
two/mod/__init__.py: error: Duplicate module named 'mod'
== Return code: 2

[case testFlagsFile]
# cmd: mypy @flagsfile
Expand Down Expand Up @@ -225,6 +230,7 @@ x.py:1: error: Function is missing a type annotation
[file mypy.ini]
[out]
mypy.ini: No [mypy] section in config file
== Return code: 0

[case testConfigErrorUnknownFlag]
# cmd: mypy -c pass
Expand All @@ -233,6 +239,7 @@ mypy.ini: No [mypy] section in config file
bad = 0
[out]
mypy.ini: [mypy]: Unrecognized option: bad = 0
== Return code: 0

[case testConfigErrorBadBoolean]
# cmd: mypy -c pass
Expand All @@ -241,6 +248,7 @@ mypy.ini: [mypy]: Unrecognized option: bad = 0
ignore_missing_imports = nah
[out]
mypy.ini: [mypy]: ignore_missing_imports: Not a boolean: nah
== Return code: 0

[case testConfigErrorNotPerFile]
# cmd: mypy -c pass
Expand All @@ -250,6 +258,7 @@ mypy.ini: [mypy]: ignore_missing_imports: Not a boolean: nah
python_version = 3.4
[out]
mypy.ini: [mypy-*]: Per-module sections should only specify per-module flags (python_version)
== Return code: 0

[case testConfigMypyPath]
# cmd: mypy file.py
Expand Down Expand Up @@ -467,6 +476,7 @@ main.py:1: error: Cannot find module named 'a.b'
python_version = 1.0
[out]
mypy.ini: [mypy]: python_version: Python major version '1' out of range (must be 2 or 3)
== Return code: 0

[case testPythonVersionTooOld26]
# cmd: mypy -c pass
Expand All @@ -475,6 +485,7 @@ mypy.ini: [mypy]: python_version: Python major version '1' out of range (must be
python_version = 2.6
[out]
mypy.ini: [mypy]: python_version: Python 2.6 is not supported (must be 2.7)
== Return code: 0

[case testPythonVersionTooOld32]
# cmd: mypy -c pass
Expand All @@ -483,6 +494,7 @@ mypy.ini: [mypy]: python_version: Python 2.6 is not supported (must be 2.7)
python_version = 3.2
[out]
mypy.ini: [mypy]: python_version: Python 3.2 is not supported (must be 3.3 or higher)
== Return code: 0

[case testPythonVersionTooNew28]
# cmd: mypy -c pass
Expand All @@ -491,6 +503,7 @@ mypy.ini: [mypy]: python_version: Python 3.2 is not supported (must be 3.3 or hi
python_version = 2.8
[out]
mypy.ini: [mypy]: python_version: Python 2.8 is not supported (must be 2.7)
== Return code: 0

[case testPythonVersionTooNew40]
# cmd: mypy -c pass
Expand All @@ -499,6 +512,7 @@ mypy.ini: [mypy]: python_version: Python 2.8 is not supported (must be 2.7)
python_version = 4.0
[out]
mypy.ini: [mypy]: python_version: Python major version '4' out of range (must be 2 or 3)
== Return code: 0

[case testPythonVersionAccepted27]
# cmd: mypy -c pass
Expand Down Expand Up @@ -1008,3 +1022,27 @@ def get_tasks(self):
return 'whatever'
[out]
a.py:1: error: Function is missing a type annotation

[case testMissingFile]
# cmd: mypy nope.py
[out]
mypy: can't read file 'nope.py': No such file or directory
== Return code: 2

[case testParseError]
# cmd: mypy a.py
[file a.py]
def foo(
[out]
a.py:1: error: unexpected EOF while parsing
== Return code: 2

[case testParseErrorAnnots]
# cmd: mypy a.py
[file a.py]
def foo(x):
# type: (str, int) -> None
return
[out]
a.py:1: error: Type signature has too many arguments
== Return code: 2
1 change: 1 addition & 0 deletions test-data/unit/reports.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
bad_report = .
[out]
mypy.ini: [mypy]: Unrecognized report type: bad_report
== Return code: 0

[case testCoberturaParser]
# cmd: mypy --cobertura-xml-report build pkg
Expand Down
0