Hello community,

here is the log from the commit of package python-unittest2 for 
openSUSE:Factory checked in at 2015-10-24 10:22:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-unittest2 (Old)
 and      /work/SRC/openSUSE:Factory/.python-unittest2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-unittest2"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-unittest2/python-unittest2.changes        
2014-12-03 22:48:16.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-unittest2.new/python-unittest2.changes   
2015-10-24 10:23:07.000000000 +0200
@@ -1,0 +2,27 @@
+Tue Oct 13 08:52:12 UTC 2015 - [email protected]
+
+- Implement update-alternatives
+
+-------------------------------------------------------------------
+Mon Oct 12 11:10:43 UTC 2015 - [email protected]
+
+- update to version 1.1.0:
+  * Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns()
+    and assertWarnsRegex() assertments now check the type of the first
+    argument to prevent possible user error. Based on patch by Daniel
+    Wagner-Hall.
+  * Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns()
+    and assertWarnsRegex() checks now emits a deprecation warning when
+    callable is None or keyword arguments except msg is passed in the
+    context manager mode.
+  * Issue #22903: The fake test case created by unittest.loader when
+    it fails importing a test module is now picklable.
+- update to version 1.0.1:
+  * Unittest2 issue #94: Need at least 1.4 of six.
+- update to version 1.0.0:
+  * Issue #22936: Permit showing local variables in tracebacks.
+- specfile:
+  * added traceback2, linecache2 requirement
+  * Implement update-alternatives
+
+-------------------------------------------------------------------

Old:
----
  unittest2-0.8.0.tar.gz

New:
----
  unittest2-1.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-unittest2.spec ++++++
--- /var/tmp/diff_new_pack.UUjW5W/_old  2015-10-24 10:23:08.000000000 +0200
+++ /var/tmp/diff_new_pack.UUjW5W/_new  2015-10-24 10:23:08.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-unittest2
-Version:        0.8.0
+Version:        1.1.0
 Release:        0
 Url:            http://pypi.python.org/pypi/unittest2
 Summary:        The new features in unittest for Python 2.7 backported to 
Python 2.3+
@@ -25,19 +25,23 @@
 Group:          Development/Languages/Python
 Source:         
http://pypi.python.org/packages/source/u/unittest2/unittest2-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
-BuildRequires:  python-argparse
 BuildRequires:  python-devel
-BuildRequires:  python-distribute
+BuildRequires:  python-argparse
+BuildRequires:  python-linecache2
+BuildRequires:  python-setuptools
 BuildRequires:  python-six
+BuildRequires:  python-traceback2
 Requires:       python-argparse
+Requires:       python-linecache2
 Requires:       python-six
-%if 0%{?suse_version}
-%py_requires
-%if 0%{?suse_version} > 1110
+Requires:       python-traceback2
+Requires(post): update-alternatives
+Requires(postun): update-alternatives
+%if 0%{?suse_version} &&  0%{?suse_version} > 1110
 BuildArch:      noarch
