Пример #1
0
    def import_plugin(self, modname):
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, (six.text_type, str)), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
        if modname in builtin_plugins:
            importspec = "_pytest." + modname
        else:
            importspec = modname
        self.rewrite_hook.mark_rewrite(importspec)
        try:
            __import__(importspec)
        except ImportError as e:
            new_exc_type = ImportError
            new_exc_message = 'Error importing plugin "%s": %s' % (
                modname,
                safe_str(e.args[0]),
            )
            new_exc = new_exc_type(new_exc_message)

            six.reraise(new_exc_type, new_exc, sys.exc_info()[2])

        except Skipped as e:
            self._warn("skipped plugin %r: %s" % ((modname, e.msg)))
        else:
            mod = sys.modules[importspec]
            self.register(mod, modname)
Пример #2
0
def warning_record_to_str(warning_message):
    """Convert a warnings.WarningMessage to a string, taking in account a lot of unicode shenaningans in Python 2.

    When Python 2 support is dropped this function can be greatly simplified.
    """
    warn_msg = warning_message.message
    unicode_warning = False
    if compat._PY2 and any(
            isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
        new_args = []
        for m in warn_msg.args:
            new_args.append(
                compat.ascii_escaped(m) if isinstance(m, compat.UNICODE_TYPES
                                                      ) else m)
        unicode_warning = list(warn_msg.args) != new_args
        warn_msg.args = new_args

    msg = warnings.formatwarning(
        warn_msg,
        warning_message.category,
        warning_message.filename,
        warning_message.lineno,
        warning_message.line,
    )
    if unicode_warning:
        warnings.warn(
            "Warning is using unicode non convertible to ascii, "
            "converting to a safe representation:\n  {!r}".format(
                compat.safe_str(msg)),
            UnicodeWarning,
        )
    return msg
Пример #3
0
 def import_plugin(self, modname):
     # most often modname refers to builtin modules, e.g. "pytester",
     # "terminal" or "capture".  Those plugins are registered under their
     # basename for historic purposes but must be imported with the
     # _pytest prefix.
     assert isinstance(modname, str)
     if self.get_plugin(modname) is not None:
         return
     if modname in builtin_plugins:
         importspec = "_pytest." + modname
     else:
         importspec = modname
     try:
         __import__(importspec)
     except ImportError as e:
         new_exc = ImportError('Error importing plugin "%s": %s' % (modname, safe_str(e.args[0])))
         # copy over name and path attributes
         for attr in ('name', 'path'):
             if hasattr(e, attr):
                 setattr(new_exc, attr, getattr(e, attr))
         raise new_exc
     except Exception as e:
         import pytest
         if not hasattr(pytest, 'skip') or not isinstance(e, pytest.skip.Exception):
             raise
         self._warn("skipped plugin %r: %s" %((modname, e.msg)))
     else:
         mod = sys.modules[importspec]
         self.register(mod, modname)
         self.consider_module(mod)
Пример #4
0
def warning_record_to_str(warning_message):
    """Convert a warnings.WarningMessage to a string, taking in account a lot of unicode shenaningans in Python 2.

    When Python 2 support is dropped this function can be greatly simplified.
    """
    warn_msg = warning_message.message
    unicode_warning = False
    if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
        new_args = []
        for m in warn_msg.args:
            new_args.append(
                compat.ascii_escaped(m) if isinstance(m, compat.UNICODE_TYPES) else m
            )
        unicode_warning = list(warn_msg.args) != new_args
        warn_msg.args = new_args

    msg = warnings.formatwarning(
        warn_msg,
        warning_message.category,
        warning_message.filename,
        warning_message.lineno,
        warning_message.line,
    )
    if unicode_warning:
        warnings.warn(
            "Warning is using unicode non convertible to ascii, "
            "converting to a safe representation:\n  {!r}".format(compat.safe_str(msg)),
            UnicodeWarning,
        )
    return msg
Пример #5
0
Файл: code.py Проект: LLNL/spack
    def _truncate_recursive_traceback(self, traceback):
        """
        Truncate the given recursive traceback trying to find the starting point
        of the recursion.

        The detection is done by going through each traceback entry and finding the
        point in which the locals of the frame are equal to the locals of a previous frame (see ``recursionindex()``.

        Handle the situation where the recursion process might raise an exception (for example
        comparing numpy arrays using equality raises a TypeError), in which case we do our best to
        warn the user of the error and show a limited traceback.
        """
        try:
            recursionindex = traceback.recursionindex()
        except Exception as e:
            max_frames = 10
            extraline = (
                '!!! Recursion error detected, but an error occurred locating the origin of recursion.\n'
                '  The following exception happened when comparing locals in the stack frame:\n'
                '    {exc_type}: {exc_msg}\n'
                '  Displaying first and last {max_frames} stack frames out of {total}.'
            ).format(exc_type=type(e).__name__, exc_msg=safe_str(e), max_frames=max_frames, total=len(traceback))
            traceback = traceback[:max_frames] + traceback[-max_frames:]
        else:
            if recursionindex is not None:
                extraline = "!!! Recursion detected (same locals & position)"
                traceback = traceback[:recursionindex + 1]
            else:
                extraline = None

        return traceback, extraline
Пример #6
0
    def _truncate_recursive_traceback(self, traceback):
        """
        Truncate the given recursive traceback trying to find the starting point
        of the recursion.

        The detection is done by going through each traceback entry and finding the
        point in which the locals of the frame are equal to the locals of a previous frame (see ``recursionindex()``.

        Handle the situation where the recursion process might raise an exception (for example
        comparing numpy arrays using equality raises a TypeError), in which case we do our best to
        warn the user of the error and show a limited traceback.
        """
        try:
            recursionindex = traceback.recursionindex()
        except Exception as e:
            max_frames = 10
            extraline = (
                '!!! Recursion error detected, but an error occurred locating the origin of recursion.\n'
                '  The following exception happened when comparing locals in the stack frame:\n'
                '    {exc_type}: {exc_msg}\n'
                '  Displaying first and last {max_frames} stack frames out of {total}.'
            ).format(exc_type=type(e).__name__,
                     exc_msg=safe_str(e),
                     max_frames=max_frames,
                     total=len(traceback))
            traceback = traceback[:max_frames] + traceback[-max_frames:]
        else:
            if recursionindex is not None:
                extraline = "!!! Recursion detected (same locals & position)"
                traceback = traceback[:recursionindex + 1]
            else:
                extraline = None

        return traceback, extraline
Пример #7
0
    def import_plugin(self, modname):
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(
            modname,
            (six.text_type, str)), ("module name as text required, got %r" %
                                    modname)
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return
        if modname in builtin_plugins:
            importspec = "_pytest." + modname
        else:
            importspec = modname
        self.rewrite_hook.mark_rewrite(importspec)
        try:
            __import__(importspec)
        except ImportError as e:
            new_exc_type = ImportError
            new_exc_message = 'Error importing plugin "%s": %s' % (
                modname,
                safe_str(e.args[0]),
            )
            new_exc = new_exc_type(new_exc_message)

            six.reraise(new_exc_type, new_exc, sys.exc_info()[2])

        except Skipped as e:
            self._warn("skipped plugin %r: %s" % ((modname, e.msg)))
        else:
            mod = sys.modules[importspec]
            self.register(mod, modname)
Пример #8
0
 def import_plugin(self, modname):
     # most often modname refers to builtin modules, e.g. "pytester",
     # "terminal" or "capture".  Those plugins are registered under their
     # basename for historic purposes but must be imported with the
     # _pytest prefix.
     assert isinstance(modname, str)
     if self.get_plugin(modname) is not None:
         return
     if modname in builtin_plugins:
         importspec = "_pytest." + modname
     else:
         importspec = modname
     try:
         __import__(importspec)
     except ImportError as e:
         new_exc = ImportError('Error importing plugin "%s": %s' %
                               (modname, safe_str(e.args[0])))
         # copy over name and path attributes
         for attr in ('name', 'path'):
             if hasattr(e, attr):
                 setattr(new_exc, attr, getattr(e, attr))
         raise new_exc
     except Exception as e:
         import pytest
         if not hasattr(pytest, 'skip') or not isinstance(
                 e, pytest.skip.Exception):
             raise
         self._warn("skipped plugin %r: %s" % ((modname, e.msg)))
     else:
         mod = sys.modules[importspec]
         self.register(mod, modname)
         self.consider_module(mod)
Пример #9
0
 def _ensure_basetemp(self, args):
     args = list(args)
     for x in args:
         if safe_str(x).startswith("--basetemp"):
             break
     else:
         args.append("--basetemp=%s" % self.tmpdir.dirpath("basetemp"))
     return args
Пример #10
0
 def toterminal(self, tw):
     if self.args:
         linesofar = ""
         for name, value in self.args:
             ns = "%s = %s" % (safe_str(name), safe_str(value))
             if len(ns) + len(linesofar) + 2 > tw.fullwidth:
                 if linesofar:
                     tw.line(linesofar)
                 linesofar = ns
             else:
                 if linesofar:
                     linesofar += ", " + ns
                 else:
                     linesofar = ns
         if linesofar:
             tw.line(linesofar)
         tw.line("")
Пример #11
0
 def _ensure_basetemp(self, args):
     args = list(args)
     for x in args:
         if safe_str(x).startswith("--basetemp"):
             break
     else:
         args.append("--basetemp=%s" % self.tmpdir.dirpath("basetemp"))
     return args
Пример #12
0
Файл: code.py Проект: LLNL/spack
 def toterminal(self, tw):
     if self.args:
         linesofar = ""
         for name, value in self.args:
             ns = "%s = %s" % (safe_str(name), safe_str(value))
             if len(ns) + len(linesofar) + 2 > tw.fullwidth:
                 if linesofar:
                     tw.line(linesofar)
                 linesofar = ns
             else:
                 if linesofar:
                     linesofar += ", " + ns
                 else:
                     linesofar = ns
         if linesofar:
             tw.line(linesofar)
         tw.line("")
Пример #13
0
 def __repr__(self):
     if self.excinfo is not None:
         status = "exception"
         value = self.excinfo.value
     else:
         # TODO: investigate unification
         value = repr(self._result)
         status = "result"
     return "<CallInfo when={when!r} {status}: {value}>".format(
         when=self.when, value=safe_str(value), status=status)
Пример #14
0
    def _importtestmodule(self):
        # we assume we are only called once per module
        importmode = self.config.getoption("--import-mode")
        try:
            mod = self.fspath.pyimport(ensuresyspath=importmode)
        except SyntaxError:
            raise self.CollectError(
                _pytest._code.ExceptionInfo().getrepr(style="short")
            )
        except self.fspath.ImportMismatchError:
            e = sys.exc_info()[1]
            raise self.CollectError(
                "import file mismatch:\n"
                "imported module %r has this __file__ attribute:\n"
                "  %s\n"
                "which is not the same as the test file we want to collect:\n"
                "  %s\n"
                "HINT: remove __pycache__ / .pyc files and/or use a "
                "unique basename for your test file modules" % e.args
            )
        except ImportError:
            from _pytest._code.code import ExceptionInfo

            exc_info = ExceptionInfo()
            if self.config.getoption("verbose") < 2:
                exc_info.traceback = exc_info.traceback.filter(filter_traceback)
            exc_repr = (
                exc_info.getrepr(style="short")
                if exc_info.traceback
                else exc_info.exconly()
            )
            formatted_tb = safe_str(exc_repr)
            raise self.CollectError(
                "ImportError while importing test module '{fspath}'.\n"
                "Hint: make sure your test modules/packages have valid Python names.\n"
                "Traceback:\n"
                "{traceback}".format(fspath=self.fspath, traceback=formatted_tb)
            )
        except _pytest.runner.Skipped as e:
            if e.allow_module_level:
                raise
            raise self.CollectError(
                "Using pytest.skip outside of a test is not allowed. "
                "To decorate a test function, use the @pytest.mark.skip "
                "or @pytest.mark.skipif decorators instead, and to skip a "
                "module use `pytestmark = pytest.mark.{skip,skipif}."
            )
        self.config.pluginmanager.consider_module(mod)
        return mod
Пример #15
0
    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(
            modname,
            six.string_types), ("module name as text required, got %r" %
                                modname)
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return

        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)

        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return

        try:
            __import__(importspec)
        except ImportError as e:
            new_exc_message = 'Error importing plugin "%s": %s' % (
                modname,
                safe_str(e.args[0]),
            )
            new_exc = ImportError(new_exc_message)
            tb = sys.exc_info()[2]

            six.reraise(ImportError, new_exc, tb)

        except Skipped as e:
            from _pytest.warnings import _issue_warning_captured

            _issue_warning_captured(
                PytestConfigWarning("skipped plugin %r: %s" %
                                    (modname, e.msg)),
                self.hook,
                stacklevel=1,
            )
        else:
            mod = sys.modules[importspec]
            self.register(mod, modname)
