commit python3-fixtures for openSUSE:Factory
30 Sep
2015
30 Sep
'15
03:49
Hello community, here is the log from the commit of package python3-fixtures for openSUSE:Factory checked in at 2015-09-30 05:49:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-fixtures (Old) and /work/SRC/openSUSE:Factory/.python3-fixtures.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-fixtures" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-fixtures/python3-fixtures.changes 2015-05-11 19:49:16.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-fixtures.new/python3-fixtures.changes 2015-09-30 05:49:27.000000000 +0200 @@ -1,0 +2,16 @@ +Tue Jun 30 23:06:13 UTC 2015 - arun@gmx.de + +- update to version 1.3.1: + * Clarify the intent around _setUp + * Handle BaseException resource leaks as well + +- changes from version 1.3.0: + * Remove trailing whitespace + * Deal with resource leaks during setUp + * Missed NEWS entry + * Fine tune the mock patch + * Add a new mockpatch fixture + * Document where the project home and source are + * Ignore built things + +------------------------------------------------------------------- Old: ---- fixtures-1.2.0.tar.gz New: ---- fixtures-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-fixtures.spec ++++++ --- /var/tmp/diff_new_pack.Mf9tpT/_old 2015-09-30 05:49:28.000000000 +0200 +++ /var/tmp/diff_new_pack.Mf9tpT/_new 2015-09-30 05:49:28.000000000 +0200 @@ -17,7 +17,7 @@ Name: python3-fixtures -Version: 1.2.0 +Version: 1.3.1 Release: 0 Summary: Fixtrues, reusable state for writing clean tests and more License: Apache-2.0 or BSD-3-Clause ++++++ fixtures-1.2.0.tar.gz -> fixtures-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/AUTHORS new/fixtures-1.3.1/AUTHORS --- old/fixtures-1.2.0/AUTHORS 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/AUTHORS 2015-06-30 04:22:04.000000000 +0200 @@ -9,6 +9,7 @@ Jonathan Lange <jml@canonical.com> Jonathan Lange <jml@mumak.net> Joshua Harlow <harlowja@yahoo-inc.com> +Julien Danjou <julien@danjou.info> Martin Pool <mbp@canonical.com> Robert Collins <robertc@robertcollins.net> Sean Dague <sean@dague.net> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/ChangeLog new/fixtures-1.3.1/ChangeLog --- old/fixtures-1.2.0/ChangeLog 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/ChangeLog 2015-06-30 04:22:04.000000000 +0200 @@ -1,6 +1,25 @@ CHANGES ======= +1.3.1 +----- + +* Release 1.3.1 +* Clarify the intent around _setUp +* Handle BaseException resource leaks as well + +1.3.0 +----- + +* Release 1.3.0 +* Remove trailing whitespace +* Deal with resource leaks during setUp +* Missed NEWS entry +* Fine tune the mock patch +* Add a new mockpatch fixture +* Document where the project home and source are +* Ignore built things + 1.2.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/NEWS new/fixtures-1.3.1/NEWS --- old/fixtures-1.2.0/NEWS 2015-05-04 23:50:18.000000000 +0200 +++ new/fixtures-1.3.1/NEWS 2015-06-30 04:21:13.000000000 +0200 @@ -6,6 +6,27 @@ NEXT ~~~~ +1.3.1 +~~~~~ + +* ``Fixture.setUp`` now uses a bare except: and will thus catch BaseException. + Any non-Exception-subclass errors are raised verbatim after calling + ``cleanUp``, to avoid inappropriate masking in callers. (Robert Collins) + +1.3.0 +~~~~~ + +* Add MockPatch, MockPatchMultiple, MockPatchObject - adapters to mock. + (Julien Danjou, Robert Collins) + +* Fixture.setUp should no longer be overridden in subclasses. Instead + override _setUp. This permits the Fixture base class to detect failures + during _setUp and trigger any registered cleanups, attach any details + to the failure exception and propogate that to callers. Overriding of + setUp is still supported: this adds a new interface for simpler + implementation of the contract of a fixture. + (Robert Collins, #1456361, #1456353) + 1.2.0 ~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/PKG-INFO new/fixtures-1.3.1/PKG-INFO --- old/fixtures-1.2.0/PKG-INFO 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/PKG-INFO 2015-06-30 04:22:04.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: fixtures -Version: 1.2.0 +Version: 1.3.1 Summary: Fixtures, reusable state for writing clean tests and more. Home-page: https://launchpad.net/python-fixtures Author: Robert Collins @@ -87,19 +87,20 @@ Creating Fixtures ================= - Minimally, subclass Fixture, define setUp to initialize your state and schedule + Minimally, subclass Fixture, define _setUp to initialize your state and schedule a cleanup for when cleanUp is called and you're done:: >>> import unittest >>> import fixtures >>> class NoddyFixture(fixtures.Fixture): - ... def setUp(self): - ... super(NoddyFixture, self).setUp() + ... def _setUp(self): ... self.frobnozzle = 42 ... self.addCleanup(delattr, self, 'frobnozzle') - This will initialize frobnozzle when setUp is called, and when cleanUp is - called get rid of the frobnozzle attribute. + This will initialize frobnozzle when ``setUp`` is called, and when ``cleanUp`` + is called get rid of the frobnozzle attribute. Prior to version 1.3.0 fixtures + recommended overriding ``setUp``. This is still supported, but since it is + harder to write leak-free fixtures in this fashion, it is not recommended. If your fixture has diagnostic data - for instance the log file of an application server, or log messages, it can expose that by creating a content @@ -107,8 +108,7 @@ >>> from testtools.content import text_content >>> class WithLog(fixtures.Fixture): - ... def setUp(self): - ... super(WithLog, self).setUp() + ... def _setUp(self): ... self.addDetail('message', text_content('foo bar baz')) The method ``useFixture`` will use another fixture, call ``setUp`` on it, call @@ -116,8 +116,7 @@ the fixture. This allows simple composition of different fixtures. >>> class ReusingFixture(fixtures.Fixture): - ... def setUp(self): - ... super(ReusingFixture, self).setUp() + ... def _setUp(self): ... self.noddy = self.useFixture(NoddyFixture()) There is a helper for adapting a function or function pair into Fixtures. it @@ -162,9 +161,9 @@ clean up after a fixture has been used, all fixtures define a ``cleanUp`` method which should be called when a fixture is finished with. - Because its nice to be able to build a particular set of related fixtures in - advance of using them, fixtures also have define a ``setUp`` method which - should be called before trying to use them. + Because it's nice to be able to build a particular set of related fixtures in + advance of using them, fixtures also have a ``setUp`` method which should be + called before trying to use them. One common desire with fixtures that are expensive to create is to reuse them in many test cases; to support this the base Fixture also defines a ``reset`` @@ -211,8 +210,7 @@ >>> import sys >>> from fixtures.fixture import MultipleExceptions >>> class BrokenFixture(fixtures.Fixture): - ... def setUp(self): - ... fixtures.Fixture.setUp(self) + ... def _setUp(self): ... self.addCleanup(lambda:1/0) ... self.addCleanup(lambda:1/0) >>> fixture = BrokenFixture() @@ -226,12 +224,32 @@ Fixtures often expose diagnostic details that can be useful for tracking down issues. The ``getDetails`` method will return a dict of all the attached - details. Each detail object is an instance of ``testtools.content.Content``. + details, but can only be called before ``cleanUp`` is called. Each detail + object is an instance of ``testtools.content.Content``. >>> with WithLog() as l: ... print(l.getDetails()['message'].as_text()) foo bar baz + Errors in setUp + +++++++++++++++ + + The examples above used ``_setUp`` rather than ``setUp`` because the base + class implementation of ``setUp`` acts to reduce the chance of leaking + external resources if an error is raised from ``_setUp``. Specifically, + ``setUp`` contains a try:/except: block which catches all exceptions, captures + any registered detail objects, and calls ``self.cleanUp`` before propogating + the error. As long as you take care to register any cleanups before calling + the code that may fail, this will cause them to be cleaned up. The captured + detail objects are provided to the args of the raised exception. + + If the error that occured was a subclass of ``Exception`` then ``setUp`` will + raise ``MultipleExceptions`` with the last element being a ``SetupError`` that + contains the detail objects. Otherwise, to prevent causing normally + uncatchable errors like KeyboardInterrupt being caught inappropriately in the + calling layer, the original exception will be raised as-is and no diagnostic + data other than that from the original exception will be available. + Shared Dependencies +++++++++++++++++++ @@ -308,7 +326,8 @@ In addition to the Fixture, FunctionFixture and MethodFixture classes fixtures includes a number of precanned fixtures. The API docs for fixtures will list - the complete set of these, should the dcs be out of date or not to hand. + the complete set of these, should the dcs be out of date or not to hand. For + the complete feature set of each fixture please see the API docs. ByteStream ++++++++++ @@ -348,6 +367,34 @@ >>> from testtools.compat import BytesIO >>> fixture = fixtures.FakePopen(lambda _:{'stdout': BytesIO('foobar')}) + MockPatchObject + +++++++++++++++ + + Adapts ``mock.patch.object`` to be used as a Fixture. + + >>> class Fred: + ... value = 1 + >>> fixture = fixtures.MockPatchObject(Fred, 'value', 2) + >>> with fixture: + ... Fred().value + 2 + >>> Fred().value + 1 + + MockPatch + +++++++++ + + Adapts ``mock.patch`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen.returncode', 3) + + MockPatchMultiple + +++++++++++++++++ + + Adapts ``mock.patch.multiple`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen', returncode=3) + MonkeyPatch +++++++++++ @@ -447,6 +494,13 @@ *Note:* Currently supported only on Unix because it relies on the ``alarm`` system call. + Contributing + ============ + + Fixtures has its project homepage on Launchpad + <https://launchpad.net/python-fixtures>. Source code is hosted on GitHub + <https://github.com/testing-cabal/fixtures>. + Platform: UNKNOWN Classifier: Development Status :: 6 - Mature diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/README new/fixtures-1.3.1/README --- old/fixtures-1.2.0/README 2014-09-25 04:37:13.000000000 +0200 +++ new/fixtures-1.3.1/README 2015-06-30 02:56:38.000000000 +0200 @@ -79,19 +79,20 @@ Creating Fixtures ================= -Minimally, subclass Fixture, define setUp to initialize your state and schedule +Minimally, subclass Fixture, define _setUp to initialize your state and schedule a cleanup for when cleanUp is called and you're done:: >>> import unittest >>> import fixtures >>> class NoddyFixture(fixtures.Fixture): - ... def setUp(self): - ... super(NoddyFixture, self).setUp() + ... def _setUp(self): ... self.frobnozzle = 42 ... self.addCleanup(delattr, self, 'frobnozzle') -This will initialize frobnozzle when setUp is called, and when cleanUp is -called get rid of the frobnozzle attribute. +This will initialize frobnozzle when ``setUp`` is called, and when ``cleanUp`` +is called get rid of the frobnozzle attribute. Prior to version 1.3.0 fixtures +recommended overriding ``setUp``. This is still supported, but since it is +harder to write leak-free fixtures in this fashion, it is not recommended. If your fixture has diagnostic data - for instance the log file of an application server, or log messages, it can expose that by creating a content @@ -99,8 +100,7 @@ >>> from testtools.content import text_content >>> class WithLog(fixtures.Fixture): - ... def setUp(self): - ... super(WithLog, self).setUp() + ... def _setUp(self): ... self.addDetail('message', text_content('foo bar baz')) The method ``useFixture`` will use another fixture, call ``setUp`` on it, call @@ -108,8 +108,7 @@ the fixture. This allows simple composition of different fixtures. >>> class ReusingFixture(fixtures.Fixture): - ... def setUp(self): - ... super(ReusingFixture, self).setUp() + ... def _setUp(self): ... self.noddy = self.useFixture(NoddyFixture()) There is a helper for adapting a function or function pair into Fixtures. it @@ -154,9 +153,9 @@ clean up after a fixture has been used, all fixtures define a ``cleanUp`` method which should be called when a fixture is finished with. -Because its nice to be able to build a particular set of related fixtures in -advance of using them, fixtures also have define a ``setUp`` method which -should be called before trying to use them. +Because it's nice to be able to build a particular set of related fixtures in +advance of using them, fixtures also have a ``setUp`` method which should be +called before trying to use them. One common desire with fixtures that are expensive to create is to reuse them in many test cases; to support this the base Fixture also defines a ``reset`` @@ -203,8 +202,7 @@ >>> import sys >>> from fixtures.fixture import MultipleExceptions >>> class BrokenFixture(fixtures.Fixture): - ... def setUp(self): - ... fixtures.Fixture.setUp(self) + ... def _setUp(self): ... self.addCleanup(lambda:1/0) ... self.addCleanup(lambda:1/0) >>> fixture = BrokenFixture() @@ -218,12 +216,32 @@ Fixtures often expose diagnostic details that can be useful for tracking down issues. The ``getDetails`` method will return a dict of all the attached -details. Each detail object is an instance of ``testtools.content.Content``. +details, but can only be called before ``cleanUp`` is called. Each detail +object is an instance of ``testtools.content.Content``. >>> with WithLog() as l: ... print(l.getDetails()['message'].as_text()) foo bar baz +Errors in setUp ++++++++++++++++ + +The examples above used ``_setUp`` rather than ``setUp`` because the base +class implementation of ``setUp`` acts to reduce the chance of leaking +external resources if an error is raised from ``_setUp``. Specifically, +``setUp`` contains a try:/except: block which catches all exceptions, captures +any registered detail objects, and calls ``self.cleanUp`` before propogating +the error. As long as you take care to register any cleanups before calling +the code that may fail, this will cause them to be cleaned up. The captured +detail objects are provided to the args of the raised exception. + +If the error that occured was a subclass of ``Exception`` then ``setUp`` will +raise ``MultipleExceptions`` with the last element being a ``SetupError`` that +contains the detail objects. Otherwise, to prevent causing normally +uncatchable errors like KeyboardInterrupt being caught inappropriately in the +calling layer, the original exception will be raised as-is and no diagnostic +data other than that from the original exception will be available. + Shared Dependencies +++++++++++++++++++ @@ -300,7 +318,8 @@ In addition to the Fixture, FunctionFixture and MethodFixture classes fixtures includes a number of precanned fixtures. The API docs for fixtures will list -the complete set of these, should the dcs be out of date or not to hand. +the complete set of these, should the dcs be out of date or not to hand. For +the complete feature set of each fixture please see the API docs. ByteStream ++++++++++ @@ -340,6 +359,34 @@ >>> from testtools.compat import BytesIO >>> fixture = fixtures.FakePopen(lambda _:{'stdout': BytesIO('foobar')}) +MockPatchObject ++++++++++++++++ + +Adapts ``mock.patch.object`` to be used as a Fixture. + + >>> class Fred: + ... value = 1 + >>> fixture = fixtures.MockPatchObject(Fred, 'value', 2) + >>> with fixture: + ... Fred().value + 2 + >>> Fred().value + 1 + +MockPatch ++++++++++ + +Adapts ``mock.patch`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen.returncode', 3) + +MockPatchMultiple ++++++++++++++++++ + +Adapts ``mock.patch.multiple`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen', returncode=3) + MonkeyPatch +++++++++++ @@ -438,3 +485,10 @@ *Note:* Currently supported only on Unix because it relies on the ``alarm`` system call. + +Contributing +============ + +Fixtures has its project homepage on Launchpad +<https://launchpad.net/python-fixtures>. Source code is hosted on GitHub +<https://github.com/testing-cabal/fixtures>. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/__init__.py new/fixtures-1.3.1/fixtures/__init__.py --- old/fixtures-1.2.0/fixtures/__init__.py 2015-05-04 23:49:57.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/__init__.py 2015-06-22 08:56:00.000000000 +0200 @@ -54,12 +54,17 @@ 'LogHandler', 'LoggerFixture', 'MethodFixture', + 'MockPatch', + 'MockPatchMultiple', + 'MockPatchObject', 'MonkeyPatch', + 'MultipleExceptions', 'NestedTempfile', 'PackagePathEntry', 'PopenFixture', 'PythonPackage', 'PythonPathEntry', + 'SetupError', 'StringStream', 'TempDir', 'TempHomeDir', @@ -76,6 +81,8 @@ Fixture, FunctionFixture, MethodFixture, + MultipleExceptions, + SetupError, ) from fixtures._fixtures import ( ByteStream, @@ -86,6 +93,9 @@ FakePopen, LoggerFixture, LogHandler, + MockPatch, + MockPatchMultiple, + MockPatchObject, MonkeyPatch, NestedTempfile, PackagePathEntry, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/__init__.py new/fixtures-1.3.1/fixtures/_fixtures/__init__.py --- old/fixtures-1.2.0/fixtures/_fixtures/__init__.py 2015-05-04 23:49:57.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/__init__.py 2015-06-22 02:24:03.000000000 +0200 @@ -25,6 +25,9 @@ 'FakePopen', 'LoggerFixture', 'LogHandler', + 'MockPatch', + 'MockPatchMultiple', + 'MockPatchObject', 'MonkeyPatch', 'NestedTempfile', 'PackagePathEntry', @@ -49,6 +52,11 @@ LoggerFixture, LogHandler, ) +from fixtures._fixtures.mockpatch import ( + MockPatch, + MockPatchMultiple, + MockPatchObject, + ) from fixtures._fixtures.monkeypatch import MonkeyPatch from fixtures._fixtures.popen import ( FakePopen, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/environ.py new/fixtures-1.3.1/fixtures/_fixtures/environ.py --- old/fixtures-1.2.0/fixtures/_fixtures/environ.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/environ.py 2015-06-22 08:56:00.000000000 +0200 @@ -40,8 +40,7 @@ self.varname = varname self.newvalue = newvalue - def setUp(self): - super(EnvironmentVariable, self).setUp() + def _setUp(self): varname = self.varname orig_value = os.environ.get(varname) if orig_value is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/logger.py new/fixtures-1.3.1/fixtures/_fixtures/logger.py --- old/fixtures-1.2.0/fixtures/_fixtures/logger.py 2015-03-26 21:33:59.000000000 +0100 +++ new/fixtures-1.3.1/fixtures/_fixtures/logger.py 2015-06-22 08:56:00.000000000 +0200 @@ -46,8 +46,7 @@ self._level = level self._nuke_handlers = nuke_handlers - def setUp(self): - super(LogHandler, self).setUp() + def _setUp(self): logger = getLogger(self._name) if self._level: self.addCleanup(logger.setLevel, logger.level) @@ -95,8 +94,7 @@ self._nuke_handlers = nuke_handlers self._formatter = formatter - def setUp(self): - super(FakeLogger, self).setUp() + def _setUp(self): name = _u("pythonlogging:'%s'") % self._name output = self.useFixture(StringStream(name)).stream self._output = output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/mockpatch.py new/fixtures-1.3.1/fixtures/_fixtures/mockpatch.py --- old/fixtures-1.2.0/fixtures/_fixtures/mockpatch.py 1970-01-01 01:00:00.000000000 +0100 +++ new/fixtures-1.3.1/fixtures/_fixtures/mockpatch.py 2015-06-22 08:56:00.000000000 +0200 @@ -0,0 +1,71 @@ +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# Copyright 2013 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# 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 extras + +import fixtures + +mock = extras.try_imports(['unittest.mock', 'mock'], None) +mock_default = extras.try_imports( + ['unittest.mock.DEFAULT', 'mock.DEFAULT'], None) + + +class _Base(fixtures.Fixture): + def _setUp(self): + _p = self._get_p() + self.addCleanup(_p.stop) + self.mock = _p.start() + + +class MockPatchObject(_Base): + """Deal with code around mock.""" + + def __init__(self, obj, attr, new=mock_default, **kwargs): + super(MockPatchObject, self).__init__() + self._get_p = lambda: mock.patch.object(obj, attr, new, **kwargs) + + +class MockPatch(_Base): + """Deal with code around mock.patch.""" + + def __init__(self, obj, new=mock_default, **kwargs): + super(MockPatch, self).__init__() + self._get_p = lambda: mock.patch(obj, new, **kwargs) + + +class MockPatchMultiple(_Base): + """Deal with code around mock.patch.multiple.""" + + # Default value to trigger a MagicMock to be created for a named + # attribute. + DEFAULT = mock_default + + def __init__(self, obj, **kwargs): + """Initialize the mocks + + Pass name=value to replace obj.name with value. + + Pass name=Multiple.DEFAULT to replace obj.name with a + MagicMock instance. + + :param obj: Object or name containing values being mocked. + :type obj: str or object + :param kwargs: names and values of attributes of obj to be mocked. + + """ + super(MockPatchMultiple, self).__init__() + self._get_p = lambda: mock.patch.multiple(obj, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/monkeypatch.py new/fixtures-1.3.1/fixtures/_fixtures/monkeypatch.py --- old/fixtures-1.2.0/fixtures/_fixtures/monkeypatch.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/monkeypatch.py 2015-06-22 08:56:00.000000000 +0200 @@ -42,8 +42,7 @@ self.name = name self.new_value = new_value - def setUp(self): - Fixture.setUp(self) + def _setUp(self): location, attribute = self.name.rsplit('.', 1) # Import, swallowing all errors as any element of location may be # a class or some such thing. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/packagepath.py new/fixtures-1.3.1/fixtures/_fixtures/packagepath.py --- old/fixtures-1.2.0/fixtures/_fixtures/packagepath.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/packagepath.py 2015-06-22 08:56:00.000000000 +0200 @@ -39,8 +39,7 @@ self.packagename = packagename self.directory = directory - def setUp(self): - Fixture.setUp(self) + def _setUp(self): path = sys.modules[self.packagename].__path__ if self.directory in path: return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/popen.py new/fixtures-1.3.1/fixtures/_fixtures/popen.py --- old/fixtures-1.2.0/fixtures/_fixtures/popen.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/popen.py 2015-06-22 08:56:00.000000000 +0200 @@ -95,8 +95,7 @@ super(FakePopen, self).__init__() self.get_info = get_info - def setUp(self): - super(FakePopen, self).setUp() + def _setUp(self): self.addCleanup(setattr, subprocess, 'Popen', subprocess.Popen) subprocess.Popen = self self.procs = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/pythonpackage.py new/fixtures-1.3.1/fixtures/_fixtures/pythonpackage.py --- old/fixtures-1.2.0/fixtures/_fixtures/pythonpackage.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/pythonpackage.py 2015-06-22 08:56:00.000000000 +0200 @@ -47,8 +47,7 @@ self.modulelist = modulelist self.init = init - def setUp(self): - Fixture.setUp(self) + def _setUp(self): self.base = self.useFixture(TempDir()).path base = self.base root = os.path.join(base, self.packagename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/pythonpath.py new/fixtures-1.3.1/fixtures/_fixtures/pythonpath.py --- old/fixtures-1.2.0/fixtures/_fixtures/pythonpath.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/pythonpath.py 2015-06-22 08:56:00.000000000 +0200 @@ -35,8 +35,7 @@ """ self.directory = directory - def setUp(self): - Fixture.setUp(self) + def _setUp(self): if self.directory in sys.path: return self.addCleanup(sys.path.remove, self.directory) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/streams.py new/fixtures-1.3.1/fixtures/_fixtures/streams.py --- old/fixtures-1.2.0/fixtures/_fixtures/streams.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/streams.py 2015-06-22 08:56:00.000000000 +0200 @@ -42,8 +42,7 @@ self._detail_name = detail_name self._stream_factory = stream_factory - def setUp(self): - super(Stream, self).setUp() + def _setUp(self): write_stream, read_stream = self._stream_factory() self.stream = write_stream self.addDetail(self._detail_name, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/tempdir.py new/fixtures-1.3.1/fixtures/_fixtures/tempdir.py --- old/fixtures-1.2.0/fixtures/_fixtures/tempdir.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/tempdir.py 2015-06-22 08:56:00.000000000 +0200 @@ -39,8 +39,7 @@ """ self.rootdir = rootdir - def setUp(self): - super(TempDir, self).setUp() + def _setUp(self): self.path = tempfile.mkdtemp(dir=self.rootdir) self.addCleanup(shutil.rmtree, self.path, ignore_errors=True) @@ -63,8 +62,7 @@ down. """ - def setUp(self): - super(NestedTempfile, self).setUp() + def _setUp(self): tempdir = self.useFixture(TempDir()).path patch = fixtures.MonkeyPatch("tempfile.tempdir", tempdir) self.useFixture(patch) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/temphomedir.py new/fixtures-1.3.1/fixtures/_fixtures/temphomedir.py --- old/fixtures-1.2.0/fixtures/_fixtures/temphomedir.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/temphomedir.py 2015-06-22 08:56:00.000000000 +0200 @@ -27,6 +27,6 @@ :ivar path: the path of the temporary directory. """ - def setUp(self): - super(TempHomeDir, self).setUp() + def _setUp(self): + super(TempHomeDir, self)._setUp() self.useFixture(fixtures.EnvironmentVariable("HOME", self.path)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/timeout.py new/fixtures-1.3.1/fixtures/_fixtures/timeout.py --- old/fixtures-1.2.0/fixtures/_fixtures/timeout.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/timeout.py 2015-06-22 08:56:00.000000000 +0200 @@ -51,8 +51,7 @@ def signal_handler(self, signum, frame): raise TimeoutException() - def setUp(self): - super(Timeout, self).setUp() + def _setUp(self): if self.alarm_fn is None: return # Can't run on Windows if self.gentle: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/_fixtures/warnings.py new/fixtures-1.3.1/fixtures/_fixtures/warnings.py --- old/fixtures-1.2.0/fixtures/_fixtures/warnings.py 2015-05-04 23:49:57.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/_fixtures/warnings.py 2015-06-22 08:56:00.000000000 +0200 @@ -34,8 +34,7 @@ def _showwarning(self, *args, **kwargs): self.captures.append(warnings.WarningMessage(*args, **kwargs)) - def setUp(self): - super(WarningsCapture, self).setUp() + def _setUp(self): patch = fixtures.MonkeyPatch("warnings.showwarning", self._showwarning) self.useFixture(patch) self.captures = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/fixture.py new/fixtures-1.3.1/fixtures/fixture.py --- old/fixtures-1.2.0/fixtures/fixture.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/fixture.py 2015-06-30 03:01:38.000000000 +0200 @@ -18,11 +18,13 @@ 'FunctionFixture', 'MethodFixture', 'MultipleExceptions', + 'SetupError', ] import itertools import sys +import six from testtools.compat import ( advance_iterator, reraise, @@ -49,6 +51,13 @@ target_details[name] = content_object +class SetupError(Exception): + """Setup failed. + + args[0] will be a details dict. + """ + + class Fixture(object): """A Fixture representing some state or resource. @@ -97,6 +106,10 @@ This should not typically be overridden, see addCleanup instead. + cleanUp may be called once and only once after setUp() has been called. + The base implementation of setUp will automatically call cleanUp if + an exception occurs within setUp itself. + :param raise_first: Deprecated parameter from before testtools gained MultipleExceptions. raise_first defaults to True. When True if a single exception is raised, it is reraised after all the @@ -111,7 +124,7 @@ try: return self._cleanups(raise_errors=raise_first) finally: - self._clear_cleanups() + self._remove_state() def _clear_cleanups(self): """Clean the cleanup queue without running them. @@ -126,6 +139,15 @@ self._details = {} self._detail_sources = [] + def _remove_state(self): + """Remove the internal state. + + Called from cleanUp to put the fixture back into a not-ready state. + """ + self._cleanups = None + self._details = None + self._detail_sources = None + def __enter__(self): self.setUp() return self @@ -134,7 +156,7 @@ try: self._cleanups() finally: - self._clear_cleanups() + self._remove_state() return False # propogate exceptions from the with body. def getDetails(self): @@ -153,16 +175,56 @@ def setUp(self): """Prepare the Fixture for use. - This should be overridden by most concrete fixtures. When overriding - be sure to include self.addCleanup calls to restore the fixture to - an un-setUp state, so that a single Fixture instance can be reused. + This should not be overridden. Concrete fixtures should implement + _setUp. Overriding of setUp is still supported, just not recommended. - After setUp is called, the fixture will have one or more attributes + After setUp has completed, the fixture will have one or more attributes which can be used (these depend totally on the concrete subclass). + :raises: MultipleExceptions if _setUp fails. The last exception + captured within the MultipleExceptions will be a SetupError + exception. :return: None. + + :changed in 1.3: The recommendation to override setUp has been + reversed - before 1.3, setUp() should be overridden, now it should + not be. + :changed in 1.3.1: BaseException is now caught, and only subclasses of + Exception are wrapped in MultipleExceptions. """ self._clear_cleanups() + try: + self._setUp() + except: + err = sys.exc_info() + details = {} + if gather_details is not None: + # Materialise all details since we're about to cleanup. + gather_details(self.getDetails(), details) + else: + details = self.getDetails() + errors = [err] + self.cleanUp(raise_first=False) + try: + raise SetupError(details) + except SetupError as e: + errors.append(sys.exc_info()) + if issubclass(err[0], Exception): + raise MultipleExceptions(*errors) + else: + six.reraise(*err) + + def _setUp(self): + """Template method for subclasses to override. + + Override this to customise the fixture. When overriding + be sure to include self.addCleanup calls to restore the fixture to + an un-setUp state, so that a single Fixture instance can be reused. + + Fixtures will never have a body in _setUp - calling super() is + entirely at the discretion of subclasses. + + :return: None. + """ def reset(self): """Reset a setUp Fixture to the 'just setUp' state again. @@ -183,15 +245,23 @@ """Use another fixture. The fixture will be setUp, and self.addCleanup(fixture.cleanUp) called. + If the fixture fails to set up, useFixture will attempt to gather its + details into this fixture's details to aid in debugging. :param fixture: The fixture to use. :return: The fixture, after setting it up and scheduling a cleanup for it. + :raises: Any errors raised by the fixture's setUp method. """ try: fixture.setUp() + except MultipleExceptions as e: + if e.args[-1][0] is SetupError: + combine_details(e.args[-1][1].args[0], self._details) + raise except: - # The child failed to come up, capture any details it has (copying + # The child failed to come up and didn't raise MultipleExceptions + # which we can understand... capture any details it has (copying # the content, it may go away anytime). if gather_details is not None: gather_details(fixture.getDetails(), self._details) @@ -249,8 +319,7 @@ self.cleanup_fn = cleanup_fn self.reset_fn = reset_fn - def setUp(self): - super(FunctionFixture, self).setUp() + def _setUp(self): fn_result = self.setup_fn() self._maybe_cleanup(fn_result) @@ -323,8 +392,7 @@ reset = getattr(obj, 'reset', None) self._reset = reset - def setUp(self): - super(MethodFixture, self).setUp() + def _setUp(self): self._setup() def cleanUp(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/tests/_fixtures/__init__.py new/fixtures-1.3.1/fixtures/tests/_fixtures/__init__.py --- old/fixtures-1.2.0/fixtures/tests/_fixtures/__init__.py 2015-03-26 03:46:21.000000000 +0100 +++ new/fixtures-1.3.1/fixtures/tests/_fixtures/__init__.py 2015-06-22 02:24:03.000000000 +0200 @@ -17,6 +17,7 @@ test_modules = [ 'environ', 'logger', + 'mockpatch', 'monkeypatch', 'packagepath', 'popen', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/tests/_fixtures/test_mockpatch.py new/fixtures-1.3.1/fixtures/tests/_fixtures/test_mockpatch.py --- old/fixtures-1.2.0/fixtures/tests/_fixtures/test_mockpatch.py 1970-01-01 01:00:00.000000000 +0100 +++ new/fixtures-1.3.1/fixtures/tests/_fixtures/test_mockpatch.py 2015-06-22 02:24:03.000000000 +0200 @@ -0,0 +1,72 @@ +# Copyright 2014 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 extras +mock = extras.try_imports(['unittest.mock', 'mock'], None) +import testtools + +from fixtures import ( + MockPatch, + MockPatchMultiple, + MockPatchObject, +) + + +class Foo(object): + def bar(self): + return self + + +def mocking_bar(self): + return 'mocked!' + + +class TestMockPatch(testtools.TestCase): + def test_mock_patch_with_replacement(self): + self.useFixture(MockPatch('%s.Foo.bar' % (__name__), mocking_bar)) + instance = Foo() + self.assertEqual(instance.bar(), 'mocked!') + + def test_mock_patch_without_replacement(self): + self.useFixture(MockPatch('%s.Foo.bar' % (__name__))) + instance = Foo() + self.assertIsInstance(instance.bar(), mock.MagicMock) + + +class TestMockMultiple(testtools.TestCase): + def test_mock_multiple_with_replacement(self): + self.useFixture(MockPatchMultiple('%s.Foo' % (__name__), + bar=mocking_bar)) + instance = Foo() + self.assertEqual(instance.bar(), 'mocked!') + + def test_mock_patch_without_replacement(self): + self.useFixture(MockPatchMultiple( + '%s.Foo' % (__name__), + bar=MockPatchMultiple.DEFAULT)) + instance = Foo() + self.assertIsInstance(instance.bar(), mock.MagicMock) + + +class TestMockPatchObject(testtools.TestCase): + def test_mock_patch_object_with_replacement(self): + self.useFixture(MockPatchObject(Foo, 'bar', mocking_bar)) + instance = Foo() + self.assertEqual(instance.bar(), 'mocked!') + + def test_mock_patch_object_without_replacement(self): + self.useFixture(MockPatchObject(Foo, 'bar')) + instance = Foo() + self.assertIsInstance(instance.bar(), mock.MagicMock) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures/tests/test_fixture.py new/fixtures-1.3.1/fixtures/tests/test_fixture.py --- old/fixtures-1.2.0/fixtures/tests/test_fixture.py 2014-09-25 04:31:06.000000000 +0200 +++ new/fixtures-1.3.1/fixtures/tests/test_fixture.py 2015-06-30 02:51:08.000000000 +0200 @@ -122,7 +122,7 @@ @require_gather_details def test_useFixture_details_captured_from_setUp(self): # Details added during fixture set-up are gathered even if setUp() - # fails with an exception. + # fails with an unknown exception. class SomethingBroke(Exception): pass class BrokenFixture(fixtures.Fixture): def setUp(self): @@ -143,6 +143,24 @@ {"content": text_content("foobar")}, simple_fixture.getDetails()) + @require_gather_details + def test_useFixture_details_captured_from_setUp_MultipleExceptions(self): + # Details added during fixture set-up are gathered even if setUp() + # fails with (cleanly - with MultipleExceptions / SetupError). + class SomethingBroke(Exception): pass + class BrokenFixture(fixtures.Fixture): + def _setUp(self): + self.addDetail('content', text_content("foobar")) + raise SomethingBroke() + class SimpleFixture(fixtures.Fixture): + def _setUp(self): + self.useFixture(BrokenFixture()) + simple = SimpleFixture() + e = self.assertRaises(fixtures.MultipleExceptions, simple.setUp) + self.assertEqual( + {"content": text_content("foobar")}, + e.args[-1][1].args[0]) + def test_getDetails(self): fixture = fixtures.Fixture() with fixture: @@ -162,7 +180,7 @@ self.assertEqual({}, parent.getDetails()) # After cleanup the child details are still gone. child.addDetail('foo', 'content') - self.assertEqual({}, parent.getDetails()) + self.assertRaises(TypeError, parent.getDetails) def test_duplicate_details_are_disambiguated(self): parent = fixtures.Fixture() @@ -185,7 +203,74 @@ self.assertEqual({}, fixture.getDetails()) fixture.addDetail('foo', 'content') # Cleanup clears the details too. - self.assertEqual({}, fixture.getDetails()) + self.assertRaises(TypeError, fixture.getDetails) + + def test_setUp_subclassed(self): + # Even though its no longer recommended, we need to be sure that + # overriding setUp and calling super().setUp still works. + class Subclass(fixtures.Fixture): + def setUp(self): + super(Subclass, self).setUp() + self.fred = 1 + self.addCleanup(setattr, self, 'fred', 2) + with Subclass() as f: + self.assertEqual(1, f.fred) + self.assertEqual(2, f.fred) + + def test__setUp(self): + # _setUp is called, and cleanups can be registered by it. + class Subclass(fixtures.Fixture): + def _setUp(self): + self.fred = 1 + self.addCleanup(setattr, self, 'fred', 2) + with Subclass() as f: + self.assertEqual(1, f.fred) + self.assertEqual(2, f.fred) + + def test__setUp_fails(self): + # when _setUp fails, the fixture is left ready-to-setUp, and any + # details added during _setUp are captured. + class Subclass(fixtures.Fixture): + def _setUp(self): + self.addDetail('log', text_content('stuff')) + 1/0 + f = Subclass() + e = self.assertRaises(fixtures.MultipleExceptions, f.setUp) + self.assertRaises(TypeError, f.cleanUp) + self.assertIsInstance(e.args[0][1], ZeroDivisionError) + self.assertIsInstance(e.args[1][1], fixtures.SetupError) + self.assertEqual('stuff', e.args[1][1].args[0]['log'].as_text()) + + def test__setUp_fails_cleanUp_fails(self): + # when _setUp fails, cleanups are called, and their failure is captured + # into the MultipleExceptions instance. + class Subclass(fixtures.Fixture): + def _setUp(self): + self.addDetail('log', text_content('stuff')) + self.addCleanup(lambda: 1/0) + raise Exception('fred') + f = Subclass() + e = self.assertRaises(fixtures.MultipleExceptions, f.setUp) + self.assertRaises(TypeError, f.cleanUp) + self.assertEqual(Exception, e.args[0][0]) + self.assertEqual(ZeroDivisionError, e.args[1][0]) + self.assertEqual(fixtures.SetupError, e.args[2][0]) + self.assertEqual('stuff', e.args[2][1].args[0]['log'].as_text()) + + def test_setup_failures_with_base_exception(self): + # when _setUp fails with a BaseException (or subclass thereof) that + # exception is propogated as is, but we still call cleanups etc. + class MyBase(BaseException):pass + log = [] + class Subclass(fixtures.Fixture): + def _setUp(self): + self.addDetail('log', text_content('stuff')) + self.addCleanup(log.append, 'cleaned') + raise MyBase('fred') + f = Subclass() + e = self.assertRaises(MyBase, f.setUp) + self.assertRaises(TypeError, f.cleanUp) + self.assertEqual(['cleaned'], log) class TestFunctionFixture(testtools.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures.egg-info/PKG-INFO new/fixtures-1.3.1/fixtures.egg-info/PKG-INFO --- old/fixtures-1.2.0/fixtures.egg-info/PKG-INFO 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/fixtures.egg-info/PKG-INFO 2015-06-30 04:22:04.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: fixtures -Version: 1.2.0 +Version: 1.3.1 Summary: Fixtures, reusable state for writing clean tests and more. Home-page: https://launchpad.net/python-fixtures Author: Robert Collins @@ -87,19 +87,20 @@ Creating Fixtures ================= - Minimally, subclass Fixture, define setUp to initialize your state and schedule + Minimally, subclass Fixture, define _setUp to initialize your state and schedule a cleanup for when cleanUp is called and you're done:: >>> import unittest >>> import fixtures >>> class NoddyFixture(fixtures.Fixture): - ... def setUp(self): - ... super(NoddyFixture, self).setUp() + ... def _setUp(self): ... self.frobnozzle = 42 ... self.addCleanup(delattr, self, 'frobnozzle') - This will initialize frobnozzle when setUp is called, and when cleanUp is - called get rid of the frobnozzle attribute. + This will initialize frobnozzle when ``setUp`` is called, and when ``cleanUp`` + is called get rid of the frobnozzle attribute. Prior to version 1.3.0 fixtures + recommended overriding ``setUp``. This is still supported, but since it is + harder to write leak-free fixtures in this fashion, it is not recommended. If your fixture has diagnostic data - for instance the log file of an application server, or log messages, it can expose that by creating a content @@ -107,8 +108,7 @@ >>> from testtools.content import text_content >>> class WithLog(fixtures.Fixture): - ... def setUp(self): - ... super(WithLog, self).setUp() + ... def _setUp(self): ... self.addDetail('message', text_content('foo bar baz')) The method ``useFixture`` will use another fixture, call ``setUp`` on it, call @@ -116,8 +116,7 @@ the fixture. This allows simple composition of different fixtures. >>> class ReusingFixture(fixtures.Fixture): - ... def setUp(self): - ... super(ReusingFixture, self).setUp() + ... def _setUp(self): ... self.noddy = self.useFixture(NoddyFixture()) There is a helper for adapting a function or function pair into Fixtures. it @@ -162,9 +161,9 @@ clean up after a fixture has been used, all fixtures define a ``cleanUp`` method which should be called when a fixture is finished with. - Because its nice to be able to build a particular set of related fixtures in - advance of using them, fixtures also have define a ``setUp`` method which - should be called before trying to use them. + Because it's nice to be able to build a particular set of related fixtures in + advance of using them, fixtures also have a ``setUp`` method which should be + called before trying to use them. One common desire with fixtures that are expensive to create is to reuse them in many test cases; to support this the base Fixture also defines a ``reset`` @@ -211,8 +210,7 @@ >>> import sys >>> from fixtures.fixture import MultipleExceptions >>> class BrokenFixture(fixtures.Fixture): - ... def setUp(self): - ... fixtures.Fixture.setUp(self) + ... def _setUp(self): ... self.addCleanup(lambda:1/0) ... self.addCleanup(lambda:1/0) >>> fixture = BrokenFixture() @@ -226,12 +224,32 @@ Fixtures often expose diagnostic details that can be useful for tracking down issues. The ``getDetails`` method will return a dict of all the attached - details. Each detail object is an instance of ``testtools.content.Content``. + details, but can only be called before ``cleanUp`` is called. Each detail + object is an instance of ``testtools.content.Content``. >>> with WithLog() as l: ... print(l.getDetails()['message'].as_text()) foo bar baz + Errors in setUp + +++++++++++++++ + + The examples above used ``_setUp`` rather than ``setUp`` because the base + class implementation of ``setUp`` acts to reduce the chance of leaking + external resources if an error is raised from ``_setUp``. Specifically, + ``setUp`` contains a try:/except: block which catches all exceptions, captures + any registered detail objects, and calls ``self.cleanUp`` before propogating + the error. As long as you take care to register any cleanups before calling + the code that may fail, this will cause them to be cleaned up. The captured + detail objects are provided to the args of the raised exception. + + If the error that occured was a subclass of ``Exception`` then ``setUp`` will + raise ``MultipleExceptions`` with the last element being a ``SetupError`` that + contains the detail objects. Otherwise, to prevent causing normally + uncatchable errors like KeyboardInterrupt being caught inappropriately in the + calling layer, the original exception will be raised as-is and no diagnostic + data other than that from the original exception will be available. + Shared Dependencies +++++++++++++++++++ @@ -308,7 +326,8 @@ In addition to the Fixture, FunctionFixture and MethodFixture classes fixtures includes a number of precanned fixtures. The API docs for fixtures will list - the complete set of these, should the dcs be out of date or not to hand. + the complete set of these, should the dcs be out of date or not to hand. For + the complete feature set of each fixture please see the API docs. ByteStream ++++++++++ @@ -348,6 +367,34 @@ >>> from testtools.compat import BytesIO >>> fixture = fixtures.FakePopen(lambda _:{'stdout': BytesIO('foobar')}) + MockPatchObject + +++++++++++++++ + + Adapts ``mock.patch.object`` to be used as a Fixture. + + >>> class Fred: + ... value = 1 + >>> fixture = fixtures.MockPatchObject(Fred, 'value', 2) + >>> with fixture: + ... Fred().value + 2 + >>> Fred().value + 1 + + MockPatch + +++++++++ + + Adapts ``mock.patch`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen.returncode', 3) + + MockPatchMultiple + +++++++++++++++++ + + Adapts ``mock.patch.multiple`` to be used as a Fixture. + + >>> fixture = fixtures.MockPatch('subprocess.Popen', returncode=3) + MonkeyPatch +++++++++++ @@ -447,6 +494,13 @@ *Note:* Currently supported only on Unix because it relies on the ``alarm`` system call. + Contributing + ============ + + Fixtures has its project homepage on Launchpad + <https://launchpad.net/python-fixtures>. Source code is hosted on GitHub + <https://github.com/testing-cabal/fixtures>. + Platform: UNKNOWN Classifier: Development Status :: 6 - Mature diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures.egg-info/SOURCES.txt new/fixtures-1.3.1/fixtures.egg-info/SOURCES.txt --- old/fixtures-1.2.0/fixtures.egg-info/SOURCES.txt 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/fixtures.egg-info/SOURCES.txt 2015-06-30 04:22:04.000000000 +0200 @@ -13,6 +13,7 @@ requirements.txt setup.cfg setup.py +test-requirements.txt tox.ini fixtures/__init__.py fixtures/callmany.py @@ -28,6 +29,7 @@ fixtures/_fixtures/__init__.py fixtures/_fixtures/environ.py fixtures/_fixtures/logger.py +fixtures/_fixtures/mockpatch.py fixtures/_fixtures/monkeypatch.py fixtures/_fixtures/packagepath.py fixtures/_fixtures/popen.py @@ -46,6 +48,7 @@ fixtures/tests/_fixtures/__init__.py fixtures/tests/_fixtures/test_environ.py fixtures/tests/_fixtures/test_logger.py +fixtures/tests/_fixtures/test_mockpatch.py fixtures/tests/_fixtures/test_monkeypatch.py fixtures/tests/_fixtures/test_packagepath.py fixtures/tests/_fixtures/test_popen.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures.egg-info/pbr.json new/fixtures-1.3.1/fixtures.egg-info/pbr.json --- old/fixtures-1.2.0/fixtures.egg-info/pbr.json 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/fixtures.egg-info/pbr.json 2015-06-30 04:22:04.000000000 +0200 @@ -1 +1 @@ -{"is_release": true, "git_version": "f7502e8"} \ No newline at end of file +{"is_release": true, "git_version": "09afde5"} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/fixtures.egg-info/requires.txt new/fixtures-1.3.1/fixtures.egg-info/requires.txt --- old/fixtures-1.2.0/fixtures.egg-info/requires.txt 2015-05-05 00:14:19.000000000 +0200 +++ new/fixtures-1.3.1/fixtures.egg-info/requires.txt 2015-06-30 04:22:04.000000000 +0200 @@ -1,2 +1,3 @@ pbr>=0.11 +six testtools>=0.9.22 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/requirements.txt new/fixtures-1.3.1/requirements.txt --- old/fixtures-1.2.0/requirements.txt 2015-05-04 06:04:12.000000000 +0200 +++ new/fixtures-1.3.1/requirements.txt 2015-06-30 02:52:47.000000000 +0200 @@ -1,2 +1,3 @@ pbr>=0.11 +six testtools>=0.9.22 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fixtures-1.2.0/test-requirements.txt new/fixtures-1.3.1/test-requirements.txt --- old/fixtures-1.2.0/test-requirements.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/fixtures-1.3.1/test-requirements.txt 2015-06-22 02:24:03.000000000 +0200 @@ -0,0 +1 @@ +mock;python_version<'3.3'
3383
Age (days ago)
3383
Last active (days ago)
0 comments
1 participants
participants (1)
-
root@hilbert.suse.de