+%else
+%{!?python_sitelib: %global python_sitelib %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
 %endif
-%endif
-%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib()")}
 
 %description
 unittest2 is a backport of the new features added to the unittest testing
@@ -52,11 +56,29 @@
 %install
 python setup.py install --prefix=%{_prefix} --root=%{buildroot}
 
+# Prepare for update-alternatives usage
+mkdir -p %{buildroot}%{_sysconfdir}/alternatives
+mv %{buildroot}%{_bindir}/unit2 %{buildroot}%{_bindir}/unit2-%{py_ver}
+ln -s -f %{_sysconfdir}/alternatives/unit2 %{buildroot}%{_bindir}/unit2
+# create a dummy target for /etc/alternatives/unit2
+touch %{buildroot}%{_sysconfdir}/alternatives/unit2
+
+%post
+"%_sbindir/update-alternatives" \
+   --install %{_bindir}/unit2 unit2 %{_bindir}/unit2-%{py_ver} 30
+
+%postun
+if [ $1 -eq 0 ] ; then
+    "%_sbindir/update-alternatives" --remove unit2 %{_bindir}/unit2-%{py_ver}
+fi
+
 %files
 %defattr(-,root,root,-)
 %doc README.txt
-%{_bindir}/unit2*
+%{_bindir}/unit2
+%{_bindir}/unit2-%{py_ver}
+%ghost %{_sysconfdir}/alternatives/unit2
 %{python_sitelib}/unittest2
-%{python_sitelib}/unittest2-%{version}-py%{py_ver}.egg-info
+%{python_sitelib}/unittest2-%{version}-py*.egg-info
 
 %changelog

++++++ unittest2-0.8.0.tar.gz -> unittest2-1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/PKG-INFO new/unittest2-1.1.0/PKG-INFO
--- old/unittest2-0.8.0/PKG-INFO        2014-11-04 16:26:25.000000000 +0100
+++ new/unittest2-1.1.0/PKG-INFO        2015-06-30 08:48:20.000000000 +0200
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: unittest2
-Version: 0.8.0
+Version: 1.1.0
 Summary: The new features in unittest backported to Python 2.4+.
 Home-page: http://pypi.python.org/pypi/unittest2
-Author: Michael Foord
-Author-email: [email protected]
+Author: Robert Collins
+Author-email: [email protected]
 License: UNKNOWN
 Description: unittest2 is a backport of the new features added to the unittest 
testing
         framework in Python 2.7 and onwards. It is tested to run on Python 
2.6, 2.7,
@@ -30,8 +30,9 @@
         
         * `Download unittest2 0.5.1 for Python 2.3 
<http://voidspace.org.uk/downloads/unittest2-0.5.1-python2.3.zip>`_
         
-        There is also a version of unittest2 for Python 3. This has the 
project name
-        "unittest2py3k" but uses the same package name ("unittest2"):
+        There was a separate version of unittest2 for Python 3. This is no 
longer
+        needed, but still exists on PyPI. This had the project name 
"unittest2py3k" but
+        uses the same package name ("unittest2"):
         
         * `unittest2 for Python 3 <http://pypi.python.org/pypi/unittest2py3k>`_
         
@@ -43,6 +44,11 @@
         will work with the standard unittest test loaders, runners result 
objects
         however.
         
+        In general for documentation on unittest2 see the current latest 
documented of
+        CPython:
+        
+        * `CPython unittest documentation 
<https://docs.python.org/dev/library/unittest.html>`_
+        
         New features include:
         
         * ``addCleanups`` - better resource management
@@ -169,11 +175,39 @@
         CHANGELOG
         =========
         
+        2015-06-20 - 1.1.0
+        ------------------
+        
+        - Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns() and
+          assertWarnsRegex() assertments now check the type of the first 
argument
+          to prevent possible user error.  Based on patch by Daniel 
Wagner-Hall.
+        
+        - Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
+          assertWarnsRegex() checks now emits a deprecation warning when 
callable is
+          None or keyword arguments except msg is passed in the context 
manager mode.
+        
+        - Issue #22903: The fake test case created by unittest.loader when it 
fails
+          importing a test module is now picklable.
+        
+        
+        2015-03-12 - 1.0.1
+        ------------------
+        
+        - Unittest2 issue #94: Need at least 1.4 of six.
+        
+        2015-03-06 - 1.0.0
+        ------------------
+        
+        - Issue #22936: Permit showing local variables in tracebacks.
+        
         2014/11/05 - 0.8
         ----------------
         
         - Issue #22457: Honour load_tests in the start_dir of discovery.
         
+        - Issue #22894: TestCase.subTest() would cause the test suite to be 
stopped
+          when in failfast mode, even in the absence of failures.
+        
         2014/10/31 - 0.7.1
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/README.txt 
new/unittest2-1.1.0/README.txt
--- old/unittest2-0.8.0/README.txt      2014-11-04 16:25:37.000000000 +0100
+++ new/unittest2-1.1.0/README.txt      2015-06-30 05:20:46.000000000 +0200
@@ -22,8 +22,9 @@
 
 * `Download unittest2 0.5.1 for Python 2.3 
<http://voidspace.org.uk/downloads/unittest2-0.5.1-python2.3.zip>`_
 
-There is also a version of unittest2 for Python 3. This has the project name
-"unittest2py3k" but uses the same package name ("unittest2"):
+There was a separate version of unittest2 for Python 3. This is no longer
+needed, but still exists on PyPI. This had the project name "unittest2py3k" but
+uses the same package name ("unittest2"):
 
 * `unittest2 for Python 3 <http://pypi.python.org/pypi/unittest2py3k>`_
 
@@ -35,6 +36,11 @@
 will work with the standard unittest test loaders, runners result objects
 however.
 
+In general for documentation on unittest2 see the current latest documented of
+CPython:
+
+* `CPython unittest documentation 
<https://docs.python.org/dev/library/unittest.html>`_
+
 New features include:
 
 * ``addCleanups`` - better resource management
@@ -161,11 +167,39 @@
 CHANGELOG
 =========
 
+2015-06-20 - 1.1.0
+------------------
+
+- Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns() and
+  assertWarnsRegex() assertments now check the type of the first argument
+  to prevent possible user error.  Based on patch by Daniel Wagner-Hall.
+
+- Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
+  assertWarnsRegex() checks now emits a deprecation warning when callable is
+  None or keyword arguments except msg is passed in the context manager mode.
+
+- Issue #22903: The fake test case created by unittest.loader when it fails
+  importing a test module is now picklable.
+
+
+2015-03-12 - 1.0.1
+------------------
+
+- Unittest2 issue #94: Need at least 1.4 of six.
+
+2015-03-06 - 1.0.0
+------------------
+
+- Issue #22936: Permit showing local variables in tracebacks.
+
 2014/11/05 - 0.8
 ----------------
 
 - Issue #22457: Honour load_tests in the start_dir of discovery.
 
+- Issue #22894: TestCase.subTest() would cause the test suite to be stopped
+  when in failfast mode, even in the absence of failures.
+
 2014/10/31 - 0.7.1
 ------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/setup.cfg 
new/unittest2-1.1.0/setup.cfg
--- old/unittest2-0.8.0/setup.cfg       2014-11-04 16:26:26.000000000 +0100
+++ new/unittest2-1.1.0/setup.cfg       2015-06-30 08:48:20.000000000 +0200
@@ -1,6 +1,9 @@
 [sdist]
 force-manifest = 1
 
+[bdist_wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/setup.py new/unittest2-1.1.0/setup.py
--- old/unittest2-0.8.0/setup.py        2014-11-04 15:51:22.000000000 +0100
+++ new/unittest2-1.1.0/setup.py        2015-06-30 08:47:44.000000000 +0200
@@ -48,16 +48,16 @@
     'Topic :: Software Development :: Testing',
 ]
 
-AUTHOR = 'Michael Foord'
+AUTHOR = 'Robert Collins'
 
-AUTHOR_EMAIL = '[email protected]'
+AUTHOR_EMAIL = '[email protected]'
 
 KEYWORDS = "unittest testing tests".split(' ')
 
 # Both install and setup requires - because we read VERSION from within the
 # package, and the package also exports all the APIs.
 # six for compat helpers
-REQUIRES = ['argparse', 'six'],
+REQUIRES = ['argparse', 'six>=1.4', 'traceback2'],
 
 params = dict(
     name=NAME,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/__init__.py 
new/unittest2-1.1.0/unittest2/__init__.py
--- old/unittest2-0.8.0/unittest2/__init__.py   2014-11-04 16:25:51.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/__init__.py   2015-06-30 08:47:26.000000000 
+0200
@@ -31,7 +31,7 @@
            'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
            'expectedFailure', 'TextTestResult', '__version__', 'collector']
 
-__version__ = '0.8.0'
+__version__ = '1.1.0'
 
 # Expose obsolete functions for backwards compatibility
 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
@@ -75,13 +75,3 @@
     return loader.discover(start_dir=this_dir, pattern=pattern)
 
 __unittest = True
-
-def load_tests(loader, tests, pattern):
-    # All our tests are in test/ - the test objects found in unittest2 itself
-    # are base classes not intended to be executed. This load_tests intercepts
-    # discovery to prevent that.
-    import unittest2.test
-    result = loader.suiteClass()
-    for path in unittest2.test.__path__:
-        result.addTests(loader.discover(path, pattern=pattern))
-    return result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/case.py 
new/unittest2-1.1.0/unittest2/case.py
--- old/unittest2-0.8.0/unittest2/case.py       2014-10-30 21:57:36.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/case.py       2015-06-30 08:17:28.000000000 
+0200
@@ -7,7 +7,7 @@
 import logging
 import pprint
 import re
-import traceback
+import traceback2 as traceback
 import types
 import unittest
 import warnings
@@ -135,6 +135,10 @@
     test_item.__unittest_expecting_failure__ = True
     return test_item
 
+def _is_subtype(expected, basetype):
+    if isinstance(expected, tuple):
+        return all(_is_subtype(e, basetype) for e in expected)
+    return isinstance(expected, type) and issubclass(expected, basetype)
 
 class _BaseTestCaseContext:
 
@@ -148,32 +152,44 @@
 
 class _AssertRaisesBaseContext(_BaseTestCaseContext):
 
-    def __init__(self, expected, test_case, callable_obj=None,
-                 expected_regex=None):
+    def __init__(self, expected, test_case, expected_regex=None):
         _BaseTestCaseContext.__init__(self, test_case)
         self.expected = expected
         self.failureException = test_case.failureException
-        if callable_obj is not None:
-            try:
-                self.obj_name = callable_obj.__name__
-            except AttributeError:
-                self.obj_name = str(callable_obj)
-        else:
-            self.obj_name = None
         if expected_regex is not None:
             expected_regex = re.compile(expected_regex)
         self.expected_regex = expected_regex
+        self.obj_name = None
         self.msg = None
 
-    def handle(self, name, callable_obj, args, kwargs):
+    def handle(self, name, args, kwargs):
         """
-        If callable_obj is None, assertRaises/Warns is being used as a
+        If args is empty, assertRaises/Warns is being used as a
         context manager, so check for a 'msg' kwarg and return self.
-        If callable_obj is not None, call it passing args and kwargs.
+        If args is not empty, call a callable passing positional and keyword
+        arguments.
         """
-        if callable_obj is None:
+        if not _is_subtype(self.expected, self._base_type):
+            raise TypeError('%s() arg 1 must be %s' %
+                            (name, self._base_type_str))
+        if args and args[0] is None:
+            warnings.warn("callable is None",
+                          DeprecationWarning, 3)
+            args = ()
+        if not args:
             self.msg = kwargs.pop('msg', None)
+            if kwargs:
+                warnings.warn('%r is an invalid keyword argument for '
+                              'this function' % next(iter(kwargs)),
+                              DeprecationWarning, 3)
             return self
+
+        callable_obj = args[0]
+        args = args[1:]
+        try:
+            self.obj_name = callable_obj.__name__
+        except AttributeError:
+            self.obj_name = str(callable_obj)
         with self:
             callable_obj(*args, **kwargs)
 
@@ -181,6 +197,9 @@
 class _AssertRaisesContext(_AssertRaisesBaseContext):
     """A context manager used to implement TestCase.assertRaises* methods."""
 
+    _base_type = BaseException
+    _base_type_str = 'an exception type or tuple of exception types'
+
     def __enter__(self):
         return self
 
@@ -190,11 +209,13 @@
                 exc_name = self.expected.__name__
             except AttributeError:
                 exc_name = str(self.expected)
-            raise self.failureException(
-                "%s not raised" % (exc_name,))
-        #else:
-        #    if getattr(traceback, 'clear_frames', None):
-        #        traceback.clear_frames(tb)
+            if self.obj_name:
+                self._raiseFailure("{0} not raised by {1}".format(exc_name,
+                                                                  
self.obj_name))
+            else:
+                self._raiseFailure("{0} not raised".format(exc_name))
+        else:
+            traceback.clear_frames(tb)
         if not issubclass(exc_type, self.expected):
             # let unexpected exceptions pass through
             return False
@@ -212,6 +233,9 @@
 class _AssertWarnsContext(_AssertRaisesBaseContext):
     """A context manager used to implement TestCase.assertWarns* methods."""
 
+    _base_type = Warning
+    _base_type_str = 'a warning type or tuple of warning types'
+
     def __enter__(self):
         # The __warningregistry__'s need to be in a pristine state for tests
         # to work properly.
@@ -697,15 +721,15 @@
             return '%s : %s' % (safe_str(standardMsg), safe_str(msg))
 
 
-    def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
-        """Fail unless an exception of class excClass is raised
-           by callableObj when invoked with arguments args and keyword
-           arguments kwargs. If a different type of exception is
+    def assertRaises(self, expected_exception, *args, **kwargs):
+        """Fail unless an exception of class expected_exception is raised
+           by the callable when invoked with specified positional and
+           keyword arguments. If a different type of exception is
            raised, it will not be caught, and the test case will be
            deemed to have suffered an error, exactly as for an
            unexpected exception.
 
-           If called with callableObj omitted or None, will return a
+           If called with the callable and arguments omitted, will return a
            context object used like this::
 
                 with self.assertRaises(SomeException):
@@ -720,28 +744,18 @@
                the_exception = cm.exception
                self.assertEqual(the_exception.error_code, 3)
         """
-        if callableObj is None:
-            return _AssertRaisesContext(excClass, self)
-        try:
-            callableObj(*args, **kwargs)
-        except excClass:
-            return
-
-        if hasattr(excClass,'__name__'):
-            excName = excClass.__name__
-        else:
-            excName = str(excClass)
-        raise self.failureException("%s not raised" % excName)
+        context = _AssertRaisesContext(expected_exception, self)
+        return context.handle('assertRaises', args, kwargs)
 
-    def assertWarns(self, expected_warning, callable_obj=None, *args, 
**kwargs):
+    def assertWarns(self, expected_warning, *args, **kwargs):
         """Fail unless a warning of class warnClass is triggered
-           by callableObj when invoked with arguments args and keyword
-           arguments kwargs.  If a different type of warning is
+           by the callable when invoked with specified positional and
+           keyword arguments.  If a different type of warning is
            triggered, it will not be handled: depending on the other
            warning filtering rules in effect, it might be silenced, printed
            out, or raised as an exception.
 
-           If called with callableObj omitted or None, will return a
+           If called with the callable and arguments omitted, will return a
            context object used like this::
 
                 with self.assertWarns(SomeWarning):
@@ -749,7 +763,7 @@
 
            The context manager keeps a reference to the first matching
            warning as the 'warning' attribute; similarly, the 'filename'
-          and 'lineno' attributes give you information about the line
+           and 'lineno' attributes give you information about the line
            of Python code from which the warning was triggered.
            This allows you to inspect the warning after the assertion::
 
@@ -758,19 +772,8 @@
                the_warning = cm.warning
                self.assertEqual(the_warning.some_attribute, 147)
         """
-        context = _AssertWarnsContext(expected_warning, self, callable_obj)
-        if callable_obj is None:
-            return context
-        context.__enter__()
-        try:
-            callable_obj(*args, **kwargs)
-        except:
-            if not context.__exit__(*sys.exc_info()):
-                raise
-            else:
-                return
-        else:
-            context.__exit__(None, None, None)
+        context = _AssertWarnsContext(expected_warning, self)
+        return context.handle('assertWarns', args, kwargs)
 
     def assertLogs(self, logger=None, level=None):
         """Fail unless a log message of level *level* or higher is emitted
@@ -1261,23 +1264,21 @@
             self.fail(self._formatMessage(msg, standardMsg))
 
     def assertRaisesRegex(self, expected_exception, expected_regex,
-                          callable_obj=None, *args, **kwargs):
+                          *args, **kwargs):
         """Asserts that the message in a raised exception matches a regex.
 
         Args:
             expected_exception: Exception class expected to be raised.
             expected_regex: Regex (re pattern object or string) expected
                     to be found in error message.
-            callable_obj: Function to be called.
-            args: Extra args.
+            args: Function to be called and extra positional args.
             kwargs: Extra kwargs.
         """