Пример #16
0
    def _importtestmodule(self):
        # we assume we are only called once per module
        importmode = self.config.getoption("--import-mode")
        try:
            mod = self.fspath.pyimport(ensuresyspath=importmode)
        except SyntaxError:
            raise self.CollectError(
                _pytest._code.ExceptionInfo().getrepr(style="short")
            )
        except self.fspath.ImportMismatchError:
            e = sys.exc_info()[1]
            raise self.CollectError(
                "import file mismatch:\n"
                "imported module %r has this __file__ attribute:\n"
                "  %s\n"
                "which is not the same as the test file we want to collect:\n"
                "  %s\n"
                "HINT: remove __pycache__ / .pyc files and/or use a "
                "unique basename for your test file modules" % e.args
            )
        except ImportError:
            from _pytest._code.code import ExceptionInfo

            exc_info = ExceptionInfo()
            if self.config.getoption("verbose") < 2:
                exc_info.traceback = exc_info.traceback.filter(filter_traceback)
            exc_repr = (
                exc_info.getrepr(style="short")
                if exc_info.traceback
                else exc_info.exconly()
            )
            formatted_tb = safe_str(exc_repr)
            raise self.CollectError(
                "ImportError while importing test module '{fspath}'.\n"
                "Hint: make sure your test modules/packages have valid Python names.\n"
                "Traceback:\n"
                "{traceback}".format(fspath=self.fspath, traceback=formatted_tb)
            )
        except _pytest.runner.Skipped as e:
            if e.allow_module_level:
                raise
            raise self.CollectError(
                "Using pytest.skip outside of a test is not allowed. "
                "To decorate a test function, use the @pytest.mark.skip "
                "or @pytest.mark.skipif decorators instead, and to skip a "
                "module use `pytestmark = pytest.mark.{skip,skipif}."
            )
        self.config.pluginmanager.consider_module(mod)
        return mod
