Skip to content

Commit

Permalink
initial conversion of exit codes to enum
Browse files Browse the repository at this point in the history
  • Loading branch information
RonnyPfannschmidt committed Jun 7, 2019
1 parent 042a10f commit 94b4ead
Show file tree
Hide file tree
Showing 19 changed files with 86 additions and 91 deletions.
4 changes: 2 additions & 2 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def main(args=None, plugins=None):
:arg plugins: list of plugin objects to be auto-registered during
initialization.
"""
from _pytest.main import EXIT_USAGEERROR
from _pytest.main import ExitCode

try:
try:
Expand Down Expand Up @@ -79,7 +79,7 @@ def main(args=None, plugins=None):
tw = py.io.TerminalWriter(sys.stderr)
for msg in e.args:
tw.line("ERROR: {}\n".format(msg), red=True)
return EXIT_USAGEERROR
return ExitCode.USAGE_ERROR


class cmdline: # compatibility namespace
Expand Down
28 changes: 16 additions & 12 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" core implementation of testing process: init, session, runtest loop. """
import fnmatch
import enum
import functools
import os
import pkgutil
Expand All @@ -19,12 +20,15 @@
from _pytest.runner import collect_one_node

# exitcodes for the command line
EXIT_OK = 0
EXIT_TESTSFAILED = 1
EXIT_INTERRUPTED = 2
EXIT_INTERNALERROR = 3
EXIT_USAGEERROR = 4
EXIT_NOTESTSCOLLECTED = 5


class ExitCode(enum.IntEnum):
OK = 0
TESTS_FAILED = 1
INTERRUPTED = 2
INTERNAL_ERROR = 3
USAGE_ERROR = 4
NO_TESTS_COLLECTED = 5


def pytest_addoption(parser):
Expand Down Expand Up @@ -188,7 +192,7 @@ def pytest_configure(config):
def wrap_session(config, doit):
"""Skeleton command line program"""
session = Session(config)
session.exitstatus = EXIT_OK
session.exitstatus = ExitCode.OK
initstate = 0
try:
try:
Expand All @@ -201,10 +205,10 @@ def wrap_session(config, doit):
session.exitstatus = EXIT_USAGEERROR
raise
except Failed:
session.exitstatus = EXIT_TESTSFAILED
session.exitstatus = ExitCode.TESTS_FAILED
except (KeyboardInterrupt, exit.Exception):
excinfo = _pytest._code.ExceptionInfo.from_current()
exitstatus = EXIT_INTERRUPTED
exitstatus = ExitCode.INTERRUPTED
if isinstance(excinfo.value, exit.Exception):
if excinfo.value.returncode is not None:
exitstatus = excinfo.value.returncode
Expand All @@ -217,7 +221,7 @@ def wrap_session(config, doit):
except: # noqa
excinfo = _pytest._code.ExceptionInfo.from_current()
config.notify_exception(excinfo, config.option)
session.exitstatus = EXIT_INTERNALERROR
session.exitstatus = ExitCode.INTERNAL_ERROR
if excinfo.errisinstance(SystemExit):
sys.stderr.write("mainloop: caught unexpected SystemExit!\n")

Expand All @@ -243,9 +247,9 @@ def _main(config, session):
config.hook.pytest_runtestloop(session=session)

if session.testsfailed:
return EXIT_TESTSFAILED
return ExitCode.TESTS_FAILED
elif session.testscollected == 0:
return EXIT_NOTESTSCOLLECTED
return ExitCode.NO_TESTS_COLLECTED


def pytest_collection(session):
Expand Down
11 changes: 5 additions & 6 deletions src/_pytest/pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
from _pytest.assertion.rewrite import AssertionRewritingHook
from _pytest.capture import MultiCapture
from _pytest.capture import SysCapture
from _pytest.main import EXIT_INTERRUPTED
from _pytest.main import EXIT_OK
from _pytest.main import ExitCode
from _pytest.main import Session
from _pytest.monkeypatch import MonkeyPatch
from _pytest.pathlib import Path
Expand Down Expand Up @@ -691,7 +690,7 @@ def getnode(self, config, arg):
p = py.path.local(arg)
config.hook.pytest_sessionstart(session=session)
res = session.perform_collect([str(p)], genitems=False)[0]
config.hook.pytest_sessionfinish(session=session, exitstatus=EXIT_OK)
config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK)
return res

def getpathnode(self, path):
Expand All @@ -708,11 +707,11 @@ def getpathnode(self, path):
x = session.fspath.bestrelpath(path)
config.hook.pytest_sessionstart(session=session)
res = session.perform_collect([x], genitems=False)[0]
config.hook.pytest_sessionfinish(session=session, exitstatus=EXIT_OK)
config.hook.pytest_sessionfinish(session=session, exitstatus=ExitCode.OK)
return res