-        context = _AssertRaisesContext(expected_exception, self, callable_obj,
-                                       expected_regex)
-        return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
+        context = _AssertRaisesContext(expected_exception, self, 
expected_regex)
+        return context.handle('assertRaisesRegex', args, kwargs)
 
     def assertWarnsRegex(self, expected_warning, expected_regex,
-                         callable_obj=None, *args, **kwargs):
+                         *args, **kwargs):
         """Asserts that the message in a triggered warning matches a regex.
         Basic functioning is similar to assertWarns() with the addition
         that only warnings whose messages also match the regular expression
@@ -1287,14 +1288,11 @@
             expected_warning: Warning class expected to be triggered.
             expected_regex: Regex (re pattern object or string) expected
                     to be found in error message.
-            callable_obj: Function to be called.
-            args: Extra args.
+            args: Function to be called and extra positional args.
             kwargs: Extra kwargs.
         """
-        context = _AssertWarnsContext(expected_warning, self, callable_obj,
-                                      expected_regex)
-        return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
-
+        context = _AssertWarnsContext(expected_warning, self, expected_regex)
+        return context.handle('assertWarnsRegex', args, kwargs)
 
     def assertRegex(self, text, expected_regex, msg=None):
         """Fail the test unless the text matches the regular expression."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/loader.py 
new/unittest2-1.1.0/unittest2/loader.py
--- old/unittest2-0.8.0/unittest2/loader.py     2014-11-04 15:32:19.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/loader.py     2015-06-29 12:04:21.000000000 
+0200
@@ -31,29 +31,40 @@
     return K
 
 
-# what about .pyc or .pyo (etc)
+# what about .pyc (etc)
 # we would need to avoid loading the same tests multiple times
-# from '.py', '.pyc' *and* '.pyo'
+# from '.py', *and* '.pyc'
 VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE)
 
 
+class _FailedTest(case.TestCase):
+    _testMethodName = None
+
+    def __init__(self, method_name, exception):
+        self._exception = exception
+        super(_FailedTest, self).__init__(method_name)
+
+    def __getattr__(self, name):
+        if name != self._testMethodName:
+            return super(_FailedTest, self).__getattr__(name)
+        def testFailure():
+            raise self._exception
+        return testFailure
+
+
 def _make_failed_import_test(name, suiteClass):
     message = 'Failed to import test module: %s\n%s' % (
         name, traceback.format_exc())
-    return _make_failed_test('ModuleImportFailure', name, ImportError(message),
-                             suiteClass, message)
+    return _make_failed_test(name, ImportError(message), suiteClass, message)
 
 def _make_failed_load_tests(name, exception, suiteClass):
     message = 'Failed to call load_tests:\n%s' % (traceback.format_exc(),)
     return _make_failed_test(
-        'LoadTestsFailure', name, exception, suiteClass, message)
+        name, exception, suiteClass, message)
 
-def _make_failed_test(classname, methodname, exception, suiteClass, message):
-    def testFailure(self):
-        raise exception
-    attrs = {methodname: testFailure}
-    TestClass = type(classname, (case.TestCase,), attrs)
-    return suiteClass((TestClass(methodname),)), message
+def _make_failed_test(methodname, exception, suiteClass, message):
+    test = _FailedTest(methodname, exception)
+    return suiteClass((test,)), message
 
 
 def _make_skipped_test(methodname, exception, suiteClass):
@@ -188,7 +199,7 @@
                 else:
                     # Otherwise, we signal that an AttributeError has occurred.
                     error_case, error_message = _make_failed_test(
-                        'AttributeError', part, e, self.suiteClass,
+                        part, e, self.suiteClass,
                         'Failed to access attribute:\n%s' % (
                             traceback.format_exc(),))
                     self.errors.append(error_message)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/main.py 
new/unittest2-1.1.0/unittest2/main.py
--- old/unittest2-0.8.0/unittest2/main.py       2014-10-31 07:25:15.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/main.py       2015-03-06 05:59:33.000000000 
+0100
@@ -65,7 +65,8 @@
     def __init__(self, module='__main__', defaultTest=None,
                  argv=None, testRunner=None,
                  testLoader=loader.defaultTestLoader, exit=True,
-                 verbosity=1, failfast=None, catchbreak=None, buffer=None):
+                 verbosity=1, failfast=None, catchbreak=None, buffer=None,
+                 tb_locals=False):
         if isinstance(module, six.string_types):
             self.module = __import__(module)
             for part in module.split('.')[1:]:
@@ -80,6 +81,7 @@
         self.failfast = failfast
         self.catchbreak = catchbreak
         self.buffer = buffer
+        self.tb_locals = tb_locals
         self.defaultTest = defaultTest
         self.testRunner = testRunner
         self.testLoader = testLoader
@@ -153,7 +155,9 @@
         parser.add_argument('-q', '--quiet', dest='verbosity',
                             action='store_const', const=0,
                             help='Quiet output')
-
+        parser.add_argument('--locals', dest='tb_locals',
+                            action='store_true',
+                            help='Show local variables in tracebacks')
         if self.failfast is None:
             parser.add_argument('-f', '--failfast', dest='failfast',
                                 action='store_true',
@@ -225,9 +229,16 @@
             self.testRunner = runner.TextTestRunner
         if isinstance(self.testRunner, six.class_types):
             try:
-                testRunner = self.testRunner(verbosity=self.verbosity,
-                                             failfast=self.failfast,
-                                             buffer=self.buffer)
+                try:
+                    testRunner = self.testRunner(verbosity=self.verbosity,
+                                                 failfast=self.failfast,
+                                                 buffer=self.buffer,
+                                                 tb_locals=self.tb_locals)
+                except TypeError:
+                    # didn't accept the tb_locals argument
+                    testRunner = self.testRunner(verbosity=self.verbosity,
+                                                 failfast=self.failfast,
+                                                 buffer=self.buffer)
             except TypeError:
                 # didn't accept the verbosity, buffer or failfast arguments
                 testRunner = self.testRunner()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/result.py 
new/unittest2-1.1.0/unittest2/result.py
--- old/unittest2-0.8.0/unittest2/result.py     2014-10-29 02:38:35.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/result.py     2015-03-06 06:17:01.000000000 
+0100
@@ -1,10 +1,10 @@
 """Test result object"""
 
 import sys
-import traceback
 import unittest
 
 from six.moves import StringIO
+import traceback2 as traceback
 
 from unittest2 import util
 from unittest2.compatibility import wraps
@@ -47,6 +47,7 @@
         self.unexpectedSuccesses = []
         self.shouldStop = False
         self.buffer = False
+        self.tb_locals = False
         self._stdout_buffer = None
         self._stderr_buffer = None
         self._original_stdout = sys.stdout
@@ -115,7 +116,6 @@
         self.failures.append((test, self._exc_info_to_string(err, test)))
         self._mirrorOutput = True
 
-    @failfast
     def addSubTest(self, test, subtest, err):
         """Called at the end of a subtest.
         'err' is None if the subtest ended successfully, otherwise it's a