Пример #17
0
    def import_plugin(self, modname, consider_entry_points=False):
        """
        Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
        names are also considered to find a plugin.
        """
        # most often modname refers to builtin modules, e.g. "pytester",
        # "terminal" or "capture".  Those plugins are registered under their
        # basename for historic purposes but must be imported with the
        # _pytest prefix.
        assert isinstance(modname, six.string_types), (
            "module name as text required, got %r" % modname
        )
        modname = str(modname)
        if self.is_blocked(modname) or self.get_plugin(modname) is not None:
            return

        importspec = "_pytest." + modname if modname in builtin_plugins else modname
        self.rewrite_hook.mark_rewrite(importspec)

        if consider_entry_points:
            loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
            if loaded:
                return

        try:
            __import__(importspec)
        except ImportError as e:
            new_exc_message = 'Error importing plugin "%s": %s' % (
                modname,
                safe_str(e.args[0]),
            )
            new_exc = ImportError(new_exc_message)
            tb = sys.exc_info()[2]

            six.reraise(ImportError, new_exc, tb)

        except Skipped as e:
            from _pytest.warnings import _issue_warning_captured

            _issue_warning_captured(
                PytestWarning("skipped plugin %r: %s" % (modname, e.msg)),
                self.hook,
                stacklevel=1,
            )
        else:
            mod = sys.modules[importspec]
            self.register(mod, modname)
