diff options
| author | shadchin <[email protected]> | 2022-02-10 16:44:30 +0300 | 
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:44:30 +0300 | 
| commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
| tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/python/pytest/py3/_pytest/skipping.py | |
| parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/skipping.py')
| -rw-r--r-- | contrib/python/pytest/py3/_pytest/skipping.py | 492 | 
1 files changed, 246 insertions, 246 deletions
diff --git a/contrib/python/pytest/py3/_pytest/skipping.py b/contrib/python/pytest/py3/_pytest/skipping.py index 9aacfecee7a..571ad4880cd 100644 --- a/contrib/python/pytest/py3/_pytest/skipping.py +++ b/contrib/python/pytest/py3/_pytest/skipping.py @@ -1,37 +1,37 @@ -"""Support for skip/xfail functions and markers.""" -import os -import platform -import sys -import traceback -from collections.abc import Mapping -from typing import Generator -from typing import Optional -from typing import Tuple -from typing import Type - -import attr - -from _pytest.config import Config +"""Support for skip/xfail functions and markers."""  +import os  +import platform  +import sys  +import traceback  +from collections.abc import Mapping  +from typing import Generator  +from typing import Optional  +from typing import Tuple  +from typing import Type  +  +import attr  +  +from _pytest.config import Config   from _pytest.config import hookimpl -from _pytest.config.argparsing import Parser -from _pytest.mark.structures import Mark -from _pytest.nodes import Item +from _pytest.config.argparsing import Parser  +from _pytest.mark.structures import Mark  +from _pytest.nodes import Item   from _pytest.outcomes import fail  from _pytest.outcomes import skip  from _pytest.outcomes import xfail -from _pytest.reports import BaseReport -from _pytest.runner import CallInfo -from _pytest.store import StoreKey +from _pytest.reports import BaseReport  +from _pytest.runner import CallInfo  +from _pytest.store import StoreKey  -def pytest_addoption(parser: Parser) -> None: +def pytest_addoption(parser: Parser) -> None:       group = parser.getgroup("general")      group.addoption(          "--runxfail",          action="store_true",          dest="runxfail",          default=False, -        help="report the results of xfail tests as if they were not marked", +        help="report the results of xfail tests as if they were not marked",       )      parser.addini( @@ -43,7 +43,7 @@ def pytest_addoption(parser: Parser) -> None:      ) -def pytest_configure(config: Config) -> None: +def pytest_configure(config: Config) -> None:       if config.option.runxfail:          # yay a hack          import pytest @@ -54,7 +54,7 @@ def pytest_configure(config: Config) -> None:          def nop(*args, **kwargs):              pass -        nop.Exception = xfail.Exception  # type: ignore[attr-defined] +        nop.Exception = xfail.Exception  # type: ignore[attr-defined]           setattr(pytest, "xfail", nop)      config.addinivalue_line( @@ -65,260 +65,260 @@ def pytest_configure(config: Config) -> None:      )      config.addinivalue_line(          "markers", -        "skipif(condition, ..., *, reason=...): " -        "skip the given test function if any of the conditions evaluate to True. " -        "Example: skipif(sys.platform == 'win32') skips the test if we are on the win32 platform. " -        "See https://docs.pytest.org/en/stable/reference.html#pytest-mark-skipif", +        "skipif(condition, ..., *, reason=...): "  +        "skip the given test function if any of the conditions evaluate to True. "  +        "Example: skipif(sys.platform == 'win32') skips the test if we are on the win32 platform. "  +        "See https://docs.pytest.org/en/stable/reference.html#pytest-mark-skipif",       )      config.addinivalue_line(          "markers", -        "xfail(condition, ..., *, reason=..., run=True, raises=None, strict=xfail_strict): " -        "mark the test function as an expected failure if any of the conditions " -        "evaluate to True. Optionally specify a reason for better reporting " +        "xfail(condition, ..., *, reason=..., run=True, raises=None, strict=xfail_strict): "  +        "mark the test function as an expected failure if any of the conditions "  +        "evaluate to True. Optionally specify a reason for better reporting "           "and run=False if you don't even want to execute the test function. "          "If only specific exception(s) are expected, you can list them in "          "raises, and if the test fails in other ways, it will be reported as " -        "a true failure. See https://docs.pytest.org/en/stable/reference.html#pytest-mark-xfail", +        "a true failure. See https://docs.pytest.org/en/stable/reference.html#pytest-mark-xfail",       ) -def evaluate_condition(item: Item, mark: Mark, condition: object) -> Tuple[bool, str]: -    """Evaluate a single skipif/xfail condition. - -    If an old-style string condition is given, it is eval()'d, otherwise the -    condition is bool()'d. If this fails, an appropriately formatted pytest.fail -    is raised. - -    Returns (result, reason). The reason is only relevant if the result is True. -    """ -    # String condition. -    if isinstance(condition, str): -        globals_ = { -            "os": os, -            "sys": sys, -            "platform": platform, -            "config": item.config, -        } -        for dictionary in reversed( -            item.ihook.pytest_markeval_namespace(config=item.config) -        ): -            if not isinstance(dictionary, Mapping): -                raise ValueError( -                    "pytest_markeval_namespace() needs to return a dict, got {!r}".format( -                        dictionary -                    ) -                ) -            globals_.update(dictionary) -        if hasattr(item, "obj"): -            globals_.update(item.obj.__globals__)  # type: ignore[attr-defined] -        try: -            filename = f"<{mark.name} condition>" -            condition_code = compile(condition, filename, "eval") -            result = eval(condition_code, globals_) -        except SyntaxError as exc: -            msglines = [ -                "Error evaluating %r condition" % mark.name, -                "    " + condition, -                "    " + " " * (exc.offset or 0) + "^", -                "SyntaxError: invalid syntax", -            ] -            fail("\n".join(msglines), pytrace=False) -        except Exception as exc: -            msglines = [ -                "Error evaluating %r condition" % mark.name, -                "    " + condition, -                *traceback.format_exception_only(type(exc), exc), -            ] -            fail("\n".join(msglines), pytrace=False) - -    # Boolean condition. -    else: -        try: -            result = bool(condition) -        except Exception as exc: -            msglines = [ -                "Error evaluating %r condition as a boolean" % mark.name, -                *traceback.format_exception_only(type(exc), exc), -            ] -            fail("\n".join(msglines), pytrace=False) - -    reason = mark.kwargs.get("reason", None) -    if reason is None: -        if isinstance(condition, str): -            reason = "condition: " + condition +def evaluate_condition(item: Item, mark: Mark, condition: object) -> Tuple[bool, str]:  +    """Evaluate a single skipif/xfail condition.  + +    If an old-style string condition is given, it is eval()'d, otherwise the  +    condition is bool()'d. If this fails, an appropriately formatted pytest.fail  +    is raised.  +  +    Returns (result, reason). The reason is only relevant if the result is True.  +    """  +    # String condition.  +    if isinstance(condition, str):  +        globals_ = {  +            "os": os,  +            "sys": sys,  +            "platform": platform,  +            "config": item.config,  +        }  +        for dictionary in reversed(  +            item.ihook.pytest_markeval_namespace(config=item.config)  +        ):  +            if not isinstance(dictionary, Mapping):  +                raise ValueError(  +                    "pytest_markeval_namespace() needs to return a dict, got {!r}".format(  +                        dictionary  +                    )  +                )  +            globals_.update(dictionary)  +        if hasattr(item, "obj"):  +            globals_.update(item.obj.__globals__)  # type: ignore[attr-defined]  +        try:  +            filename = f"<{mark.name} condition>"  +            condition_code = compile(condition, filename, "eval")  +            result = eval(condition_code, globals_)  +        except SyntaxError as exc:  +            msglines = [  +                "Error evaluating %r condition" % mark.name,  +                "    " + condition,  +                "    " + " " * (exc.offset or 0) + "^",  +                "SyntaxError: invalid syntax",  +            ]  +            fail("\n".join(msglines), pytrace=False)  +        except Exception as exc:  +            msglines = [  +                "Error evaluating %r condition" % mark.name,  +                "    " + condition,  +                *traceback.format_exception_only(type(exc), exc),  +            ]  +            fail("\n".join(msglines), pytrace=False)  +  +    # Boolean condition.  +    else:  +        try:  +            result = bool(condition)  +        except Exception as exc:  +            msglines = [  +                "Error evaluating %r condition as a boolean" % mark.name,  +                *traceback.format_exception_only(type(exc), exc),  +            ]  +            fail("\n".join(msglines), pytrace=False)  +  +    reason = mark.kwargs.get("reason", None)  +    if reason is None:  +        if isinstance(condition, str):  +            reason = "condition: " + condition           else: -            # XXX better be checked at collection time -            msg = ( -                "Error evaluating %r: " % mark.name -                + "you need to specify reason=STRING when using booleans as conditions." -            ) -            fail(msg, pytrace=False) - -    return result, reason - - [email protected](slots=True, frozen=True) -class Skip: -    """The result of evaluate_skip_marks().""" - -    reason = attr.ib(type=str) - - -def evaluate_skip_marks(item: Item) -> Optional[Skip]: -    """Evaluate skip and skipif marks on item, returning Skip if triggered.""" -    for mark in item.iter_markers(name="skipif"): -        if "condition" not in mark.kwargs: -            conditions = mark.args -        else: -            conditions = (mark.kwargs["condition"],) - -        # Unconditional. -        if not conditions: -            reason = mark.kwargs.get("reason", "") -            return Skip(reason) - -        # If any of the conditions are true. -        for condition in conditions: -            result, reason = evaluate_condition(item, mark, condition) -            if result: -                return Skip(reason) - -    for mark in item.iter_markers(name="skip"): -        if "reason" in mark.kwargs: -            reason = mark.kwargs["reason"] -        elif mark.args: -            reason = mark.args[0] -        else: -            reason = "unconditional skip" -        return Skip(reason) - -    return None - - [email protected](slots=True, frozen=True) -class Xfail: -    """The result of evaluate_xfail_marks().""" - -    reason = attr.ib(type=str) -    run = attr.ib(type=bool) -    strict = attr.ib(type=bool) -    raises = attr.ib(type=Optional[Tuple[Type[BaseException], ...]]) - - -def evaluate_xfail_marks(item: Item) -> Optional[Xfail]: -    """Evaluate xfail marks on item, returning Xfail if triggered.""" -    for mark in item.iter_markers(name="xfail"): -        run = mark.kwargs.get("run", True) -        strict = mark.kwargs.get("strict", item.config.getini("xfail_strict")) -        raises = mark.kwargs.get("raises", None) -        if "condition" not in mark.kwargs: -            conditions = mark.args -        else: -            conditions = (mark.kwargs["condition"],) - -        # Unconditional. -        if not conditions: -            reason = mark.kwargs.get("reason", "") -            return Xfail(reason, run, strict, raises) - -        # If any of the conditions are true. -        for condition in conditions: -            result, reason = evaluate_condition(item, mark, condition) -            if result: -                return Xfail(reason, run, strict, raises) - -    return None - - -# Whether skipped due to skip or skipif marks. -skipped_by_mark_key = StoreKey[bool]() -# Saves the xfail mark evaluation. Can be refreshed during call if None. -xfailed_key = StoreKey[Optional[Xfail]]() -unexpectedsuccess_key = StoreKey[str]() - - -@hookimpl(tryfirst=True) -def pytest_runtest_setup(item: Item) -> None: -    skipped = evaluate_skip_marks(item) -    item._store[skipped_by_mark_key] = skipped is not None -    if skipped: -        skip(skipped.reason) - -    item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) -    if xfailed and not item.config.option.runxfail and not xfailed.run: -        xfail("[NOTRUN] " + xfailed.reason) - - -@hookimpl(hookwrapper=True) -def pytest_runtest_call(item: Item) -> Generator[None, None, None]: -    xfailed = item._store.get(xfailed_key, None) -    if xfailed is None: -        item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) - -    if xfailed and not item.config.option.runxfail and not xfailed.run: -        xfail("[NOTRUN] " + xfailed.reason) - -    yield - -    # The test run may have added an xfail mark dynamically. -    xfailed = item._store.get(xfailed_key, None) -    if xfailed is None: -        item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item) - - +            # XXX better be checked at collection time  +            msg = (  +                "Error evaluating %r: " % mark.name  +                + "you need to specify reason=STRING when using booleans as conditions."  +            )  +            fail(msg, pytrace=False)  + +    return result, reason  + + [email protected](slots=True, frozen=True)  +class Skip:  +    """The result of evaluate_skip_marks()."""  + +    reason = attr.ib(type=str)  + + +def evaluate_skip_marks(item: Item) -> Optional[Skip]:  +    """Evaluate skip and skipif marks on item, returning Skip if triggered."""  +    for mark in item.iter_markers(name="skipif"):  +        if "condition" not in mark.kwargs:  +            conditions = mark.args  +        else:  +            conditions = (mark.kwargs["condition"],)  + +        # Unconditional.  +        if not conditions:  +            reason = mark.kwargs.get("reason", "")  +            return Skip(reason)  + +        # If any of the conditions are true.  +        for condition in conditions:  +            result, reason = evaluate_condition(item, mark, condition)  +            if result:  +                return Skip(reason)  + +    for mark in item.iter_markers(name="skip"):  +        if "reason" in mark.kwargs:  +            reason = mark.kwargs["reason"]  +        elif mark.args:  +            reason = mark.args[0]  +        else:  +            reason = "unconditional skip"  +        return Skip(reason)  +  +    return None  +  +  [email protected](slots=True, frozen=True)  +class Xfail:  +    """The result of evaluate_xfail_marks()."""  +  +    reason = attr.ib(type=str)  +    run = attr.ib(type=bool)  +    strict = attr.ib(type=bool)  +    raises = attr.ib(type=Optional[Tuple[Type[BaseException], ...]])  +  +  +def evaluate_xfail_marks(item: Item) -> Optional[Xfail]:  +    """Evaluate xfail marks on item, returning Xfail if triggered."""  +    for mark in item.iter_markers(name="xfail"):  +        run = mark.kwargs.get("run", True)  +        strict = mark.kwargs.get("strict", item.config.getini("xfail_strict"))  +        raises = mark.kwargs.get("raises", None)  +        if "condition" not in mark.kwargs:  +            conditions = mark.args  +        else:  +            conditions = (mark.kwargs["condition"],)  +  +        # Unconditional.  +        if not conditions:  +            reason = mark.kwargs.get("reason", "")  +            return Xfail(reason, run, strict, raises)  +  +        # If any of the conditions are true.  +        for condition in conditions:  +            result, reason = evaluate_condition(item, mark, condition)  +            if result:  +                return Xfail(reason, run, strict, raises)  +  +    return None  +  +  +# Whether skipped due to skip or skipif marks.  +skipped_by_mark_key = StoreKey[bool]()  +# Saves the xfail mark evaluation. Can be refreshed during call if None.  +xfailed_key = StoreKey[Optional[Xfail]]()  +unexpectedsuccess_key = StoreKey[str]()  +  +  +@hookimpl(tryfirst=True)  +def pytest_runtest_setup(item: Item) -> None:  +    skipped = evaluate_skip_marks(item)  +    item._store[skipped_by_mark_key] = skipped is not None  +    if skipped:  +        skip(skipped.reason)  +  +    item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)  +    if xfailed and not item.config.option.runxfail and not xfailed.run:  +        xfail("[NOTRUN] " + xfailed.reason)  +  +   @hookimpl(hookwrapper=True) -def pytest_runtest_makereport(item: Item, call: CallInfo[None]): +def pytest_runtest_call(item: Item) -> Generator[None, None, None]:  +    xfailed = item._store.get(xfailed_key, None)  +    if xfailed is None:  +        item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)  +  +    if xfailed and not item.config.option.runxfail and not xfailed.run:  +        xfail("[NOTRUN] " + xfailed.reason)  +  +    yield  +  +    # The test run may have added an xfail mark dynamically.  +    xfailed = item._store.get(xfailed_key, None)  +    if xfailed is None:  +        item._store[xfailed_key] = xfailed = evaluate_xfail_marks(item)  +  +  +@hookimpl(hookwrapper=True)  +def pytest_runtest_makereport(item: Item, call: CallInfo[None]):       outcome = yield      rep = outcome.get_result() -    xfailed = item._store.get(xfailed_key, None) -    # unittest special case, see setting of unexpectedsuccess_key -    if unexpectedsuccess_key in item._store and rep.when == "call": -        reason = item._store[unexpectedsuccess_key] -        if reason: -            rep.longrepr = f"Unexpected success: {reason}" +    xfailed = item._store.get(xfailed_key, None)  +    # unittest special case, see setting of unexpectedsuccess_key  +    if unexpectedsuccess_key in item._store and rep.when == "call":  +        reason = item._store[unexpectedsuccess_key]  +        if reason:  +            rep.longrepr = f"Unexpected success: {reason}"           else:              rep.longrepr = "Unexpected success" -        rep.outcome = "failed" +        rep.outcome = "failed"       elif item.config.option.runxfail: -        pass  # don't interfere -    elif call.excinfo and isinstance(call.excinfo.value, xfail.Exception): -        assert call.excinfo.value.msg is not None +        pass  # don't interfere  +    elif call.excinfo and isinstance(call.excinfo.value, xfail.Exception):  +        assert call.excinfo.value.msg is not None           rep.wasxfail = "reason: " + call.excinfo.value.msg          rep.outcome = "skipped" -    elif not rep.skipped and xfailed: +    elif not rep.skipped and xfailed:           if call.excinfo: -            raises = xfailed.raises -            if raises is not None and not isinstance(call.excinfo.value, raises): +            raises = xfailed.raises  +            if raises is not None and not isinstance(call.excinfo.value, raises):                   rep.outcome = "failed"              else:                  rep.outcome = "skipped" -                rep.wasxfail = xfailed.reason +                rep.wasxfail = xfailed.reason           elif call.when == "call": -            if xfailed.strict: +            if xfailed.strict:                   rep.outcome = "failed" -                rep.longrepr = "[XPASS(strict)] " + xfailed.reason +                rep.longrepr = "[XPASS(strict)] " + xfailed.reason               else:                  rep.outcome = "passed" -                rep.wasxfail = xfailed.reason - -    if ( -        item._store.get(skipped_by_mark_key, True) +                rep.wasxfail = xfailed.reason  +  +    if (  +        item._store.get(skipped_by_mark_key, True)           and rep.skipped          and type(rep.longrepr) is tuple      ): -        # Skipped by mark.skipif; change the location of the failure +        # Skipped by mark.skipif; change the location of the failure           # to point to the item definition, otherwise it will display -        # the location of where the skip exception was raised within pytest. -        _, _, reason = rep.longrepr -        filename, line = item.reportinfo()[:2] -        assert line is not None -        rep.longrepr = str(filename), line + 1, reason +        # the location of where the skip exception was raised within pytest.  +        _, _, reason = rep.longrepr  +        filename, line = item.reportinfo()[:2]  +        assert line is not None  +        rep.longrepr = str(filename), line + 1, reason  -def pytest_report_teststatus(report: BaseReport) -> Optional[Tuple[str, str, str]]: +def pytest_report_teststatus(report: BaseReport) -> Optional[Tuple[str, str, str]]:       if hasattr(report, "wasxfail"):          if report.skipped: -            return "xfailed", "x", "XFAIL" +            return "xfailed", "x", "XFAIL"           elif report.passed: -            return "xpassed", "X", "XPASS" -    return None +            return "xpassed", "X", "XPASS"  +    return None   | 