@@ -124,6 +124,8 @@
         # By default, we don't do anything with successful subtests, but
         # more sophisticated test results might want to record them.
         if err is not None:
+            if getattr(self, 'failfast', False):
+                self.stop()
             if issubclass(err[0], test.failureException):
                 errors = self.failures
             else:
@@ -171,9 +173,11 @@
         if exctype is test.failureException:
             # Skip assert*() traceback levels
             length = self._count_relevant_tb_levels(tb)
-            msgLines = traceback.format_exception(exctype, value, tb, length)
         else:
-            msgLines = traceback.format_exception(exctype, value, tb)
+            length = None
+        tb_e = traceback.TracebackException(
+            exctype, value, tb, limit=length, capture_locals=self.tb_locals)
+        msgLines = list(tb_e.format())
 
         if self.buffer:
             output = sys.stdout.getvalue()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/runner.py 
new/unittest2-1.1.0/unittest2/runner.py
--- old/unittest2-0.8.0/unittest2/runner.py     2014-10-28 08:43:01.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/runner.py     2015-03-06 06:22:55.000000000 
+0100
@@ -4,6 +4,8 @@
 import time
 import unittest
 
+from six import u
+
 from unittest2 import result
 
 try:
@@ -28,7 +30,7 @@
     def writeln(self, arg=None):
         if arg:
             self.write(arg)
