From c378a3d1761f302085c8d803b9b28f06eb5dc7cf Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Tue, 8 Dec 2015 16:38:07 -0600 Subject: [PATCH 01/10] Deprecations fixture A new Deprecations fixture is added which when active causes calls to deprecated function to raise. --- .gitignore | 1 + README | 12 ++- fixtures/__init__.py | 2 + fixtures/_fixtures/__init__.py | 4 + fixtures/_fixtures/deprecations.py | 84 +++++++++++++++++++ fixtures/tests/_fixtures/__init__.py | 1 + fixtures/tests/_fixtures/test_deprecations.py | 59 +++++++++++++ 7 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 fixtures/_fixtures/deprecations.py create mode 100644 fixtures/tests/_fixtures/test_deprecations.py diff --git a/.gitignore b/.gitignore index 213e3c2..03ae26e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ AUTHORS ChangeLog .eggs build +.tox diff --git a/README b/README index e7db1af..1d36e3b 100644 --- a/README +++ b/README @@ -334,6 +334,16 @@ in test failure descriptions. Very useful in combination with MonkeyPatch. ... pass >>> fixture.cleanUp() +Deprecations +++++++++++++ + +Prevent code under test from calling deprecated functions. + + >>> fixture = fixtures.Deprecations('my_module') + >>> fixture.setUp() + >>> warnings.warn('stop using me', DeprecationWarning) # will raise + >>> fixture.cleanUp() + EnvironmentVariable +++++++++++++++++++ @@ -385,7 +395,7 @@ MockPatchMultiple Adapts ``mock.patch.multiple`` to be used as a Fixture. - >>> fixture = fixtures.MockPatch('subprocess.Popen', returncode=3) + >>> fixture = fixtures.MockPatchMultiple('subprocess.Popen', returncode=3) MonkeyPatch +++++++++++ diff --git a/fixtures/__init__.py b/fixtures/__init__.py index 0d15408..03b7dd5 100644 --- a/fixtures/__init__.py +++ b/fixtures/__init__.py @@ -44,6 +44,7 @@ __all__ = [ 'ByteStream', + 'Deprecations', 'DetailStream', 'EnvironmentVariable', 'EnvironmentVariableFixture', @@ -86,6 +87,7 @@ ) from fixtures._fixtures import ( ByteStream, + Deprecations, DetailStream, EnvironmentVariable, EnvironmentVariableFixture, diff --git a/fixtures/_fixtures/__init__.py b/fixtures/_fixtures/__init__.py index b60a6fb..d30c566 100644 --- a/fixtures/_fixtures/__init__.py +++ b/fixtures/_fixtures/__init__.py @@ -18,6 +18,7 @@ __all__ = [ 'ByteStream', + 'Deprecations', 'DetailStream', 'EnvironmentVariable', 'EnvironmentVariableFixture', @@ -43,6 +44,9 @@ ] +from fixtures._fixtures.deprecations import ( + Deprecations, + ) from fixtures._fixtures.environ import ( EnvironmentVariable, EnvironmentVariableFixture, diff --git a/fixtures/_fixtures/deprecations.py b/fixtures/_fixtures/deprecations.py new file mode 100644 index 0000000..1489aa1 --- /dev/null +++ b/fixtures/_fixtures/deprecations.py @@ -0,0 +1,84 @@ +# Copyright 2015 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from __future__ import absolute_import + +import contextlib +import re +import warnings # conflicts with the local warnings module so absolute_import + +import fixtures + + +class Deprecations(fixtures.Fixture): + """Prevent calls to deprecated function. + + This fixture can be added to a testcase to ensure that the code under test + isn't calling deprecated function. It sets Python's `warnings` module for + the module under test to "error" so that DeprecationWarning will be + raised. + + You might want your application to not use any deprecated function. + Deprecated function is going to be removed and sometimes is being removed + because it's buggy and you shouldn't be using it. + + It can be difficult to tell just through code reviews that new code is + calling deprecated function. This fixture can be used to protect you from + developers proposing changes that use deprecated function. + + It can also be useful to be able to test if your application is still using + some function that's been newly deprecated. + + :param str module: The name of the module. Deprecated function called from + this module will be errors. + + """ + + def __init__(self, module): + super(Deprecations, self).__init__() + self._module = module + + def _setUp(self): + module_regex = '^%s' % re.escape(self._module + '.') + warnings.filterwarnings('error', category=DeprecationWarning, + module=module_regex) + self.addCleanup(warnings.resetwarnings) + + def expect_deprecations(self): + """Indicate that this test expects to call deprecated function. + + If you've got a test that you expect to call deprecated function and + you don't want it to fail call this at the start of the test. + + """ + warnings.resetwarnings() + + @contextlib.contextmanager + def expect_deprecations_here(self): + """This section of code expects to call deprecated function. + + If you've got a test that part of it is testing deprecated function + then wrap the part in this context manager:: + + with self.deprecations.expect_deprecations_here(): + call_deprecated_function() + + """ + warnings.resetwarnings() + + yield + + module_regex = '^%s' % re.escape(self._module + '.') + warnings.filterwarnings('error', category=DeprecationWarning, + module=module_regex) diff --git a/fixtures/tests/_fixtures/__init__.py b/fixtures/tests/_fixtures/__init__.py index 1b4c359..12347fc 100644 --- a/fixtures/tests/_fixtures/__init__.py +++ b/fixtures/tests/_fixtures/__init__.py @@ -15,6 +15,7 @@ def load_tests(loader, standard_tests, pattern): test_modules = [ + 'deprecations', 'environ', 'logger', 'mockpatch', diff --git a/fixtures/tests/_fixtures/test_deprecations.py b/fixtures/tests/_fixtures/test_deprecations.py new file mode 100644 index 0000000..7aefcb1 --- /dev/null +++ b/fixtures/tests/_fixtures/test_deprecations.py @@ -0,0 +1,59 @@ +# Copyright 2015 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import warnings + +import testtools + +from fixtures import Deprecations + + +MODULE = 'fixtures' + + +class TestDeprecations(testtools.TestCase): + def test_enabled_raises(self): + # When the Deprecations fixture is active, calling deprecated function + # is an error. + self.useFixture(Deprecations(MODULE)) + self.assertRaises( + DeprecationWarning, + lambda: warnings.warn('message ignored', DeprecationWarning)) + + def test_expect_deprecations(self): + # When expect_deprecations in a test, deprecations are not an error. + deprecations = self.useFixture(Deprecations(MODULE)) + deprecations.expect_deprecations() + warnings.warn('message ignored', DeprecationWarning) + + def test_expect_deprecations_here(self): + # While in the expect_deprecations_here() context, deprecations are not + # errors, and afterwards deprecations are errors. + deprecations = self.useFixture(Deprecations(MODULE)) + with deprecations.expect_deprecations_here(): + warnings.warn('message ignored', DeprecationWarning) + self.assertRaises( + DeprecationWarning, + lambda: warnings.warn('message ignored', DeprecationWarning)) + + def test_other_module(self): + # When the Deprecations fixture is active, deprecations from other + # modules are ignored. + self.useFixture(Deprecations('different_module')) + warnings.warn('message ignored', DeprecationWarning) + + def test_null_case(self): + # When the Deprecations fixture isn't used then deprecations are not + # errors. This shows that python works as expected. + warnings.warn('message ignored', DeprecationWarning) From 55c3636f0067a93368357aa2fa7c9e830a88cc07 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Wed, 9 Dec 2015 10:01:11 -0600 Subject: [PATCH 02/10] Import warnings in README unit tests fail due to the example not importing warnings. --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 1d36e3b..383f25e 100644 --- a/README +++ b/README @@ -339,6 +339,7 @@ Deprecations Prevent code under test from calling deprecated functions. + >>> import warnings >>> fixture = fixtures.Deprecations('my_module') >>> fixture.setUp() >>> warnings.warn('stop using me', DeprecationWarning) # will raise From df856f0e6e176fdfceefeb6bdd05a853070c129f Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Wed, 9 Dec 2015 10:02:23 -0600 Subject: [PATCH 03/10] Use context for Deprecations fixture in example This is a little cleaner --- README | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README b/README index 383f25e..389791e 100644 --- a/README +++ b/README @@ -340,10 +340,8 @@ Deprecations Prevent code under test from calling deprecated functions. >>> import warnings - >>> fixture = fixtures.Deprecations('my_module') - >>> fixture.setUp() - >>> warnings.warn('stop using me', DeprecationWarning) # will raise - >>> fixture.cleanUp() + >>> with fixtures.Deprecations('my_module'): + ... warnings.warn('stop using me', DeprecationWarning) # will raise EnvironmentVariable +++++++++++++++++++ From 79397791c3ef6190a5fefe091caaf9f2d12cbeac Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 12:48:41 -0500 Subject: [PATCH 04/10] Cleanups Fixed up some comments and copyrights. --- fixtures/_fixtures/deprecations.py | 35 ++++++++++--------- fixtures/tests/_fixtures/test_deprecations.py | 23 ++++++------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/fixtures/_fixtures/deprecations.py b/fixtures/_fixtures/deprecations.py index 1489aa1..192ba3a 100644 --- a/fixtures/_fixtures/deprecations.py +++ b/fixtures/_fixtures/deprecations.py @@ -1,19 +1,22 @@ -# Copyright 2015 IBM Corp. +# Copyright (c) 2015 IBM Corp. # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause +# license at the users choice. A copy of both licenses are available in the +# project source as Apache-2.0 and BSD. You may not use this file except in +# compliance with one of these two licences. + +# Unless required by applicable law or agreed to in writing, software +# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# license you chose for the specific language governing permissions and +# limitations under that license. from __future__ import absolute_import +__all__ = [ + 'Deprecations', +] + import contextlib import re import warnings # conflicts with the local warnings module so absolute_import @@ -22,7 +25,7 @@ class Deprecations(fixtures.Fixture): - """Prevent calls to deprecated function. + """Prevent calls to deprecated functions. This fixture can be added to a testcase to ensure that the code under test isn't calling deprecated function. It sets Python's `warnings` module for @@ -40,9 +43,8 @@ class Deprecations(fixtures.Fixture): It can also be useful to be able to test if your application is still using some function that's been newly deprecated. - :param str module: The name of the module. Deprecated function called from - this module will be errors. - + :param str module: The name of a Python module. DeprecationWarnings emitted + from this module will cause an error to be raised. """ def __init__(self, module): @@ -60,7 +62,6 @@ def expect_deprecations(self): If you've got a test that you expect to call deprecated function and you don't want it to fail call this at the start of the test. - """ warnings.resetwarnings() diff --git a/fixtures/tests/_fixtures/test_deprecations.py b/fixtures/tests/_fixtures/test_deprecations.py index 7aefcb1..d56a1b0 100644 --- a/fixtures/tests/_fixtures/test_deprecations.py +++ b/fixtures/tests/_fixtures/test_deprecations.py @@ -1,16 +1,15 @@ -# Copyright 2015 IBM Corp. +# Copyright (c) 2015 IBM Corp. # -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause +# license at the users choice. A copy of both licenses are available in the +# project source as Apache-2.0 and BSD. You may not use this file except in +# compliance with one of these two licences. + +# Unless required by applicable law or agreed to in writing, software +# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# license you chose for the specific language governing permissions and +# limitations under that license. import warnings From 022069716646a14936d00a448ddc474a82ada067 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 12:53:25 -0500 Subject: [PATCH 05/10] Revert unnecessary change --- README | 2 +- fixtures/__init__.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 2baabf0..d74af26 100644 --- a/README +++ b/README @@ -402,7 +402,7 @@ MockPatchMultiple Adapts ``mock.patch.multiple`` to be used as a Fixture. - >>> fixture = fixtures.MockPatchMultiple('subprocess.Popen', returncode=3) + >>> fixture = fixtures.MockPatch('subprocess.Popen', returncode=3) MonkeyPatch +++++++++++ diff --git a/fixtures/__init__.py b/fixtures/__init__.py index 6b97dfc..0c8fca5 100644 --- a/fixtures/__init__.py +++ b/fixtures/__init__.py @@ -1,12 +1,12 @@ # fixtures: Fixtures with cleanups for testing and convenience. # # Copyright (c) 2010, 2011, Robert Collins -# +# # Licensed under either the Apache License, Version 2.0 or the BSD 3-clause # license at the users choice. A copy of both licenses are available in the # project source as Apache-2.0 and BSD. You may not use this file except in # compliance with one of these two licences. -# +# # Unless required by applicable law or agreed to in writing, software # distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the From 0d0f027b29d8f23b414fa5de6da7366f357becdc Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 14:49:17 -0500 Subject: [PATCH 06/10] Use catch_warnings --- fixtures/_fixtures/deprecations.py | 36 +++++++++++-------- fixtures/tests/_fixtures/test_deprecations.py | 21 +++++++++-- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/fixtures/_fixtures/deprecations.py b/fixtures/_fixtures/deprecations.py index 192ba3a..0b10940 100644 --- a/fixtures/_fixtures/deprecations.py +++ b/fixtures/_fixtures/deprecations.py @@ -49,21 +49,29 @@ class Deprecations(fixtures.Fixture): def __init__(self, module): super(Deprecations, self).__init__() - self._module = module + self._module_regex = '^%s' % re.escape(module + '.') def _setUp(self): - module_regex = '^%s' % re.escape(self._module + '.') + cw = warnings.catch_warnings() + cw.__enter__() + self.addCleanup(cw.__exit__) warnings.filterwarnings('error', category=DeprecationWarning, - module=module_regex) - self.addCleanup(warnings.resetwarnings) + module=self._module_regex) - def expect_deprecations(self): + def ignore_deprecations(self): """Indicate that this test expects to call deprecated function. - If you've got a test that you expect to call deprecated function and - you don't want it to fail call this at the start of the test. + Normally you'll want to protect all tests from calling deprecated + functions, then some function is deprecated and now tests are failing + due to the deprecation. This function can be used to indicate + that the test is going to call deprecated function and not to fail. + This can be used as a marker for either tests that are there to verify + deprecated functions continue to work and will be removed along with + the function, or as tests that need to be fixed to stop calling + deprecated functions. """ - warnings.resetwarnings() + warnings.filterwarnings('ignore', category=DeprecationWarning, + module=self._module_regex) @contextlib.contextmanager def expect_deprecations_here(self): @@ -76,10 +84,8 @@ def expect_deprecations_here(self): call_deprecated_function() """ - warnings.resetwarnings() - - yield - - module_regex = '^%s' % re.escape(self._module + '.') - warnings.filterwarnings('error', category=DeprecationWarning, - module=module_regex) + try: + self.cleanUp() + yield + finally: + self.setUp() diff --git a/fixtures/tests/_fixtures/test_deprecations.py b/fixtures/tests/_fixtures/test_deprecations.py index d56a1b0..47d7691 100644 --- a/fixtures/tests/_fixtures/test_deprecations.py +++ b/fixtures/tests/_fixtures/test_deprecations.py @@ -30,10 +30,10 @@ def test_enabled_raises(self): DeprecationWarning, lambda: warnings.warn('message ignored', DeprecationWarning)) - def test_expect_deprecations(self): - # When expect_deprecations in a test, deprecations are not an error. + def test_ignore_deprecations(self): + # When ignore_deprecations() in a test, deprecations are not an error. deprecations = self.useFixture(Deprecations(MODULE)) - deprecations.expect_deprecations() + deprecations.ignore_deprecations() warnings.warn('message ignored', DeprecationWarning) def test_expect_deprecations_here(self): @@ -56,3 +56,18 @@ def test_null_case(self): # When the Deprecations fixture isn't used then deprecations are not # errors. This shows that python works as expected. warnings.warn('message ignored', DeprecationWarning) + + def test_restore_warnings(self): + # When the test is done using the Deprecations fixture, the original + # warning settings are restored to whatever they were before. + warnings.filterwarnings('always', category=DeprecationWarning, + module=r'^%s\.' % MODULE) + + # Define a function so the warning always comes from the same line. + def f(): + warnings.warn('deprecation warning', DeprecationWarning) + + f() + with Deprecations(MODULE): + self.assertRaises(DeprecationWarning, f) + f() From fc7337d72d63086878f5dd93332d26cec2b0e956 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 14:59:27 -0500 Subject: [PATCH 07/10] Rename expect_deprecations_here to ignore_deprecations_here --- fixtures/_fixtures/deprecations.py | 8 ++--- fixtures/tests/_fixtures/test_deprecations.py | 31 +++++-------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/fixtures/_fixtures/deprecations.py b/fixtures/_fixtures/deprecations.py index 0b10940..673081c 100644 --- a/fixtures/_fixtures/deprecations.py +++ b/fixtures/_fixtures/deprecations.py @@ -74,18 +74,18 @@ def ignore_deprecations(self): module=self._module_regex) @contextlib.contextmanager - def expect_deprecations_here(self): - """This section of code expects to call deprecated function. + def ignore_deprecations_here(self): + """This section of code ignores calls to deprecated functions. - If you've got a test that part of it is testing deprecated function + If you've got a test that part of it is testing deprecated functions then wrap the part in this context manager:: with self.deprecations.expect_deprecations_here(): call_deprecated_function() """ + self.cleanUp() try: - self.cleanUp() yield finally: self.setUp() diff --git a/fixtures/tests/_fixtures/test_deprecations.py b/fixtures/tests/_fixtures/test_deprecations.py index 47d7691..cb747c9 100644 --- a/fixtures/tests/_fixtures/test_deprecations.py +++ b/fixtures/tests/_fixtures/test_deprecations.py @@ -22,6 +22,11 @@ class TestDeprecations(testtools.TestCase): + def test_null_case(self): + # When the Deprecations fixture isn't used then deprecations are not + # errors. This shows that python works as required for these tests. + warnings.warn('message ignored', DeprecationWarning) + def test_enabled_raises(self): # When the Deprecations fixture is active, calling deprecated function # is an error. @@ -36,11 +41,11 @@ def test_ignore_deprecations(self): deprecations.ignore_deprecations() warnings.warn('message ignored', DeprecationWarning) - def test_expect_deprecations_here(self): - # While in the expect_deprecations_here() context, deprecations are not + def test_ignore_deprecations_here(self): + # While in the ignore_deprecations_here() context, deprecations are not # errors, and afterwards deprecations are errors. deprecations = self.useFixture(Deprecations(MODULE)) - with deprecations.expect_deprecations_here(): + with deprecations.ignore_deprecations_here(): warnings.warn('message ignored', DeprecationWarning) self.assertRaises( DeprecationWarning, @@ -51,23 +56,3 @@ def test_other_module(self): # modules are ignored. self.useFixture(Deprecations('different_module')) warnings.warn('message ignored', DeprecationWarning) - - def test_null_case(self): - # When the Deprecations fixture isn't used then deprecations are not - # errors. This shows that python works as expected. - warnings.warn('message ignored', DeprecationWarning) - - def test_restore_warnings(self): - # When the test is done using the Deprecations fixture, the original - # warning settings are restored to whatever they were before. - warnings.filterwarnings('always', category=DeprecationWarning, - module=r'^%s\.' % MODULE) - - # Define a function so the warning always comes from the same line. - def f(): - warnings.warn('deprecation warning', DeprecationWarning) - - f() - with Deprecations(MODULE): - self.assertRaises(DeprecationWarning, f) - f() From 46e10c8ebc1613fb770ca6c571bbeeb401eef485 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 15:00:10 -0500 Subject: [PATCH 08/10] Undo unrelated change --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 03ae26e..213e3c2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,3 @@ AUTHORS ChangeLog .eggs build -.tox From f7e61132811e50f85ffce4e85696a1433a5dc8e6 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 15:20:22 -0500 Subject: [PATCH 09/10] Add test for multiple instances --- fixtures/tests/_fixtures/test_deprecations.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/fixtures/tests/_fixtures/test_deprecations.py b/fixtures/tests/_fixtures/test_deprecations.py index cb747c9..83b1744 100644 --- a/fixtures/tests/_fixtures/test_deprecations.py +++ b/fixtures/tests/_fixtures/test_deprecations.py @@ -49,10 +49,24 @@ def test_ignore_deprecations_here(self): warnings.warn('message ignored', DeprecationWarning) self.assertRaises( DeprecationWarning, - lambda: warnings.warn('message ignored', DeprecationWarning)) + lambda: warnings.warn('not ignored', DeprecationWarning)) def test_other_module(self): # When the Deprecations fixture is active, deprecations from other # modules are ignored. self.useFixture(Deprecations('different_module')) warnings.warn('message ignored', DeprecationWarning) + + def test_multiple_instances(self): + # When there are multiple Deprecations fixtures in use, one going out + # of scope doesn't mess up the other one. + self.useFixture(Deprecations(MODULE)) + + with Deprecations('different_module'): + self.assertRaises( + DeprecationWarning, + lambda: warnings.warn('not ignored', DeprecationWarning)) + + self.assertRaises( + DeprecationWarning, + lambda: warnings.warn('not ignored', DeprecationWarning)) From f4eacf23a0f2b2461199f8e152ac44615bd4b633 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Thu, 7 Apr 2016 15:23:07 -0500 Subject: [PATCH 10/10] Add note about modifying global state --- fixtures/_fixtures/deprecations.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fixtures/_fixtures/deprecations.py b/fixtures/_fixtures/deprecations.py index 673081c..9325b77 100644 --- a/fixtures/_fixtures/deprecations.py +++ b/fixtures/_fixtures/deprecations.py @@ -43,6 +43,10 @@ class Deprecations(fixtures.Fixture): It can also be useful to be able to test if your application is still using some function that's been newly deprecated. + .. note:: This fixture uses :func:`warnings.catch_warnings`, as such the + note there applies: The fixture modifies global state and therefore is + not thread safe. + :param str module: The name of a Python module. DeprecationWarnings emitted from this module will cause an error to be raised. """