From 495a55725b5f85ca6935ff2d67a2fd62f915e924 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 14:02:01 -0300 Subject: [PATCH 1/8] Separate deprecations and removals in the CHANGELOG --- changelog/README.rst | 3 ++- pyproject.toml | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/changelog/README.rst b/changelog/README.rst index 47e21fb33..e471409b0 100644 --- a/changelog/README.rst +++ b/changelog/README.rst @@ -14,7 +14,8 @@ Each file should be named like ``..rst``, where * ``feature``: new user facing features, like new command-line options and new behavior. * ``bugfix``: fixes a reported bug. * ``doc``: documentation improvement, like rewording an entire session or adding missing docs. -* ``removal``: feature deprecation or removal. +* ``deprecation``: feature deprecation. +* ``removal``: feature removal. * ``vendor``: changes in packages vendored in pytest. * ``trivial``: fixing a small typo or internal change that might be noteworthy. diff --git a/pyproject.toml b/pyproject.toml index b1e85601e..e82f051e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,12 @@ template = "changelog/_template.rst" [[tool.towncrier.type]] directory = "removal" - name = "Deprecations and Removals" + name = "Removals" + showcontent = true + + [[tool.towncrier.type]] + directory = "deprecation" + name = "Deprecations" showcontent = true [[tool.towncrier.type]] From bf074b37a3192a454f8c156e116eebd0b4588d9e Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 14:04:29 -0300 Subject: [PATCH 2/8] Show deprecation warnings for compat properties Fix #3616 --- changelog/3616.deprecation.rst | 8 ++++++++ doc/en/historical-notes.rst | 10 ++++++++++ src/_pytest/nodes.py | 13 ++++++++----- src/_pytest/python.py | 2 +- testing/deprecated_test.py | 17 +++++++++++++++++ 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 changelog/3616.deprecation.rst diff --git a/changelog/3616.deprecation.rst b/changelog/3616.deprecation.rst new file mode 100644 index 000000000..e02e83c20 --- /dev/null +++ b/changelog/3616.deprecation.rst @@ -0,0 +1,8 @@ +The following accesses have been documented as deprecated for years, but are now actually emitting deprecation warnings. + +* Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances. Now + users will this warning:: + + usage of Function.Module is deprecated, please use pytest.Module instead + + Users should just ``import pytest`` and access those objects using the ``pytest`` module. diff --git a/doc/en/historical-notes.rst b/doc/en/historical-notes.rst index 028ceff9b..9462d700f 100644 --- a/doc/en/historical-notes.rst +++ b/doc/en/historical-notes.rst @@ -175,3 +175,13 @@ Previous to version 2.4 to set a break point in code one needed to use ``pytest. This is no longer needed and one can use the native ``import pdb;pdb.set_trace()`` call directly. For more details see :ref:`breakpoints`. + +"compat" properties +------------------- + +.. deprecated:: 3.9 + +Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances have long +been documented as deprecated, but started to emit warnings from pytest ``3.9`` and onward. + +Users should just ``import pytest`` and access those objects using the ``pytest`` module. diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 29d1f0a87..222059d8c 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -11,6 +11,7 @@ import _pytest._code from _pytest.compat import getfslineno from _pytest.mark.structures import NodeKeywords, MarkInfo +from _pytest.warning_types import RemovedInPytest4Warning SEP = "/" @@ -61,11 +62,13 @@ class _CompatProperty(object): if obj is None: return self - # TODO: reenable in the features branch - # warnings.warn( - # "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format( - # name=self.name, owner=type(owner).__name__), - # PendingDeprecationWarning, stacklevel=2) + warnings.warn( + "usage of {owner}.{name} is deprecated, please use pytest.{name} instead".format( + name=self.name, owner=owner.__name__ + ), + RemovedInPytest4Warning, + stacklevel=2, + ) return getattr(__import__("pytest"), self.name) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 051650272..dff7a6950 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -800,7 +800,7 @@ class Generator(FunctionMixin, PyCollector): "%r generated tests with non-unique name %r" % (self, name) ) seen[name] = True - values.append(self.Function(name, self, args=args, callobj=call)) + values.append(Function(name, self, args=args, callobj=call)) self.warn(deprecated.YIELD_TESTS) return values diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index fbaca4e30..d53f86e15 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -30,6 +30,23 @@ def test_yield_tests_deprecation(testdir): assert result.stdout.str().count("yield tests are deprecated") == 2 +def test_compat_properties_deprecation(testdir): + testdir.makepyfile( + """ + def test_foo(request): + print(request.node.Module) + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + [ + "*test_compat_properties_deprecation.py:2:*usage of Function.Module is deprecated, " + "please use pytest.Module instead*", + "*1 passed, 1 warnings in*", + ] + ) + + @pytest.mark.filterwarnings("default") def test_funcarg_prefix_deprecation(testdir): testdir.makepyfile( From 482bd5efd2a88a025a21979a6d7e7923a0605209 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 14:25:46 -0300 Subject: [PATCH 3/8] Show deprecation warning for cached_setup --- changelog/3616.deprecation.rst | 3 +++ src/_pytest/fixtures.py | 5 +++++ testing/deprecated_test.py | 21 +++++++++++++++++++++ testing/python/fixture.py | 2 ++ 4 files changed, 31 insertions(+) diff --git a/changelog/3616.deprecation.rst b/changelog/3616.deprecation.rst index e02e83c20..e91d1ad07 100644 --- a/changelog/3616.deprecation.rst +++ b/changelog/3616.deprecation.rst @@ -6,3 +6,6 @@ The following accesses have been documented as deprecated for years, but are now usage of Function.Module is deprecated, please use pytest.Module instead Users should just ``import pytest`` and access those objects using the ``pytest`` module. + +* ``request.cached_setup``, this was the precursor of the setup/teardown mechanism available to fixtures. You can + consult `funcarg comparision section in the docs `_. diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 068e6814c..f2c8085ed 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -479,6 +479,11 @@ class FixtureRequest(FuncargnamesCompatAttr): or ``session`` indicating the caching lifecycle of the resource. :arg extrakey: added to internal caching key of (funcargname, scope). """ + msg = ( + "cached_setup is deprecated and will be removed in a future release. " + "Use standard fixture functions instead." + ) + warnings.warn(RemovedInPytest4Warning(msg), stacklevel=2) if not hasattr(self.config, "_setupcache"): self.config._setupcache = {} # XXX weakref? cachekey = (self.fixturename, self._getscopeitem(scope), extrakey) diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index d53f86e15..7ca8e6bae 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -47,6 +47,27 @@ def test_compat_properties_deprecation(testdir): ) +def test_cached_setup_deprecation(testdir): + testdir.makepyfile( + """ + import pytest + @pytest.fixture + def fix(request): + return request.cached_setup(lambda: 1) + + def test_foo(fix): + assert fix == 1 + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + [ + "*test_cached_setup_deprecation.py:4:*cached_setup is deprecated*", + "*1 passed, 1 warnings in*", + ] + ) + + @pytest.mark.filterwarnings("default") def test_funcarg_prefix_deprecation(testdir): testdir.makepyfile( diff --git a/testing/python/fixture.py b/testing/python/fixture.py index fc3eee42b..4e44bf961 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -977,6 +977,7 @@ class TestRequestCachedSetup(object): ) reprec.assertoutcome(passed=4) + @pytest.mark.filterwarnings("ignore:cached_setup is deprecated") def test_request_cachedsetup_extrakey(self, testdir): item1 = testdir.getitem("def test_func(): pass") req1 = fixtures.FixtureRequest(item1) @@ -994,6 +995,7 @@ class TestRequestCachedSetup(object): assert ret1 == ret1b assert ret2 == ret2b + @pytest.mark.filterwarnings("ignore:cached_setup is deprecated") def test_request_cachedsetup_cache_deletion(self, testdir): item1 = testdir.getitem("def test_func(): pass") req1 = fixtures.FixtureRequest(item1) From b7dd9154c370b5d22ca921cdac4962ca3ca8aacd Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 14:55:28 -0300 Subject: [PATCH 4/8] Deprecate custom node types during collection by using special names --- changelog/3616.deprecation.rst | 7 +++++++ src/_pytest/nodes.py | 11 +++++++---- testing/deprecated_test.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/changelog/3616.deprecation.rst b/changelog/3616.deprecation.rst index e91d1ad07..04d4bb509 100644 --- a/changelog/3616.deprecation.rst +++ b/changelog/3616.deprecation.rst @@ -9,3 +9,10 @@ The following accesses have been documented as deprecated for years, but are now * ``request.cached_setup``, this was the precursor of the setup/teardown mechanism available to fixtures. You can consult `funcarg comparision section in the docs `_. + +* Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector`` + subclasses has been deprecated. Users instead should use ``pytest_collect_make_item`` to customize node types during + collection. + + 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. diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 222059d8c..8fc11eb4c 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -130,10 +130,13 @@ class Node(object): return getattr(__import__("pytest"), name) else: cls = getattr(self, name) - # TODO: reenable in the features branch - # warnings.warn("use of node.%s is deprecated, " - # "use pytest_pycollect_makeitem(...) to create custom " - # "collection nodes" % name, category=DeprecationWarning) + msg = ( + 'use of special named "%s" objects in collectors of type "%s" to ' + "customize the created nodes is deprecated. " + "Use pytest_pycollect_makeitem(...) to create custom " + "collection nodes instead." % (name, type(self).__name__) + ) + self.warn(RemovedInPytest4Warning(msg)) return cls def __repr__(self): diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 7ca8e6bae..49b21ccb1 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -68,6 +68,36 @@ def test_cached_setup_deprecation(testdir): ) +def test_custom_class_deprecation(testdir): + testdir.makeconftest( + """ + import pytest + + class MyModule(pytest.Module): + + class Class(pytest.Class): + pass + + def pytest_pycollect_makemodule(path, parent): + return MyModule(path, parent) + """ + ) + testdir.makepyfile( + """ + class Test: + def test_foo(self): + pass + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + [ + '*test_custom_class_deprecation.py:1:*"Class" objects in collectors of type "MyModule*', + "*1 passed, 1 warnings in*", + ] + ) + + @pytest.mark.filterwarnings("default") def test_funcarg_prefix_deprecation(testdir): testdir.makepyfile( From feb8240410194c050c881678c97c0d7246ec1ccb Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 15:44:02 -0300 Subject: [PATCH 5/8] Use self.Function again during collection --- src/_pytest/python.py | 5 ++++- testing/python/collect.py | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index dff7a6950..a0a0655fd 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -800,7 +800,10 @@ class Generator(FunctionMixin, PyCollector): "%r generated tests with non-unique name %r" % (self, name) ) seen[name] = True - values.append(Function(name, self, args=args, callobj=call)) + with warnings.catch_warnings(): + # ignore our own deprecation warning + function_class = self.Function + values.append(function_class(name, self, args=args, callobj=call)) self.warn(deprecated.YIELD_TESTS) return values diff --git a/testing/python/collect.py b/testing/python/collect.py index c92de12a0..25d8a8e77 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -240,6 +240,9 @@ class TestClass(object): assert result.ret == EXIT_NOTESTSCOLLECTED +@pytest.mark.filterwarnings( + "ignore:usage of Generator.Function is deprecated, please use pytest.Function instead" +) class TestGenerator(object): def test_generative_functions(self, testdir): modcol = testdir.getmodulecol( @@ -1255,6 +1258,9 @@ class TestReportInfo(object): assert lineno == 1 assert msg == "TestClass" + @pytest.mark.filterwarnings( + "ignore:usage of Generator.Function is deprecated, please use pytest.Function instead" + ) def test_generator_reportinfo(self, testdir): modcol = testdir.getmodulecol( """ From 32ee0b9c885d8bdda9edeabd86277ba1cb31dce4 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 13 Sep 2018 15:56:50 -0300 Subject: [PATCH 6/8] Move warning messages to _pytest.deprecated --- src/_pytest/deprecated.py | 16 ++++++++++++++++ src/_pytest/fixtures.py | 8 +++----- src/_pytest/nodes.py | 19 ++++++++++--------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index dea8bbde8..5c98fd43c 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -18,6 +18,22 @@ YIELD_TESTS = RemovedInPytest4Warning( "yield tests are deprecated, and scheduled to be removed in pytest 4.0" ) +CACHED_SETUP = RemovedInPytest4Warning( + "cached_setup is deprecated and will be removed in a future release. " + "Use standard fixture functions instead." +) + +COMPAT_PROPERTY = ( + "usage of {owner}.{name} is deprecated, please use pytest.{name} instead" +) + +CUSTOM_CLASS = ( + '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." +) + FUNCARG_PREFIX = ( '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' "and scheduled to be removed in pytest 4.0. " diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index f2c8085ed..610907342 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -479,11 +479,9 @@ class FixtureRequest(FuncargnamesCompatAttr): or ``session`` indicating the caching lifecycle of the resource. :arg extrakey: added to internal caching key of (funcargname, scope). """ - msg = ( - "cached_setup is deprecated and will be removed in a future release. " - "Use standard fixture functions instead." - ) - warnings.warn(RemovedInPytest4Warning(msg), stacklevel=2) + from _pytest.deprecated import CACHED_SETUP + + warnings.warn(CACHED_SETUP, stacklevel=2) if not hasattr(self.config, "_setupcache"): self.config._setupcache = {} # XXX weakref? cachekey = (self.fixturename, self._getscopeitem(scope), extrakey) diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 8fc11eb4c..287bd4181 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -62,11 +62,12 @@ class _CompatProperty(object): if obj is None: return self + from _pytest.deprecated import COMPAT_PROPERTY + warnings.warn( - "usage of {owner}.{name} is deprecated, please use pytest.{name} instead".format( - name=self.name, owner=owner.__name__ + RemovedInPytest4Warning( + COMPAT_PROPERTY.format(name=self.name, owner=owner.__name__) ), - RemovedInPytest4Warning, stacklevel=2, ) return getattr(__import__("pytest"), self.name) @@ -129,14 +130,14 @@ class Node(object): if isinstance(maybe_compatprop, _CompatProperty): return getattr(__import__("pytest"), name) else: + from _pytest.deprecated import CUSTOM_CLASS + cls = getattr(self, name) - msg = ( - 'use of special named "%s" objects in collectors of type "%s" to ' - "customize the created nodes is deprecated. " - "Use pytest_pycollect_makeitem(...) to create custom " - "collection nodes instead." % (name, type(self).__name__) + self.warn( + RemovedInPytest4Warning( + CUSTOM_CLASS.format(name=name, type_name=type(self).__name__) + ) ) - self.warn(RemovedInPytest4Warning(msg)) return cls def __repr__(self): From da6830f19b13dba32956f27d0493c26e0ab29322 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 14 Sep 2018 14:49:05 -0300 Subject: [PATCH 7/8] 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): From ae8f3695b52c69df9eb7911e209c82617f816a8f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 14 Sep 2018 15:31:20 -0300 Subject: [PATCH 8/8] Move UnformattedWarning to _pytest.warning_types --- src/_pytest/deprecated.py | 18 +----------------- src/_pytest/warning_types.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index d5ec5dbbf..69beeab5f 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -10,24 +10,8 @@ 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)) +from _pytest.warning_types import UnformattedWarning, RemovedInPytest4Warning MAIN_STR_ARGS = RemovedInPytest4Warning( diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py index 8861f6f2b..55e1f037a 100644 --- a/src/_pytest/warning_types.py +++ b/src/_pytest/warning_types.py @@ -1,3 +1,6 @@ +import attr + + class PytestWarning(UserWarning): """ Bases: :class:`UserWarning`. @@ -39,4 +42,19 @@ class PytestExperimentalApiWarning(PytestWarning, FutureWarning): ) +@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)) + + PYTESTER_COPY_EXAMPLE = PytestExperimentalApiWarning.simple("testdir.copy_example")