-        self.write('\n') # text-mode streams translate to \r\n if needed
+        self.write(u('\n')) # text-mode streams translate to \r\n if needed
 
 
 class TextTestResult(result.TestResult):
@@ -36,8 +38,8 @@
 
     Used by TextTestRunner.
     """
-    separator1 = '=' * 70
-    separator2 = '-' * 70
+    separator1 = u('=' * 70)
+    separator2 = u('-' * 70)
 
     def __init__(self, stream, descriptions, verbosity):
         super(TextTestResult, self).__init__(stream, descriptions, verbosity)
@@ -135,12 +137,19 @@
     resultclass = TextTestResult
 
     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
-                    failfast=False, buffer=False, resultclass=None):
+                 failfast=False, buffer=False, resultclass=None,
+                 tb_locals=False):
+        """Construct a TextTestRunner.
+
+        Subclasses should accept **kwargs to ensure compatibility as the
+        interface changes.
+        """
         self.stream = _WritelnDecorator(stream)
         self.descriptions = descriptions
         self.verbosity = verbosity
         self.failfast = failfast
         self.buffer = buffer
+        self.tb_locals = tb_locals
         if resultclass is not None:
             self.resultclass = resultclass
 
@@ -152,6 +161,7 @@
         result = self._makeResult()
         result.failfast = self.failfast
         result.buffer = self.buffer
+        result.tb_locals = self.tb_locals
         registerResult(result)
 
         startTime = time.time()
@@ -171,7 +181,7 @@
         if hasattr(result, 'separator2'):
             self.stream.writeln(result.separator2)
         run = result.testsRun
-        self.stream.writeln("Ran %d test%s in %.3fs" %
+        self.stream.writeln(u("Ran %d test%s in %.3fs") %
                             (run, run != 1 and "s" or "", timeTaken))
         self.stream.writeln()
 
@@ -186,22 +196,22 @@
             expectedFails, unexpectedSuccesses, skipped = results
         infos = []
         if not result.wasSuccessful():
-            self.stream.write("FAILED")
+            self.stream.write(u("FAILED"))
             failed, errored = map(len, (result.failures, result.errors))
             if failed:
-                infos.append("failures=%d" % failed)
+                infos.append(u("failures=%d") % failed)
             if errored:
-                infos.append("errors=%d" % errored)
+                infos.append(u("errors=%d") % errored)
         else:
-            self.stream.write("OK")
+            self.stream.write(u("OK"))
         if skipped:
-            infos.append("skipped=%d" % skipped)
+            infos.append(u("skipped=%d") % skipped)
         if expectedFails:
-            infos.append("expected failures=%d" % expectedFails)
+            infos.append(u("expected failures=%d") % expectedFails)
         if unexpectedSuccesses:
-            infos.append("unexpected successes=%d" % unexpectedSuccesses)
+            infos.append(u("unexpected successes=%d") % unexpectedSuccesses)
         if infos:
-            self.stream.writeln(" (%s)" % (", ".join(infos),))
+            self.stream.writeln(u(" (%s)") % (u(", ").join(infos),))
         else:
-            self.stream.write("\n")
+            self.stream.write(u("\n"))
         return result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/unittest2-0.8.0/unittest2/test/_test_unittest2_with.py 
new/unittest2-1.1.0/unittest2/test/_test_unittest2_with.py
--- old/unittest2-0.8.0/unittest2/test/_test_unittest2_with.py  2014-10-22 
00:51:22.000000000 +0200
+++ new/unittest2-1.1.0/unittest2/test/_test_unittest2_with.py  2015-06-29 
12:23:32.000000000 +0200
@@ -45,7 +45,7 @@
             self.assertRaises(KeyError, lambda: None)
         except self.failureException:
             e = sys.exc_info()[1]
-            self.assertIn("KeyError not raised", e.args)
+            self.assertIn("KeyError not raised by <lambda>", e.args)
         else:
             self.fail("assertRaises() didn't fail")
         try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/support.py 
new/unittest2-1.1.0/unittest2/test/support.py
--- old/unittest2-0.8.0/unittest2/test/support.py       2014-10-29 
11:38:26.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/support.py       2015-06-29 
12:24:31.000000000 +0200
@@ -135,8 +135,6 @@
             try:
                 if not hash(obj_1) == hash(obj_2):
                     self.fail("%r and %r do not hash equal" % (obj_1, obj_2))
-            except KeyboardInterrupt:
-                raise
             except Exception:
                 e = sys.exc_info()[1]
                 self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e))
@@ -146,8 +144,6 @@
                 if hash(obj_1) == hash(obj_2):
                     self.fail("%s and %s hash equal, but shouldn't" %
                               (obj_1, obj_2))
-            except KeyboardInterrupt:
-                raise
             except Exception:
                 e = sys.exc_info()[1]
                 self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_assertions.py 
new/unittest2-1.1.0/unittest2/test/test_assertions.py
--- old/unittest2-0.8.0/unittest2/test/test_assertions.py       2014-10-31 
00:48:15.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_assertions.py       2015-06-30 
08:19:24.000000000 +0200
@@ -75,6 +75,10 @@
         getattr(sys, 'pypy_version_info', None),
         "pypy doesn't use refcounting."
         )
+    @unittest.skipIf(
+        sys.version_info[:2] in ((3, 2), (3, 3)),
+        "python 3.2 and 3.3 always leak."
+        )
     def test_assertRaises_frames_survival(self):
         # Issue #9815: assertRaises should avoid keeping local variables
         # in a traceback alive.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_break.py 
new/unittest2-1.1.0/unittest2/test/test_break.py
--- old/unittest2-0.8.0/unittest2/test/test_break.py    2014-10-28 
23:54:40.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_break.py    2015-03-06 
06:01:36.000000000 +0100
@@ -213,6 +213,7 @@
                 self.verbosity = verbosity
                 self.failfast = failfast
                 self.catchbreak = catchbreak
+                self.tb_locals = False
                 self.testRunner = FakeRunner
                 self.test = test
                 self.result = None
@@ -221,8 +222,9 @@
         p.runTests()
 
         self.assertEqual(FakeRunner.initArgs, [((), {'verbosity': verbosity,
-                                                'failfast': failfast,
-                                                'buffer': None})])
+                                                     'failfast': failfast,
+                                                     'tb_locals': False,
+                                                     'buffer': None})])
         self.assertEqual(FakeRunner.runArgs, [test])
         self.assertEqual(p.result, result)
 
@@ -234,8 +236,9 @@
         p.runTests()
 
         self.assertEqual(FakeRunner.initArgs, [((), {'verbosity': verbosity,
-                                                'failfast': failfast,
-                                                'buffer': None})])
+                                                     'failfast': failfast,
+                                                     'tb_locals': False,
+                                                     'buffer': None})])
         self.assertEqual(FakeRunner.runArgs, [test])
         self.assertEqual(p.result, result)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_case.py 
new/unittest2-1.1.0/unittest2/test/test_case.py
--- old/unittest2-0.8.0/unittest2/test/test_case.py     2014-10-30 
10:54:05.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_case.py     2015-06-29 
12:29:49.000000000 +0200
@@ -391,6 +391,34 @@
         Foo(events).run(result)
         self.assertEqual(events, expected)
 
+    def test_subtests_failfast(self):
+        # Ensure proper test flow with subtests and failfast (issue #22894)
+        events = []
+
+        class Foo(unittest.TestCase):
+            def test_a(self):
+                with self.subTest():
+                    events.append('a1')
+                events.append('a2')
+
+            def test_b(self):
+                with self.subTest():
+                    events.append('b1')
+                with self.subTest():
+                    self.fail('failure')
+                events.append('b2')
+
+            def test_c(self):
+                events.append('c')
+
+        result = unittest.TestResult()
+        result.failfast = True
+        suite = unittest.makeSuite(Foo)
+        suite.run(result)
+
+        expected = ['a1', 'a2', 'b1']
+        self.assertEqual(events, expected)
+
     # "This class attribute gives the exception raised by the test() method.
     # If a test framework needs to use a specialized exception, possibly to
     # carry additional information, it must subclass this exception in
@@ -1024,6 +1052,71 @@
         self.assertRaises(self.failureException, self.assertRegex,
                           'saaas', r'aaaa')
 
+    def testAssertRaisesCallable(self):
+        class ExceptionMock(Exception):
+            pass
+        def Stub():
+            raise ExceptionMock('We expect')
+        self.assertRaises(ExceptionMock, Stub)
+        # A tuple of exception classes is accepted
+        self.assertRaises((ValueError, ExceptionMock), Stub)
+        # *args and **kwargs also work
+        self.assertRaises(ValueError, int, '19', base=8)
+        # Failure when no exception is raised
+        with self.assertRaises(self.failureException):
+            self.assertRaises(ExceptionMock, lambda: 0)
+        # Failure when the function is None
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(ExceptionMock, None)
+        # Failure when another exception is raised
+        with self.assertRaises(ExceptionMock):
+            self.assertRaises(ValueError, Stub)
+
+    def testAssertRaisesContext(self):
+        class ExceptionMock(Exception):
+            pass
+        def Stub():
+            raise ExceptionMock('We expect')
+        with self.assertRaises(ExceptionMock):
+            Stub()
+        # A tuple of exception classes is accepted
+        with self.assertRaises((ValueError, ExceptionMock)) as cm:
+            Stub()
+        # The context manager exposes caught exception
+        self.assertIsInstance(cm.exception, ExceptionMock)
+        self.assertEqual(cm.exception.args[0], 'We expect')
+        # *args and **kwargs also work
+        with self.assertRaises(ValueError):
+            int('19', base=8)
+        # Failure when no exception is raised
+        with self.assertRaises(self.failureException):
+            with self.assertRaises(ExceptionMock):
+                pass
+        # Custom message
+        with self.assertRaisesRegex(self.failureException, 'foobar'):
+            with self.assertRaises(ExceptionMock, msg='foobar'):
+                pass
+        # Invalid keyword argument
+        with self.assertWarnsRegex(DeprecationWarning, 'foobar'):
+            with self.assertRaises(AssertionError):
+                with self.assertRaises(ExceptionMock, foobar=42):
+                    pass
+        # Failure when another exception is raised
+        with self.assertRaises(ExceptionMock):
+            self.assertRaises(ValueError, Stub)
+
+    def testAssertRaisesNoExceptionType(self):
+        with self.assertRaises(TypeError):
+            self.assertRaises()
+        with self.assertRaises(TypeError):
+            self.assertRaises(1)
+        with self.assertRaises(TypeError):
+            self.assertRaises(object)
+        with self.assertRaises(TypeError):
+            self.assertRaises((ValueError, 1))
+        with self.assertRaises(TypeError):
+            self.assertRaises((ValueError, object))
+
     def testAssertRaisesRegex(self):
         class ExceptionMock(Exception):
             pass
@@ -1034,20 +1127,27 @@
         self.assertRaisesRegex(ExceptionMock, re.compile('expect$'), Stub)
         self.assertRaisesRegex(ExceptionMock, 'expect$', Stub)
         self.assertRaisesRegex(ExceptionMock, u('expect$'), Stub)
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaisesRegex(ExceptionMock, 'expect$', None)
 
     def testAssertNotRaisesRegex(self):
         self.assertRaisesRegex(
-                self.failureException, '^Exception not raised$',
+                self.failureException, '^Exception not raised by <lambda>$',
                 self.assertRaisesRegex, Exception, re.compile('x'),
                 lambda: None)
         self.assertRaisesRegex(
-                self.failureException, '^Exception not raised$',
+                self.failureException, '^Exception not raised by <lambda>$',
                 self.assertRaisesRegex, Exception, 'x',
                 lambda: None)
-        self.assertRaisesRegex(
-                self.failureException, '^Exception not raised$',
-                self.assertRaisesRegex, Exception, u('x'),
-                lambda: None)
+        # Custom message
+        with self.assertRaisesRegex(self.failureException, 'foobar'):
+            with self.assertRaisesRegex(Exception, 'expect', msg='foobar'):
+                pass
+        # Invalid keyword argument
+        with self.assertWarnsRegex(DeprecationWarning, 'foobar'):
+            with self.assertRaises(AssertionError):
+                with self.assertRaisesRegex(Exception, 'expect', foobar=42):
+                    pass
 
     def testAssertRaisesRegexInvalidRegex(self):
         # Issue 20145.
@@ -1093,6 +1193,50 @@
                 self.assertRaisesRegex, Exception,
                 re.compile('^Expected$'), Stub)
 
+    def testAssertRaisesRegexNoExceptionType(self):
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex()
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex(ValueError)
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex(1, 'expect')
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex(object, 'expect')
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex((ValueError, 1), 'expect')
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex((ValueError, object), 'expect')
+
+    def testAssertWarnsNoExceptionType(self):
+        with self.assertRaises(TypeError):
+            self.assertWarns()
+        with self.assertRaises(TypeError):
+            self.assertWarns(1)
+        with self.assertRaises(TypeError):
+            self.assertWarns(object)
+        with self.assertRaises(TypeError):
+            self.assertWarns((UserWarning, 1))
+        with self.assertRaises(TypeError):
+            self.assertWarns((UserWarning, object))
+        with self.assertRaises(TypeError):
+            self.assertWarns((UserWarning, Exception))
+
+    def testAssertWarnsRegexNoExceptionType(self):
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex()
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex(UserWarning)
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex(1, 'expect')
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex(object, 'expect')
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex((UserWarning, 1), 'expect')
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex((UserWarning, object), 'expect')
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex((UserWarning, Exception), 'expect')
+
     @contextlib.contextmanager
     def assertNoStderr(self):
         with captured_stderr() as buf:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_discovery.py 
new/unittest2-1.1.0/unittest2/test/test_discovery.py
--- old/unittest2-0.8.0/unittest2/test/test_discovery.py        2014-11-04 
15:11:54.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_discovery.py        2015-06-29 
06:17:45.000000000 +0200
@@ -3,6 +3,7 @@
 import re
 import sys
 import types
+import pickle
 try:
     import builtins
 except ImportError:
@@ -491,6 +492,10 @@
             test.my_package()
         self.assertEqual(import_calls, ['my_package'])
 
+        # Check picklability
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            pickle.loads(pickle.dumps(test, proto))
+
     def test_discover_with_module_that_raises_SkipTest_on_import(self):
         loader = unittest.TestLoader()
 
@@ -527,6 +532,10 @@
         self.assertEqual(result.testsRun, 1)
         self.assertEqual(import_calls, ['my_package'])
 
+        # Check picklability
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            pickle.loads(pickle.dumps(suite, proto))
+
     def test_command_line_handling_parseArgs(self):
         # Haha - take that uninstantiable class
         program = TestableTestProgram()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_program.py 
new/unittest2-1.1.0/unittest2/test/test_program.py
--- old/unittest2-0.8.0/unittest2/test/test_program.py  2014-10-29 
11:50:49.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_program.py  2015-03-06 
06:13:56.000000000 +0100
@@ -118,6 +118,7 @@
     result = None
     verbosity = 1
     defaultTest = None
+    tb_locals = False
     testRunner = None
     testLoader = unittest2.defaultTestLoader
     progName = 'test'
@@ -130,18 +131,19 @@
 class FakeRunner(object):
     initArgs = None
     test = None
-    raiseError = False
+    raiseError = 0
 
     def __init__(self, **kwargs):
         FakeRunner.initArgs = kwargs
         if FakeRunner.raiseError:
-            FakeRunner.raiseError = False
+            FakeRunner.raiseError -= 1
             raise TypeError
 
     def run(self, test):
         FakeRunner.test = test
         return RESULT
 
+
 class TestCommandLineArgs(unittest2.TestCase):
 
     def setUp(self):
@@ -149,7 +151,7 @@
         self.program.createTests = lambda: None
         FakeRunner.initArgs = None
         FakeRunner.test = None
-        FakeRunner.raiseError = False
+        FakeRunner.raiseError = 0
 
     def testVerbosity(self):
         program = self.program
@@ -225,6 +227,7 @@
 
         self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
                                                 'failfast': 'failfast',
+                                                'tb_locals': False,
                                                 'buffer': 'buffer'})
         self.assertEqual(FakeRunner.test, 'test')
         self.assertIs(program.result, RESULT)
@@ -243,10 +246,24 @@
         self.assertEqual(FakeRunner.test, 'test')
         self.assertIs(program.result, RESULT)
 
+    def test_locals(self):
+        program = self.program
+
+        program.testRunner = FakeRunner
+        program.parseArgs([None, '--locals'])
+        self.assertEqual(True, program.tb_locals)
+        program.runTests()
+        self.assertEqual(FakeRunner.initArgs, {'buffer': False,
+                                               'failfast': False,
+                                               'tb_locals': True,
+                                               'verbosity': 1})
+
     def testRunTestsOldRunnerClass(self):
         program = self.program
 
-        FakeRunner.raiseError = True
+        # Two TypeErrors are needed to fall all the way back to old-style
+        # runners - one to fail tb_locals, one to fail buffer etc.
+        FakeRunner.raiseError = 2
         program.testRunner = FakeRunner
         program.verbosity = 'verbosity'
         program.failfast = 'failfast'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_result.py 
new/unittest2-1.1.0/unittest2/test/test_result.py
--- old/unittest2-0.8.0/unittest2/test/test_result.py   2014-10-29 
11:05:10.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_result.py   2015-03-06 
06:20:12.000000000 +0100
@@ -1,13 +1,28 @@
 import sys
 import textwrap
-import traceback
+import traceback2 as traceback
 
+import six
 from six.moves import StringIO
 
 import unittest2
 import unittest2 as unittest
 
 
+class MockTraceback(object):
+    class TracebackException:
+        def __init__(self, *args, **kwargs):
+            self.capture_locals = kwargs.get('capture_locals', False)
+        def format(self):
+            result = ['A traceback']
+            if self.capture_locals:
+                result.append('locals')
+            return result
+
+def restore_traceback():
+    unittest.result.traceback = traceback
+
+
 class Test_TestResult(unittest2.TestCase):
     # Note: there are not separate tests for TestResult.wasSuccessful(),
     # TestResult.errors, TestResult.failures, TestResult.testsRun or
@@ -177,7 +192,7 @@
 
         test_case, formatted_exc = result.failures[0]
         self.assertIs(test_case, test)
-        self.assertIsInstance(formatted_exc, str)
+        self.assertIsInstance(formatted_exc, six.string_types)
 
     # "addError(test, err)"
     # ...
@@ -225,7 +240,26 @@
 
         test_case, formatted_exc = result.errors[0]
         self.assertIs(test_case, test)
-        self.assertIsInstance(formatted_exc, str)
+        self.assertIsInstance(formatted_exc, six.string_types)
+
+    def test_addError_locals(self):
+        class Foo(unittest.TestCase):
+            def test_1(self):
+                1/0
+
+        test = Foo('test_1')
+        result = unittest.TestResult()
+        result.tb_locals = True
+
+        unittest.result.traceback = MockTraceback
+        self.addCleanup(restore_traceback)
+        result.startTestRun()
+        test.run(result)
+        result.stopTestRun()
+
+        self.assertEqual(len(result.errors), 1)
+        test_case, formatted_exc = result.errors[0]
+        self.assertEqual('A tracebacklocals', formatted_exc)
 
     def test_addSubTest(self):
         log = []
@@ -391,16 +425,6 @@
         self.assertTrue(self.testRan)
 
 
-class MockTraceback(object):
-    @staticmethod
-    def format_exception(*_):
-        return ['A traceback']
-
-
-def restore_traceback():
-    unittest2.result.traceback = traceback
-
-                
 class TestOutputBuffering(unittest2.TestCase):
 
     def setUp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/test/test_runner.py 
new/unittest2-1.1.0/unittest2/test/test_runner.py
--- old/unittest2-0.8.0/unittest2/test/test_runner.py   2014-10-28 
23:46:13.000000000 +0100
+++ new/unittest2-1.1.0/unittest2/test/test_runner.py   2015-03-06 
06:05:12.000000000 +0100
@@ -160,7 +160,7 @@
         self.assertEqual(runner.verbosity, 1)
         self.assertTrue(runner.descriptions)
         self.assertEqual(runner.resultclass, unittest2.TextTestResult)
-
+        self.assertFalse(runner.tb_locals)
 
     def test_multiple_inheritance(self):
         class AResult(unittest.TestResult):
@@ -181,7 +181,7 @@
                 pass
         result = unittest2.TestResult()
         runner = unittest2.TextTestRunner(stream=StringIO(), failfast=True,
-                                           buffer=True)
+                                          buffer=True)
         # Use our result object
         runner._makeResult = lambda: result
         runner.run(Test('testFoo'))
@@ -189,6 +189,11 @@
         self.assertTrue(result.failfast)
         self.assertTrue(result.buffer)
 
+    def test_locals(self):
+        runner = unittest.TextTestRunner(stream=io.StringIO(), tb_locals=True)
+        result = runner.run(unittest.TestSuite())
+        self.assertEqual(True, result.tb_locals)
+
     def testRunnerRegistersResult(self):
         class Test(unittest2.TestCase):
             def testFoo(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2/util.py 
new/unittest2-1.1.0/unittest2/util.py
--- old/unittest2-0.8.0/unittest2/util.py       2014-10-29 04:25:24.000000000 
+0100
+++ new/unittest2-1.1.0/unittest2/util.py       2014-11-05 10:17:14.000000000 
+0100
@@ -60,45 +60,6 @@
 def strclass(cls):
     return "%s.%s" % (cls.__module__, getattr(cls, '__qualname__', 
cls.__name__))
 
-def sorted_list_difference(expected, actual):
-    """Finds elements in only one or the other of two, sorted input lists.
-
-    Returns a two-element tuple of lists.    The first list contains those
-    elements in the "expected" list but not in the "actual" list, and the
-    second contains those elements in the "actual" list but not in the
-    "expected" list.    Duplicate elements in either input list are ignored.
-    """
-    i = j = 0
-    missing = []
-    unexpected = []
-    while True:
-        try:
-            e = expected[i]
-            a = actual[j]
-            if e < a:
-                missing.append(e)
-                i += 1
-                while expected[i] == e:
-                    i += 1
-            elif e > a:
-                unexpected.append(a)
-                j += 1
-                while actual[j] == a:
-                    j += 1
-            else:
-                i += 1
-                try:
-                    while expected[i] == e:
-                        i += 1
-                finally:
-                    j += 1
-                    while actual[j] == a:
-                        j += 1
-        except IndexError:
-            missing.extend(expected[i:])
-            unexpected.extend(actual[j:])
-            break
-    return missing, unexpected
 
 def unorderable_list_difference(expected, actual, ignore_duplicate=False):
     """Same behavior as sorted_list_difference but
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2.egg-info/PKG-INFO 
new/unittest2-1.1.0/unittest2.egg-info/PKG-INFO
--- old/unittest2-0.8.0/unittest2.egg-info/PKG-INFO     2014-11-04 
16:26:25.000000000 +0100
+++ new/unittest2-1.1.0/unittest2.egg-info/PKG-INFO     2015-06-30 
08:48:20.000000000 +0200
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: unittest2
-Version: 0.8.0
+Version: 1.1.0
 Summary: The new features in unittest backported to Python 2.4+.
 Home-page: http://pypi.python.org/pypi/unittest2
