Start the laywork to capture standard warnings

This commit is contained in:
Bruno Oliveira 2018-08-29 17:53:51 -03:00
parent 1a9d913ee1
commit 0100f61b62
6 changed files with 45 additions and 20 deletions

View File

@ -7,10 +7,7 @@ be removed when the time comes.
""" """
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
from _pytest.warning_types import RemovedInPytest4Warning
class RemovedInPytest4Warning(DeprecationWarning):
"""warning class for features removed in pytest 4.0"""
MAIN_STR_ARGS = "passing a string to pytest.main() is deprecated, " "pass a list of arguments instead." MAIN_STR_ARGS = "passing a string to pytest.main() is deprecated, " "pass a list of arguments instead."

View File

@ -1,5 +1,6 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import os import os
import warnings
import six import six
import py import py
@ -7,6 +8,7 @@ import attr
import _pytest import _pytest
import _pytest._code import _pytest._code
from _pytest.compat import getfslineno
from _pytest.mark.structures import NodeKeywords, MarkInfo from _pytest.mark.structures import NodeKeywords, MarkInfo
@ -145,6 +147,14 @@ class Node(object):
) )
) )
def std_warn(self, message, category=None):
from _pytest.warning_types import PytestWarning
if category is None:
assert isinstance(message, PytestWarning)
path, lineno = get_fslocation_from_item(self)
warnings.warn_explicit(message, category, filename=str(path), lineno=lineno)
# methods for ordering nodes # methods for ordering nodes
@property @property
def nodeid(self): def nodeid(self):
@ -314,10 +324,13 @@ def get_fslocation_from_item(item):
* "fslocation": a pair (path, lineno) * "fslocation": a pair (path, lineno)
* "fspath": just a path * "fspath": just a path
""" """
fslocation = getattr(item, "location", None) result = getattr(item, "location", None)
if fslocation is None: if result is not None:
fslocation = getattr(item, "fspath", None) return result
return fslocation obj = getattr(item, "obj", None)
if obj is not None:
return getfslineno(obj)
return getattr(item, "fspath", None), None
class Collector(Node): class Collector(Node):

View File

@ -44,7 +44,7 @@ from _pytest.mark.structures import (
get_unpacked_marks, get_unpacked_marks,
normalize_mark_list, normalize_mark_list,
) )
from _pytest.warning_types import PytestUsageWarning
# relative paths that we use to filter traceback entries from appearing to the user; # relative paths that we use to filter traceback entries from appearing to the user;
# see filter_traceback # see filter_traceback
@ -656,17 +656,23 @@ class Class(PyCollector):
if not safe_getattr(self.obj, "__test__", True): if not safe_getattr(self.obj, "__test__", True):
return [] return []
if hasinit(self.obj): if hasinit(self.obj):
self.warn( # self.warn(
"C1", # "C1",
# "cannot collect test class %r because it has a "
# "__init__ constructor" % self.obj.__name__,
# )
self.std_warn(
"cannot collect test class %r because it has a " "cannot collect test class %r because it has a "
"__init__ constructor" % self.obj.__name__, "__init__ constructor" % self.obj.__name__,
PytestUsageWarning,
) )
return [] return []
elif hasnew(self.obj): elif hasnew(self.obj):
self.warn( self.std_warn(
"C1", PytestUsageWarning(
"cannot collect test class %r because it has a " "cannot collect test class %r because it has a "
"__new__ constructor" % self.obj.__name__, "__new__ constructor" % self.obj.__name__
)
) )
return [] return []
return [self._getcustomclass("Instance")(name="()", parent=self)] return [self._getcustomclass("Instance")(name="()", parent=self)]

View File

@ -331,12 +331,11 @@ class TerminalReporter(object):
warnings.append(warning) warnings.append(warning)
def pytest_warning_captured(self, warning_message, item): def pytest_warning_captured(self, warning_message, item):
from _pytest.nodes import get_fslocation_from_item # from _pytest.nodes import get_fslocation_from_item
from _pytest.warnings import warning_record_to_str from _pytest.warnings import warning_record_to_str
warnings = self.stats.setdefault("warnings", []) warnings = self.stats.setdefault("warnings", [])
fslocation = warning_message.filename, warning_message.lineno
fslocation = get_fslocation_from_item(item)
message = warning_record_to_str(warning_message) message = warning_record_to_str(warning_message)
nodeid = item.nodeid if item is not None else "" nodeid = item.nodeid if item is not None else ""
@ -713,7 +712,7 @@ class TerminalReporter(object):
for w in warning_records: for w in warning_records:
lines = w.message.splitlines() lines = w.message.splitlines()
indented = "\n".join(" " + x for x in lines) indented = "\n".join(" " + x for x in lines)
self._tw.line(indented) self._tw.line(indented.rstrip())
self._tw.line() self._tw.line()
self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html") self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html")

View File

@ -0,0 +1,10 @@
class PytestWarning(UserWarning):
"""Base class for all warnings emitted by pytest"""
class PytestUsageWarning(PytestWarning):
"""Warnings related to pytest usage: either command line or testing code."""
class RemovedInPytest4Warning(PytestWarning):
"""warning class for features that will be removed in pytest 4.0"""

View File

@ -16,7 +16,7 @@ from _pytest.mark import (
from _pytest.nodes import Node from _pytest.nodes import Node
ignore_markinfo = pytest.mark.filterwarnings( ignore_markinfo = pytest.mark.filterwarnings(
"ignore:MarkInfo objects:_pytest.deprecated.RemovedInPytest4Warning" "ignore:MarkInfo objects:_pytest.warning_types.RemovedInPytest4Warning"
) )