def genitems(self, colitems):
"""Generate all test items from a collection node.
"""Generate all test items from a collection node.src/_pytest/main.py
This recurses into the collection node and returns a list of all the
test items contained within.
Expand Down Expand Up @@ -841,7 +840,7 @@ class reprec:

# typically we reraise keyboard interrupts from the child run
# because it's our user requesting interruption of the testing
if ret == EXIT_INTERRUPTED and not no_reraise_ctrlc:
if ret == ExitCode.INTERRUPTED and not no_reraise_ctrlc:
calls = reprec.getcalls("pytest_keyboard_interrupt")
if calls and calls[-1].excinfo.type == KeyboardInterrupt:
raise KeyboardInterrupt()
Expand Down
18 changes: 7 additions & 11 deletions src/_pytest/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@

import pytest
from _pytest import nodes
from _pytest.main import EXIT_INTERRUPTED
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import EXIT_OK
from _pytest.main import EXIT_TESTSFAILED
from _pytest.main import EXIT_USAGEERROR
from _pytest.main import ExitCode

REPORT_COLLECTING_RESOLUTION = 0.5

Expand Down Expand Up @@ -654,17 +650,17 @@ def pytest_sessionfinish(self, exitstatus):
outcome.get_result()
self._tw.line("")
summary_exit_codes = (
EXIT_OK,
EXIT_TESTSFAILED,
EXIT_INTERRUPTED,
EXIT_USAGEERROR,
EXIT_NOTESTSCOLLECTED,
ExitCode.OK,
ExitCode.TESTS_FAILED,
ExitCode.INTERRUPTED,
ExitCode.USAGE_ERROR,
ExitCode.NO_TESTS_COLLECTED,
)
if exitstatus in summary_exit_codes:
self.config.hook.pytest_terminal_summary(
terminalreporter=self, exitstatus=exitstatus, config=self.config
)
if exitstatus == EXIT_INTERRUPTED:
if exitstatus == ExitCode.INTERRUPTED:
self._report_keyboardinterrupt()
del self._keyboardinterrupt_memo
self.summary_stats()
Expand Down
2 changes: 2 additions & 0 deletions src/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from _pytest.fixtures import fixture
from _pytest.fixtures import yield_fixture
from _pytest.freeze_support import freeze_includes
from _pytest.main import ExitCode
from _pytest.main import Session
from _pytest.mark import MARK_GEN as mark
from _pytest.mark import param
Expand Down Expand Up @@ -57,6 +58,7 @@
"Collector",
"deprecated_call",
"exit",
"ExitCode",
"fail",
"File",
"fixture",
Expand Down
23 changes: 11 additions & 12 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
import py

import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import EXIT_USAGEERROR
from _pytest.main import ExitCode
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG


Expand All @@ -24,7 +23,7 @@ class TestGeneralUsage:
def test_config_error(self, testdir):
testdir.copy_example("conftest_usageerror/conftest.py")
result = testdir.runpytest(testdir.tmpdir)
assert result.ret == EXIT_USAGEERROR
assert result.ret == ExitCode.USAGE_ERROR
result.stderr.fnmatch_lines(["*ERROR: hello"])
result.stdout.fnmatch_lines(["*pytest_unconfigure_called"])

Expand Down Expand Up @@ -83,7 +82,7 @@ def pytest_unconfigure():
"""
)
result = testdir.runpytest("-s", "asd")
assert result.ret == 4 # EXIT_USAGEERROR
assert result.ret == ExitCode.USAGE_ERROR
result.stderr.fnmatch_lines(["ERROR: file not found*asd"])
result.stdout.fnmatch_lines(["*---configure", "*---unconfigure"])

Expand Down Expand Up @@ -229,7 +228,7 @@ def pytest_collect_directory():
"""
)
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result.stdout.fnmatch_lines(["*1 skip*"])