-Author: Michael Foord
-Author-email: [email protected]
+Author: Robert Collins
+Author-email: [email protected]
 License: UNKNOWN
 Description: unittest2 is a backport of the new features added to the unittest 
testing
         framework in Python 2.7 and onwards. It is tested to run on Python 
2.6, 2.7,
@@ -30,8 +30,9 @@
         
         * `Download unittest2 0.5.1 for Python 2.3 
<http://voidspace.org.uk/downloads/unittest2-0.5.1-python2.3.zip>`_
         
-        There is also a version of unittest2 for Python 3. This has the 
project name
-        "unittest2py3k" but uses the same package name ("unittest2"):
+        There was a separate version of unittest2 for Python 3. This is no 
longer
+        needed, but still exists on PyPI. This had the project name 
"unittest2py3k" but
+        uses the same package name ("unittest2"):
         
         * `unittest2 for Python 3 <http://pypi.python.org/pypi/unittest2py3k>`_
         
@@ -43,6 +44,11 @@
         will work with the standard unittest test loaders, runners result 
objects
         however.
         
+        In general for documentation on unittest2 see the current latest 
documented of
+        CPython:
+        
+        * `CPython unittest documentation 
<https://docs.python.org/dev/library/unittest.html>`_
+        
         New features include:
         
         * ``addCleanups`` - better resource management