Пример #18
0
def catch_warnings_for_item(item):
    """
    catches the warnings generated during setup/call/teardown execution
    of the given item and after it is done posts them as warnings to this
    item.
    """
    args = item.config.getoption('pythonwarnings') or []
    inifilters = item.config.getini("filterwarnings")
    with warnings.catch_warnings(record=True) as log:
        for arg in args:
            warnings._setoption(arg)

        for arg in inifilters:
            _setoption(warnings, arg)

        mark = item.get_marker('filterwarnings')
        if mark:
            for arg in mark.args:
                warnings._setoption(arg)

        yield

        for warning in log:
            warn_msg = warning.message
            unicode_warning = False

            if compat._PY2 and any(
                    isinstance(m, compat.UNICODE_TYPES)
                    for m in warn_msg.args):
                new_args = [compat.safe_str(m) for m in warn_msg.args]
                unicode_warning = warn_msg.args != new_args
                warn_msg.args = new_args

            msg = warnings.formatwarning(warn_msg, warning.category,
                                         warning.filename, warning.lineno,
                                         warning.line)
            item.warn("unused", msg)

            if unicode_warning:
                warnings.warn(
                    "Warning is using unicode non convertible to ascii, "
                    "converting to a safe representation:\n  %s" % msg,
                    UnicodeWarning)
