From da6830f19b13dba32956f27d0493c26e0ab29322 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 14 Sep 2018 14:49:05 -0300 Subject: [PATCH] Introduce UnformattedWarning to keep warning types and messages in _pytest.deprecated --- changelog/3616.deprecation.rst | 4 +++ src/_pytest/config/findpaths.py | 9 ++---- src/_pytest/deprecated.py | 52 +++++++++++++++++++++++++-------- src/_pytest/fixtures.py | 13 ++++----- src/_pytest/nodes.py | 12 ++------ src/_pytest/resultlog.py | 3 +- 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/changelog/3616.deprecation.rst b/changelog/3616.deprecation.rst index 04d4bb509..8ea1b4d3d 100644 --- a/changelog/3616.deprecation.rst +++ b/changelog/3616.deprecation.rst @@ -16,3 +16,7 @@ The following accesses have been documented as deprecated for years, but are now This issue should affect only advanced plugins who create new collection types, so if you see this warning message please contact the authors so they can change the code. + +* The warning that produces the message below has changed to ``RemovedInPytest4Warning``:: + + getfuncargvalue is deprecated, use getfixturevalue diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 7480603be..f99430198 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -103,21 +103,18 @@ def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None): if inifile: iniconfig = py.iniconfig.IniConfig(inifile) is_cfg_file = str(inifile).endswith(".cfg") - # TODO: [pytest] section in *.cfg files is depricated. Need refactoring. sections = ["tool:pytest", "pytest"] if is_cfg_file else ["pytest"] for section in sections: try: inicfg = iniconfig[section] if is_cfg_file and section == "pytest" and config is not None: from _pytest.deprecated import CFG_PYTEST_SECTION - from _pytest.warning_types import RemovedInPytest4Warning from _pytest.warnings import _issue_config_warning + # TODO: [pytest] section in *.cfg files is deprecated. Need refactoring once + # the deprecation expires. _issue_config_warning( - RemovedInPytest4Warning( - CFG_PYTEST_SECTION.format(filename=str(inifile)) - ), - config, + CFG_PYTEST_SECTION.format(filename=str(inifile)), config ) break except KeyError: diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 5c98fd43c..d5ec5dbbf 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -4,11 +4,32 @@ that is planned to be removed in the next pytest release. Keeping it in a central location makes it easy to track what is deprecated and should be removed when the time comes. + +All constants defined in this module should be either PytestWarning instances or UnformattedWarning +in case of warnings which need to format their messages. """ from __future__ import absolute_import, division, print_function +import attr + from _pytest.warning_types import RemovedInPytest4Warning + +@attr.s +class UnformattedWarning(object): + """Used to hold warnings that need to format their message at runtime, as opposed to a direct message. + + Using this class avoids to keep all the warning types and messages in this module, avoiding misuse. + """ + + category = attr.ib() + template = attr.ib() + + def format(self, **kwargs): + """Returns an instance of the warning category, formatted with given kwargs""" + return self.category(self.template.format(**kwargs)) + + MAIN_STR_ARGS = RemovedInPytest4Warning( "passing a string to pytest.main() is deprecated, " "pass a list of arguments instead." @@ -23,36 +44,43 @@ CACHED_SETUP = RemovedInPytest4Warning( "Use standard fixture functions instead." ) -COMPAT_PROPERTY = ( - "usage of {owner}.{name} is deprecated, please use pytest.{name} instead" +COMPAT_PROPERTY = UnformattedWarning( + RemovedInPytest4Warning, + "usage of {owner}.{name} is deprecated, please use pytest.{name} instead", ) -CUSTOM_CLASS = ( +CUSTOM_CLASS = UnformattedWarning( + RemovedInPytest4Warning, 'use of special named "{name}" objects in collectors of type "{type_name}" to ' "customize the created nodes is deprecated. " "Use pytest_pycollect_makeitem(...) to create custom " - "collection nodes instead." + "collection nodes instead.", ) -FUNCARG_PREFIX = ( +FUNCARG_PREFIX = UnformattedWarning( + RemovedInPytest4Warning, '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' "and scheduled to be removed in pytest 4.0. " - "Please remove the prefix and use the @pytest.fixture decorator instead." + "Please remove the prefix and use the @pytest.fixture decorator instead.", ) -FIXTURE_FUNCTION_CALL = ( +FIXTURE_FUNCTION_CALL = UnformattedWarning( + RemovedInPytest4Warning, 'Fixture "{name}" called directly. Fixtures are not meant to be called directly, ' "are created automatically when test functions request them as parameters. " - "See https://docs.pytest.org/en/latest/fixture.html for more information." + "See https://docs.pytest.org/en/latest/fixture.html for more information.", ) -CFG_PYTEST_SECTION = ( - "[pytest] section in {filename} files is deprecated, use [tool:pytest] instead." +CFG_PYTEST_SECTION = UnformattedWarning( + RemovedInPytest4Warning, + "[pytest] section in {filename} files is deprecated, use [tool:pytest] instead.", ) -GETFUNCARGVALUE = "getfuncargvalue is deprecated, use getfixturevalue" +GETFUNCARGVALUE = RemovedInPytest4Warning( + "getfuncargvalue is deprecated, use getfixturevalue" +) -RESULT_LOG = ( +RESULT_LOG = RemovedInPytest4Warning( "--result-log is deprecated and scheduled for removal in pytest 4.0.\n" "See https://docs.pytest.org/en/latest/usage.html#creating-resultlog-format-files for more information." ) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 610907342..964b16e29 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -32,7 +32,7 @@ from _pytest.compat import ( get_real_method, _PytestWrapper, ) -from _pytest.deprecated import FIXTURE_FUNCTION_CALL, RemovedInPytest4Warning +from _pytest.deprecated import FIXTURE_FUNCTION_CALL from _pytest.outcomes import fail, TEST_OUTCOME FIXTURE_MSG = 'fixtures cannot have "pytest_funcarg__" prefix and be decorated with @pytest.fixture:\n{}' @@ -515,7 +515,7 @@ class FixtureRequest(FuncargnamesCompatAttr): """ Deprecated, use getfixturevalue. """ from _pytest import deprecated - warnings.warn(deprecated.GETFUNCARGVALUE, DeprecationWarning, stacklevel=2) + warnings.warn(deprecated.GETFUNCARGVALUE, stacklevel=2) return self.getfixturevalue(argname) def _get_active_fixturedef(self, argname): @@ -959,8 +959,9 @@ def wrap_function_to_warning_if_called_directly(function, fixture_marker): used as an argument in a test function. """ is_yield_function = is_generator(function) - msg = FIXTURE_FUNCTION_CALL.format(name=fixture_marker.name or function.__name__) - warning = RemovedInPytest4Warning(msg) + warning = FIXTURE_FUNCTION_CALL.format( + name=fixture_marker.name or function.__name__ + ) if is_yield_function: @@ -1287,9 +1288,7 @@ class FixtureManager(object): filename, lineno = getfslineno(obj) warnings.warn_explicit( - RemovedInPytest4Warning( - deprecated.FUNCARG_PREFIX.format(name=name) - ), + deprecated.FUNCARG_PREFIX.format(name=name), category=None, filename=str(filename), lineno=lineno + 1, diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 287bd4181..9cd758941 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -11,7 +11,6 @@ import _pytest._code from _pytest.compat import getfslineno from _pytest.mark.structures import NodeKeywords, MarkInfo -from _pytest.warning_types import RemovedInPytest4Warning SEP = "/" @@ -65,10 +64,7 @@ class _CompatProperty(object): from _pytest.deprecated import COMPAT_PROPERTY warnings.warn( - RemovedInPytest4Warning( - COMPAT_PROPERTY.format(name=self.name, owner=owner.__name__) - ), - stacklevel=2, + COMPAT_PROPERTY.format(name=self.name, owner=owner.__name__), stacklevel=2 ) return getattr(__import__("pytest"), self.name) @@ -133,11 +129,7 @@ class Node(object): from _pytest.deprecated import CUSTOM_CLASS cls = getattr(self, name) - self.warn( - RemovedInPytest4Warning( - CUSTOM_CLASS.format(name=name, type_name=type(self).__name__) - ) - ) + self.warn(CUSTOM_CLASS.format(name=name, type_name=type(self).__name__)) return cls def __repr__(self): diff --git a/src/_pytest/resultlog.py b/src/_pytest/resultlog.py index 8a972eed7..9ae90e770 100644 --- a/src/_pytest/resultlog.py +++ b/src/_pytest/resultlog.py @@ -31,10 +31,9 @@ def pytest_configure(config): config.pluginmanager.register(config._resultlog) from _pytest.deprecated import RESULT_LOG - from _pytest.warning_types import RemovedInPytest4Warning from _pytest.warnings import _issue_config_warning - _issue_config_warning(RemovedInPytest4Warning(RESULT_LOG), config) + _issue_config_warning(RESULT_LOG, config) def pytest_unconfigure(config):