@@ -169,11 +175,39 @@
         CHANGELOG
         =========
         
+        2015-06-20 - 1.1.0
+        ------------------
+        
+        - Issue #15836: assertRaises(), assertRaisesRegex(), assertWarns() and
+          assertWarnsRegex() assertments now check the type of the first 
argument
+          to prevent possible user error.  Based on patch by Daniel 
Wagner-Hall.
+        
+        - Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
+          assertWarnsRegex() checks now emits a deprecation warning when 
callable is
+          None or keyword arguments except msg is passed in the context 
manager mode.
+        
+        - Issue #22903: The fake test case created by unittest.loader when it 
fails
+          importing a test module is now picklable.
+        
+        
+        2015-03-12 - 1.0.1
+        ------------------
+        
+        - Unittest2 issue #94: Need at least 1.4 of six.
+        
+        2015-03-06 - 1.0.0
+        ------------------
+        
+        - Issue #22936: Permit showing local variables in tracebacks.
+        
         2014/11/05 - 0.8
         ----------------
         
         - Issue #22457: Honour load_tests in the start_dir of discovery.
         
+        - Issue #22894: TestCase.subTest() would cause the test suite to be 
stopped
+          when in failfast mode, even in the absence of failures.
+        
         2014/10/31 - 0.7.1
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unittest2-0.8.0/unittest2.egg-info/requires.txt 
new/unittest2-1.1.0/unittest2.egg-info/requires.txt
--- old/unittest2-0.8.0/unittest2.egg-info/requires.txt 2014-11-04 
16:26:25.000000000 +0100
+++ new/unittest2-1.1.0/unittest2.egg-info/requires.txt 2015-06-30 
08:48:20.000000000 +0200
@@ -1,2 +1,3 @@
 argparse
-six
+six>=1.4
+traceback2


Reply via email to