def test_issue88_initial_file_multinodes(self, testdir):
Expand All @@ -247,7 +246,7 @@ def test_issue93_initialnode_importing_capturing(self, testdir):
"""
)
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
assert "should not be seen" not in result.stdout.str()
assert "stderr42" not in result.stderr.str()

Expand Down Expand Up @@ -290,13 +289,13 @@ def test_issue109_sibling_conftests_not_loaded(self, testdir):
sub2 = testdir.mkdir("sub2")
sub1.join("conftest.py").write("assert 0")
result = testdir.runpytest(sub2)
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
sub2.ensure("__init__.py")
p = sub2.ensure("test_hello.py")
result = testdir.runpytest(p)
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result = testdir.runpytest(sub1)
assert result.ret == EXIT_USAGEERROR
assert result.ret == ExitCode.USAGE_ERROR

def test_directory_skipped(self, testdir):
testdir.makeconftest(
Expand All @@ -308,7 +307,7 @@ def pytest_ignore_collect():
)
testdir.makepyfile("def test_hello(): pass")
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result.stdout.fnmatch_lines(["*1 skipped*"])

def test_multiple_items_per_collector_byid(self, testdir):
Expand Down Expand Up @@ -612,7 +611,7 @@ def test_invoke_with_invalid_type(self, capsys):

def test_invoke_with_path(self, tmpdir, capsys):
retcode = pytest.main(tmpdir)
assert retcode == EXIT_NOTESTSCOLLECTED
assert retcode == ExitCode.NO_TESTS_COLLECTED
out, err = capsys.readouterr()

def test_invoke_plugin_api(self, testdir, capsys):
Expand Down Expand Up @@ -1160,7 +1159,7 @@ def test_fixture_mock_integration(testdir):

def test_usage_error_code(testdir):
result = testdir.runpytest("-unknown-option-")
assert result.ret == EXIT_USAGEERROR
assert result.ret == ExitCode.USAGE_ERROR


@pytest.mark.filterwarnings("default")
Expand Down
6 changes: 3 additions & 3 deletions testing/python/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import _pytest._code
import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import ExitCode
from _pytest.nodes import Collector


Expand Down Expand Up @@ -246,7 +246,7 @@ def prop(self):
"""
)
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED


class TestFunction:
Expand Down Expand Up @@ -1140,7 +1140,7 @@ class Test(object):
)
result = testdir.runpytest()
assert "TypeError" not in result.stdout.str()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED


def test_collect_functools_partial(testdir):
Expand Down
6 changes: 3 additions & 3 deletions testing/test_assertrewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from _pytest.assertion.rewrite import AssertionRewritingHook
from _pytest.assertion.rewrite import PYTEST_TAG
from _pytest.assertion.rewrite import rewrite_asserts
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import ExitCode


def setup_module(mod):
Expand Down Expand Up @@ -692,7 +692,7 @@ def test_zipfile(self, testdir):
import test_gum.test_lizard"""
% (z_fn,)
)
assert testdir.runpytest().ret == EXIT_NOTESTSCOLLECTED
assert testdir.runpytest().ret == ExitCode.NO_TESTS_COLLECTED

def test_readonly(self, testdir):
sub = testdir.mkdir("testing")
Expand Down Expand Up @@ -792,7 +792,7 @@ def test_package_without__init__py(self, testdir):
pkg = testdir.mkdir("a_package_without_init_py")
pkg.join("module.py").ensure()
testdir.makepyfile("import a_package_without_init_py.module")
assert testdir.runpytest().ret == EXIT_NOTESTSCOLLECTED
assert testdir.runpytest().ret == ExitCode.NO_TESTS_COLLECTED

def test_rewrite_warning(self, testdir):
testdir.makeconftest(
Expand Down
4 changes: 2 additions & 2 deletions testing/test_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import pytest
from _pytest import capture
from _pytest.capture import CaptureManager
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import ExitCode

# note: py.io capture tests where copied from
# pylib 1.4.20.dev2 (rev 13d9af95547e)
Expand Down Expand Up @@ -361,7 +361,7 @@ def test_conftestlogging_is_shown(self, testdir):
)
# make sure that logging is still captured in tests
result = testdir.runpytest_subprocess("-s", "-p", "no:capturelog")
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result.stderr.fnmatch_lines(["WARNING*hello435*"])
assert "operation on closed file" not in result.stderr.str()

Expand Down
7 changes: 3 additions & 4 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

import pytest
from _pytest.main import _in_venv
from _pytest.main import EXIT_INTERRUPTED
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.main import ExitCode
from _pytest.main import Session


Expand Down Expand Up @@ -347,7 +346,7 @@ def pytest_ignore_collect(path, config):
assert result.ret == 0
result.stdout.fnmatch_lines(["*1 passed*"])
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
result.stdout.fnmatch_lines(["*collected 0 items*"])

def test_collectignore_exclude_on_option(self, testdir):
Expand All @@ -364,7 +363,7 @@ def pytest_configure(config):
testdir.mkdir("hello")
testdir.makepyfile(test_world="def test_hello(): pass")
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED
assert "passed" not in result.stdout.str()
result = testdir.runpytest("--XX")
assert result.ret == 0
Expand Down
Loading

0 comments on commit 94b4ead

Please sign in to comment.