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 57bf9d6 commit c9f7dea
Show file tree
Hide file tree
Showing 20 changed files with 89 additions and 93 deletions.
4 changes: 2 additions & 2 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,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 @@ -84,7 +84,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(object): # compatibility namespace
Expand Down
4 changes: 2 additions & 2 deletions src/_pytest/config/argparsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import py
import six

from ..main import EXIT_USAGEERROR
from ..main import ExitCode

FILE_OR_DIR = "file_or_dir"

Expand Down Expand Up @@ -344,7 +344,7 @@ def error(self, message):
Overrides the method in parent class to change exit code"""
self.print_usage(_sys.stderr)
args = {"prog": self.prog, "message": message}
self.exit(EXIT_USAGEERROR, _("%(prog)s: error: %(message)s\n") % args)
self.exit(ExitCode.USAGE_ERROR, _("%(prog)s: error: %(message)s\n") % args)

def parse_args(self, args=None, namespace=None):
"""allow splitting of positional arguments"""
Expand Down
28 changes: 16 additions & 12 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import print_function

import contextlib
import enum
import functools
import os
import pkgutil
Expand All @@ -25,12 +26,15 @@


# 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 @@ -192,7 +196,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 @@ -204,10 +208,10 @@ def wrap_session(config, doit):
except 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 initstate <= 2 and isinstance(excinfo.value, exit.Exception):
sys.stderr.write("{}: {}\n".format(excinfo.typename, excinfo.value.msg))
if excinfo.value.returncode is not None:
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 Spurious 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 @@ -24,8 +24,7 @@
from _pytest.capture import MultiCapture
from _pytest.capture import SysCapture
from _pytest.compat import safe_str
from _pytest.main import EXIT_INTERRUPTED
from _pytest.main import EXIT_OK
from _pytest.main import ExitCode
from _pytest.main import Session
from _pytest.pathlib import Path

Expand Down Expand Up @@ -722,7 +721,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 @@ -739,11 +738,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 @@ -865,7 +864,7 @@ class reprec(object):

# 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 kwargs.get("no_reraise_ctrlc"):
if ret == ExitCode.INTERRUPTED and not kwargs.get("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 @@ -20,11 +20,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


class MoreQuietAction(argparse.Action):
Expand Down Expand Up @@ -622,17 +618,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
)
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 @@ -51,6 +52,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 @@ -12,8 +12,7 @@
import six

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 @@ -28,7 +27,7 @@ class TestGeneralUsage(object):
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 @@ -87,7 +86,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 @@ -194,7 +193,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 @@ -212,7 +211,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 @@ -255,13 +254,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 @@ -273,7 +272,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 @@ -568,7 +567,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 @@ -1109,4 +1108,4 @@ 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
6 changes: 3 additions & 3 deletions testing/python/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,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 @@ -237,7 +237,7 @@ def prop(self):
"""
)
result = testdir.runpytest()
assert result.ret == EXIT_NOTESTSCOLLECTED
assert result.ret == ExitCode.NO_TESTS_COLLECTED


@pytest.mark.filterwarnings(
Expand Down Expand Up @@ -1136,7 +1136,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 @@ -20,7 +20,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

ast = pytest.importorskip("ast")
if sys.platform.startswith("java"):
Expand Down Expand Up @@ -701,7 +701,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 @@ -808,7 +808,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 @@ -16,7 +16,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 @@ -359,7 +359,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
6 changes: 3 additions & 3 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

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


Expand Down Expand Up @@ -351,7 +351,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 @@ -368,7 +368,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 c9f7dea

Please sign in to comment.