Пример #19
0
def catch_warnings_for_item(item):
    """
    catches the warnings generated during setup/call/teardown execution
    of the given item and after it is done posts them as warnings to this
    item.
    """
    args = item.config.getoption('pythonwarnings') or []
    inifilters = item.config.getini("filterwarnings")
    with warnings.catch_warnings(record=True) as log:
        for arg in args:
            warnings._setoption(arg)

        for arg in inifilters:
            _setoption(warnings, arg)

        mark = item.get_marker('filterwarnings')
        if mark:
            for arg in mark.args:
                warnings._setoption(arg)

        yield

        for warning in log:
            warn_msg = warning.message
            unicode_warning = False

            if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args):
                new_args = [compat.safe_str(m) for m in warn_msg.args]
                unicode_warning = warn_msg.args != new_args
                warn_msg.args = new_args

            msg = warnings.formatwarning(
                warn_msg, warning.category,
                warning.filename, warning.lineno, warning.line)
            item.warn("unused", msg)

            if unicode_warning:
                warnings.warn(
                    "Warning is using unicode non convertible to ascii, "
                    "converting to a safe representation:\n  %s" % msg,
                    UnicodeWarning)
Пример #20
0
def main(args=None, plugins=None):
    """ return exit code, after performing an in-process test run.

    :arg args: list of command line arguments.

    :arg plugins: list of plugin objects to be auto-registered during
                  initialization.
    """
    from _pytest.main import EXIT_USAGEERROR

    try:
        try:
            config = _prepareconfig(args, plugins)
        except ConftestImportFailure as e:
            exc_info = ExceptionInfo(e.excinfo)
            tw = py.io.TerminalWriter(sys.stderr)
            tw.line(
                "ImportError while loading conftest '{e.path}'.".format(e=e), red=True
            )
            exc_info.traceback = exc_info.traceback.filter(filter_traceback)
            exc_repr = (
                exc_info.getrepr(style="short", chain=False)
                if exc_info.traceback
                else exc_info.exconly()
            )
            formatted_tb = safe_str(exc_repr)
            for line in formatted_tb.splitlines():
                tw.line(line.rstrip(), red=True)
            return 4
        else:
            try:
                return config.hook.pytest_cmdline_main(config=config)
            finally:
                config._ensure_unconfigure()
    except UsageError as e:
        tw = py.io.TerminalWriter(sys.stderr)
        for msg in e.args:
            tw.line("ERROR: {}\n".format(msg), red=True)
        return EXIT_USAGEERROR
Пример #21
0
def main(args=None, plugins=None):
    """ return exit code, after performing an in-process test run.

    :arg args: list of command line arguments.

    :arg plugins: list of plugin objects to be auto-registered during
                  initialization.
    """
    from _pytest.main import EXIT_USAGEERROR

    try:
        try:
            config = _prepareconfig(args, plugins)
        except ConftestImportFailure as e:
            exc_info = ExceptionInfo(e.excinfo)
            tw = py.io.TerminalWriter(sys.stderr)
            tw.line(
                "ImportError while loading conftest '{e.path}'.".format(e=e), red=True
            )
            exc_info.traceback = exc_info.traceback.filter(filter_traceback)
            exc_repr = (
                exc_info.getrepr(style="short", chain=False)
                if exc_info.traceback
                else exc_info.exconly()
            )
            formatted_tb = safe_str(exc_repr)
            for line in formatted_tb.splitlines():
                tw.line(line.rstrip(), red=True)
            return 4
        else:
            try:
                return config.hook.pytest_cmdline_main(config=config)
            finally:
                config._ensure_unconfigure()
    except UsageError as e:
        tw = py.io.TerminalWriter(sys.stderr)
        for msg in e.args:
            tw.line("ERROR: {}\n".format(msg), red=True)
        return EXIT_USAGEERROR
Пример #22
0
def catch_warnings_for_item(item):
    """
    catches the warnings generated during setup/call/teardown execution
    of the given item and after it is done posts them as warnings to this
    item.
    """
    args = item.config.getoption('pythonwarnings') or []
    inifilters = item.config.getini("filterwarnings")
    with warnings.catch_warnings(record=True) as log:
        for arg in args:
            warnings._setoption(arg)

        for arg in inifilters:
            _setoption(warnings, arg)

        yield

        for warning in log:
            warn_msg = warning.message
            unicode_warning = False

            if compat._PY2 and any(
                    isinstance(m, compat.UNICODE_TYPES)
                    for m in warn_msg.args):
                warn_msg.args = [compat.safe_str(m) for m in warn_msg.args]
                unicode_warning = True

            msg = warnings.formatwarning(warn_msg, warning.category,
                                         warning.filename, warning.lineno,
                                         warning.line)
            item.warn("unused", msg)

            if unicode_warning:
                warnings.warn(
                    "This warning %s is broken as it's message is not a str instance"
                    "(after all this is a stdlib problem workaround)" % msg,
                    UnicodeWarning)