Hello community,

here is the log from the commit of package python-parameterized for 
openSUSE:Factory checked in at 2020-06-05 20:00:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-parameterized (Old)
 and      /work/SRC/openSUSE:Factory/.python-parameterized.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-parameterized"

Fri Jun  5 20:00:19 2020 rev:7 rq:811024 version:0.7.4

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-parameterized/python-parameterized.changes    
    2019-12-11 12:11:00.036592066 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-parameterized.new.3606/python-parameterized.changes
      2020-06-05 20:00:28.731992702 +0200
@@ -1,0 +2,20 @@
+Tue Jun  2 14:26:24 UTC 2020 - [email protected]
+
+- version update to 0.7.4
+    * Add ``class_name_func`` option to ``@parameterized_class``
+    * Fix arguments being passed to skip_on_empty_helper (thanks @gaf3;
+      https://github.com/wolever/parameterized/issues/57)
+    * Fix tests on Python 3.8.2 (thanks @Ikke;
+      https://github.com/wolever/parameterized/pull/99)
+    * Fix some typos (thanks @LWprogramming, @jinnovation;
+      https://github.com/wolever/parameterized/pull/77,
+      https://github.com/wolever/parameterized/pull/80)
+    * Fix unicode handling in setup.py (thanks @sliwinski-milosz;
+      https://github.com/wolever/parameterized/pull/89)
+    * Fix Python 3.9 compat (thanks @vstinner;
+      https://github.com/wolever/parameterized/pull/94)
+    * Add `@parameterized_class` name function callback support (thanks
+      @duncwebb et al; https://github.com/wolever/parameterized/pull/74)
+- drop dependency on unittest2
+
+-------------------------------------------------------------------

Old:
----
  parameterized-0.7.1.tar.gz

New:
----
  parameterized-0.7.4.tar.gz

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

Other differences:
------------------
++++++ python-parameterized.spec ++++++
--- /var/tmp/diff_new_pack.XqZum8/_old  2020-06-05 20:00:30.795999472 +0200
+++ /var/tmp/diff_new_pack.XqZum8/_new  2020-06-05 20:00:30.799999485 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-parameterized
 #
-# Copyright (c) 2019 SUSE LLC
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-parameterized
-Version:        0.7.1
+Version:        0.7.4
 Release:        0
 Summary:        Parameterized testing
 License:        BSD-2-Clause
@@ -31,12 +31,10 @@
 BuildRequires:  %{python_module nose2}
 BuildRequires:  %{python_module nose}
 BuildRequires:  %{python_module setuptools}
-BuildRequires:  %{python_module unittest2}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Suggests:       python-nose
 Suggests:       python-nose2
-Suggests:       python-unittest2
 BuildArch:      noarch
 %python_subpackages
 
@@ -58,10 +56,8 @@
 
 %check
 export LANG=en_US.UTF8
-# gh#wolever/parameterized#84
 %{python_expand nosetests-%$python_version}
 %{python_expand nose2-%$python_version}
-%{python_expand unit2-%$python_version}
 %python_exec -m unittest parameterized.test
 
 %files %{python_files}

++++++ parameterized-0.7.1.tar.gz -> parameterized-0.7.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/.travis.yml 
new/parameterized-0.7.4/.travis.yml
--- old/parameterized-0.7.1/.travis.yml 2019-11-19 22:04:40.000000000 +0100
+++ new/parameterized-0.7.4/.travis.yml 2020-04-12 23:07:48.000000000 +0200
@@ -1,71 +0,0 @@
-# !!! WARNING !!!
-# This file is automatically generated by ./rebuild-travis-yaml
-# !!! WARNING !!!
-language: python
-sudo: false
-matrix:
-  include:
-    - env: "TOXENV=py27-nose"
-      python: "2.7"
-    - env: "TOXENV=py27-nose2"
-      python: "2.7"
-    - env: "TOXENV=py27-pytest2"
-      python: "2.7"
-    - env: "TOXENV=py27-pytest3"
-      python: "2.7"
-    - env: "TOXENV=py27-unit"
-      python: "2.7"
-    - env: "TOXENV=py27-unit2"
-      python: "2.7"
-    - env: "TOXENV=py35-nose"
-      python: "3.5"
-    - env: "TOXENV=py35-nose2"
-      python: "3.5"
-    - env: "TOXENV=py35-pytest2"
-      python: "3.5"
-    - env: "TOXENV=py35-pytest3"
-      python: "3.5"
-    - env: "TOXENV=py35-unit"
-      python: "3.5"
-    - env: "TOXENV=py35-unit2"
-      python: "3.5"
-    - env: "TOXENV=py36-nose"
-      python: "3.6"
-    - env: "TOXENV=py36-nose2"
-      python: "3.6"
-    - env: "TOXENV=py36-pytest2"
-      python: "3.6"
-    - env: "TOXENV=py36-pytest3"
-      python: "3.6"
-    - env: "TOXENV=py36-unit"
-      python: "3.6"
-    - env: "TOXENV=py36-unit2"
-      python: "3.6"
-    - env: "TOXENV=pypy-nose"
-      python: "pypy"
-    - env: "TOXENV=pypy-nose2"
-      python: "pypy"
-    - env: "TOXENV=pypy-pytest2"
-      python: "pypy"
-    - env: "TOXENV=pypy-pytest3"
-      python: "pypy"
-    - env: "TOXENV=pypy-unit"
-      python: "pypy"
-    - env: "TOXENV=pypy-unit2"
-      python: "pypy"
-    - env: "TOXENV=py37-nose"
-      python: "3.7"
-    - env: "TOXENV=py37-nose2"
-      python: "3.7"
-    - env: "TOXENV=py37-pytest3"
-      python: "3.7"
-    - env: "TOXENV=py37-unit"
-      python: "3.7"
-    - env: "TOXENV=py37-unit2"
-      python: "3.7"
-
-install: pip install tox
-script: tox
-# !!! WARNING !!!
-# This file is automatically generated by ./rebuild-travis-yaml
-# !!! WARNING !!!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/CHANGELOG.txt 
new/parameterized-0.7.4/CHANGELOG.txt
--- old/parameterized-0.7.1/CHANGELOG.txt       2019-11-19 23:04:03.000000000 
+0100
+++ new/parameterized-0.7.4/CHANGELOG.txt       2020-04-14 19:58:58.000000000 
+0200
@@ -1,3 +1,23 @@
+0.7.4 (2020-04-14)
+    * Add ``class_name_func`` option to ``@parameterized_class``
+    * Fix arguments being passed to skip_on_empty_helper (thanks @gaf3;
+      https://github.com/wolever/parameterized/issues/57)
+    * Fix tests on Python 3.8.2 (thanks @Ikke;
+      https://github.com/wolever/parameterized/pull/99)
+
+0.7.3 (2020-04-12)
+    * Fix some typos (thanks @LWprogramming, @jinnovation;
+      https://github.com/wolever/parameterized/pull/77,
+      https://github.com/wolever/parameterized/pull/80)
+    * Fix unicode handling in setup.py (thanks @sliwinski-milosz;
+      https://github.com/wolever/parameterized/pull/89)
+    * Fix Python 3.9 compat (thanks @vstinner;
+      https://github.com/wolever/parameterized/pull/94)
+
+0.7.2 (2020-04-12)
+    * Add `@parameterized_class` name function callback support (thanks
+      @duncwebb et al; https://github.com/wolever/parameterized/pull/74)
+
 0.7.1 (2019-11-19)
     * Fix #73: calling `setUp` and `tearDown` in parameterized classes
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/LICENSE.txt 
new/parameterized-0.7.4/LICENSE.txt
--- old/parameterized-0.7.1/LICENSE.txt 2019-11-19 21:17:12.000000000 +0100
+++ new/parameterized-0.7.4/LICENSE.txt 2020-04-12 23:37:30.000000000 +0200
@@ -1,5 +1,3 @@
-tl;dr: all code code is licensed under simplified BSD.
-
 Unless stated otherwise in the source files, all code is copyright 2010 David
 Wolever <[email protected]>. All rights reserved.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/PKG-INFO 
new/parameterized-0.7.4/PKG-INFO
--- old/parameterized-0.7.1/PKG-INFO    2019-11-19 23:04:22.000000000 +0100
+++ new/parameterized-0.7.4/PKG-INFO    2020-04-14 19:59:42.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: parameterized
-Version: 0.7.1
+Version: 0.7.4
 Summary: Parameterized testing with any Python test framework
 Home-page: https://github.com/wolever/parameterized
 Author: David Wolever
@@ -9,15 +9,14 @@
 Description: Parameterized testing with any Python test framework
         ====================================================
         
-        |pypi| |travis|
-        
-        .. |pypi| image:: https://img.shields.io/pypi/v/parameterized.svg
+        .. image:: https://img.shields.io/pypi/v/parameterized.svg
             :alt: PyPI
             :target: https://pypi.org/project/parameterized/
         
-        .. |travis| image:: 
https://travis-ci.org/wolever/parameterized.svg?branch=master
-            :alt: Travis CI
-            :target: https://travis-ci.org/wolever/parameterized
+        .. image:: https://circleci.com/gh/wolever/parameterized.svg?style=svg
+            :alt: Circle CI
+            :target: https://circleci.com/gh/wolever/parameterized
+        
         
         Parameterized testing in Python sucks.
         
@@ -197,6 +196,8 @@
              - Py3.5
              - Py3.6
              - Py3.7
+             - Py3.8
+             - Py3.9
              - PyPy
              - ``@mock.patch``
            * - nose
@@ -208,6 +209,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - nose2
              - yes
              - yes
@@ -217,6 +220,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 2
              - yes
              - yes
@@ -226,6 +231,8 @@
              - no*
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 3
              - yes
              - yes
@@ -235,6 +242,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 4
              - no**
              - no**
@@ -244,6 +253,8 @@
              - no**
              - no**
              - no**
+             - no**
+             - no**
            * - py.test fixtures
              - no†
              - no†
@@ -253,6 +264,8 @@
              - no†
              - no†
              - no†
+             - no†
+             - no†
            * - | unittest
                | (``@parameterized.expand``)
              - yes
@@ -263,6 +276,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - | unittest2
                | (``@parameterized.expand``)
              - yes
@@ -273,6 +288,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
         
         \*: py.test 2 does `does not appear to work (#71)`__ under Python 3. 
Please comment on the related issues if you are affected.
         
@@ -397,7 +414,7 @@
         ``test_add_0_2_and_3`` and ``test_add_1_3_and_5``.
         
         The names of the test cases generated by ``@parameterized.expand`` can 
be
-        customized using the ``testcase_func_name`` keyword argument. The 
value should
+        customized using the ``name_func`` keyword argument. The value should
         be a function which accepts three arguments: ``testcase_func``, 
``param_num``,
         and ``params``, and it should return the name of the test case.
         ``testcase_func`` will be the function to be tested, ``param_num`` 
will be the
@@ -419,7 +436,7 @@
                 @parameterized.expand([
                     (2, 3, 5),
                     (2, 3, 5),
-                ], testcase_func_name=custom_name_func)
+                ], name_func=custom_name_func)
                 def test_add(self, a, b, expected):
                     assert_equal(a + b, expected)
         
@@ -495,41 +512,77 @@
         
         .. code:: python
         
-           from yourapp.models import User
-           from parameterized import parameterized_class
+            from yourapp.models import User
+            from parameterized import parameterized_class
         
-           @parameterized_class(("username", "access_level", 
"expected_status_code"), [
-              ("user_1", 1, 200),
-              ("user_2", 2, 404)
-           ])
-           class TestUserAccessLevel(TestCase):
-              def setUp(self):
-                 
self.client.force_login(User.objects.get(username=self.username)[0])
-        
-              def test_url_a(self):
-                 response = self.client.get("/url")
-                 self.assertEqual(response.status_code, 
self.expected_status_code)
+            @parameterized_class([
+               { "username": "user_1", "access_level": 1 },
+               { "username": "user_2", "access_level": 2, 
"expected_status_code": 404 },
+            ])
+            class TestUserAccessLevel(TestCase):
+               expected_status_code = 200
         
-              def tearDown(self):
-                 self.client.logout()
+               def setUp(self):
+                  
self.client.force_login(User.objects.get(username=self.username)[0])
         
+               def test_url_a(self):
+                  response = self.client.get('/url')
+                  self.assertEqual(response.status_code, 
self.expected_status_code)
         
-           @parameterized_class([
-              { "username": "user_1", "access_level": 1 },
-              { "username": "user_2", "access_level": 2, 
"expected_status_code": 404 },
-           ])
-           class TestUserAccessLevel(TestCase):
-              expected_status_code = 200
+               def tearDown(self):
+                  self.client.logout()
+        
+        
+            @parameterized_class(("username", "access_level", 
"expected_status_code"), [
+               ("user_1", 1, 200),
+               ("user_2", 2, 404)
+            ])
+            class TestUserAccessLevel(TestCase):
+               def setUp(self):
+                  
self.client.force_login(User.objects.get(username=self.username)[0])
+        
+               def test_url_a(self):
+                  response = self.client.get("/url")
+                  self.assertEqual(response.status_code, 
self.expected_status_code)
+        
+               def tearDown(self):
+                  self.client.logout()
+        
+        
+        The ``@parameterized_class`` decorator accepts a ``class_name_func`` 
argument,
+        which controls the name of the parameterized classes generated by
+        ``@parameterized_class``:
         
-              def setUp(self):
-                 
self.client.force_login(User.objects.get(username=self.username)[0])
+        .. code:: python
+        
+            from parameterized import parameterized, parameterized_class
+        
+            def get_class_name(cls, num, params_dict):
+                # By default the generated class named includes either the 
"name"
+                # parameter (if present), or the first string value. This 
example shows
+                # multiple parameters being included in the generated class 
name:
+                return "%s_%s_%s%s" %(
+                    cls.__name__,
+                    num,
+                    parameterized.to_safe_name(params_dict['a']),
+                    parameterized.to_safe_name(params_dict['b']),
+                )
+        
+            @parameterized_class([
+               { "a": "hello", "b": " world!", "expected": "hello world!" },
+               { "a": "say ", "b": " cheese :)", "expected": "say cheese :)" },
+            ], class_name_func=get_class_name)
+            class TestConcatenation(TestCase):
+              def test_concat(self):
+                  self.assertEqual(self.a + self.b, self.expected)
+        
+        ::
+        
+            $ nosetests -v test_math.py
+            test_concat (test_concat.TestConcatenation_0_hello_world_) ... ok
+            test_concat (test_concat.TestConcatenation_0_say_cheese__) ... ok
         
-              def test_url_a(self):
-                 response = self.client.get('/url')
-                 self.assertEqual(response.status_code, 
self.expected_status_code)
         
-              def tearDown(self):
-                 self.client.logout()
         
         Using with Single Parameters
         ............................
@@ -624,3 +677,4 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: License :: OSI Approved :: BSD License
+Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/README.rst 
new/parameterized-0.7.4/README.rst
--- old/parameterized-0.7.1/README.rst  2019-11-19 23:04:05.000000000 +0100
+++ new/parameterized-0.7.4/README.rst  2020-04-14 19:27:29.000000000 +0200
@@ -1,15 +1,14 @@
 Parameterized testing with any Python test framework
 ====================================================
 
-|pypi| |travis|
-
-.. |pypi| image:: https://img.shields.io/pypi/v/parameterized.svg
+.. image:: https://img.shields.io/pypi/v/parameterized.svg
     :alt: PyPI
     :target: https://pypi.org/project/parameterized/
 
-.. |travis| image:: 
https://travis-ci.org/wolever/parameterized.svg?branch=master
-    :alt: Travis CI
-    :target: https://travis-ci.org/wolever/parameterized
+.. image:: https://circleci.com/gh/wolever/parameterized.svg?style=svg
+    :alt: Circle CI
+    :target: https://circleci.com/gh/wolever/parameterized
+
 
 Parameterized testing in Python sucks.
 
@@ -189,6 +188,8 @@
      - Py3.5
      - Py3.6
      - Py3.7
+     - Py3.8
+     - Py3.9
      - PyPy
      - ``@mock.patch``
    * - nose
@@ -200,6 +201,8 @@
      - yes
      - yes
      - yes
+     - yes
+     - yes
    * - nose2
      - yes
      - yes
@@ -209,6 +212,8 @@
      - yes
      - yes
      - yes
+     - yes
+     - yes
    * - py.test 2
      - yes
      - yes
@@ -218,6 +223,8 @@
      - no*
      - yes
      - yes
+     - yes
+     - yes
    * - py.test 3
      - yes
      - yes
@@ -227,6 +234,8 @@
      - yes
      - yes
      - yes
+     - yes
+     - yes
    * - py.test 4
      - no**
      - no**
@@ -236,6 +245,8 @@
      - no**
      - no**
      - no**
+     - no**
+     - no**
    * - py.test fixtures
      - no†
      - no†
@@ -245,6 +256,8 @@
      - no†
      - no†
      - no†
+     - no†
+     - no†
    * - | unittest
        | (``@parameterized.expand``)
      - yes
@@ -255,6 +268,8 @@
      - yes
      - yes
      - yes
+     - yes
+     - yes
    * - | unittest2
        | (``@parameterized.expand``)
      - yes
@@ -265,6 +280,8 @@
      - yes
      - yes
      - yes
+     - yes
+     - yes
 
 \*: py.test 2 does `does not appear to work (#71)`__ under Python 3. Please 
comment on the related issues if you are affected.
 
@@ -389,7 +406,7 @@
 ``test_add_0_2_and_3`` and ``test_add_1_3_and_5``.
 
 The names of the test cases generated by ``@parameterized.expand`` can be
-customized using the ``testcase_func_name`` keyword argument. The value should
+customized using the ``name_func`` keyword argument. The value should
 be a function which accepts three arguments: ``testcase_func``, ``param_num``,
 and ``params``, and it should return the name of the test case.
 ``testcase_func`` will be the function to be tested, ``param_num`` will be the
@@ -411,7 +428,7 @@
         @parameterized.expand([
             (2, 3, 5),
             (2, 3, 5),
-        ], testcase_func_name=custom_name_func)
+        ], name_func=custom_name_func)
         def test_add(self, a, b, expected):
             assert_equal(a + b, expected)
 
@@ -487,41 +504,77 @@
 
 .. code:: python
 
-   from yourapp.models import User
-   from parameterized import parameterized_class
+    from yourapp.models import User
+    from parameterized import parameterized_class
 
-   @parameterized_class(("username", "access_level", "expected_status_code"), [
-      ("user_1", 1, 200),
-      ("user_2", 2, 404)
-   ])
-   class TestUserAccessLevel(TestCase):
-      def setUp(self):
-         self.client.force_login(User.objects.get(username=self.username)[0])
-
-      def test_url_a(self):
-         response = self.client.get("/url")
-         self.assertEqual(response.status_code, self.expected_status_code)
+    @parameterized_class([
+       { "username": "user_1", "access_level": 1 },
+       { "username": "user_2", "access_level": 2, "expected_status_code": 404 
},
+    ])
+    class TestUserAccessLevel(TestCase):
+       expected_status_code = 200
 
-      def tearDown(self):
-         self.client.logout()
+       def setUp(self):
+          self.client.force_login(User.objects.get(username=self.username)[0])
 
+       def test_url_a(self):
+          response = self.client.get('/url')
+          self.assertEqual(response.status_code, self.expected_status_code)
 
-   @parameterized_class([
-      { "username": "user_1", "access_level": 1 },
-      { "username": "user_2", "access_level": 2, "expected_status_code": 404 },
-   ])
-   class TestUserAccessLevel(TestCase):
-      expected_status_code = 200
+       def tearDown(self):
+          self.client.logout()
+
+
+    @parameterized_class(("username", "access_level", "expected_status_code"), 
[
+       ("user_1", 1, 200),
+       ("user_2", 2, 404)
+    ])
+    class TestUserAccessLevel(TestCase):
+       def setUp(self):
+          self.client.force_login(User.objects.get(username=self.username)[0])
+
+       def test_url_a(self):
+          response = self.client.get("/url")
+          self.assertEqual(response.status_code, self.expected_status_code)
+
+       def tearDown(self):
+          self.client.logout()
+
+
+The ``@parameterized_class`` decorator accepts a ``class_name_func`` argument,
+which controls the name of the parameterized classes generated by
+``@parameterized_class``:
 
-      def setUp(self):
-         self.client.force_login(User.objects.get(username=self.username)[0])
+.. code:: python
+
+    from parameterized import parameterized, parameterized_class
+
+    def get_class_name(cls, num, params_dict):
+        # By default the generated class named includes either the "name"
+        # parameter (if present), or the first string value. This example shows
+        # multiple parameters being included in the generated class name:
+        return "%s_%s_%s%s" %(
+            cls.__name__,
+            num,
+            parameterized.to_safe_name(params_dict['a']),
+            parameterized.to_safe_name(params_dict['b']),
+        )
+
+    @parameterized_class([
+       { "a": "hello", "b": " world!", "expected": "hello world!" },
+       { "a": "say ", "b": " cheese :)", "expected": "say cheese :)" },
+    ], class_name_func=get_class_name)
+    class TestConcatenation(TestCase):
+      def test_concat(self):
+          self.assertEqual(self.a + self.b, self.expected)
+
+::
+
+    $ nosetests -v test_math.py
+    test_concat (test_concat.TestConcatenation_0_hello_world_) ... ok
+    test_concat (test_concat.TestConcatenation_0_say_cheese__) ... ok
 
-      def test_url_a(self):
-         response = self.client.get('/url')
-         self.assertEqual(response.status_code, self.expected_status_code)
 
-      def tearDown(self):
-         self.client.logout()
 
 Using with Single Parameters
 ............................
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/parameterized/parameterized.py 
new/parameterized-0.7.4/parameterized/parameterized.py
--- old/parameterized-0.7.1/parameterized/parameterized.py      2019-11-19 
23:04:03.000000000 +0100
+++ new/parameterized-0.7.4/parameterized/parameterized.py      2020-04-14 
19:33:58.000000000 +0200
@@ -44,7 +44,10 @@
     def make_method(func, instance, type):
         return MethodType(func, instance, type)
 
+
 CompatArgSpec = namedtuple("CompatArgSpec", "args varargs keywords defaults")
+
+
 def getargspec(func):
     if PY2:
         return CompatArgSpec(*inspect.getargspec(func))
@@ -58,11 +61,11 @@
         ) %(func, ))
     return CompatArgSpec(*args[:4])
 
-_param = namedtuple("param", "args kwargs")
 
 def skip_on_empty_helper(*a, **kw):
     raise SkipTest("parameterized input is empty")
 
+
 def reapply_patches_if_need(func):
 
     def dummy_wrapper(orgfunc):
@@ -79,11 +82,14 @@
             func = patch_obj.decorate_callable(func)
     return func
 
+
 def delete_patches_if_need(func):
     if hasattr(func, 'patchings'):
         func.patchings[:] = []
 
 
+_param = namedtuple("param", "args kwargs")
+
 class param(_param):
     """ Represents a single parameter to a test case.
 
@@ -217,6 +223,7 @@
 
     return result
 
+
 def short_repr(x, n=64):
     """ A shortened repr of ``x`` which is guaranteed to be ``unicode``::
 
@@ -236,6 +243,7 @@
         x_repr = x_repr[:n//2] + "..." + x_repr[len(x_repr) - n//2:]
     return x_repr
 
+
 def default_doc_func(func, num, p):
     if func.__doc__ is None:
         return None
@@ -256,9 +264,11 @@
     args = "%s[with %s]" %(len(first) and " " or "", ", ".join(descs))
     return "".join([first.rstrip(), args, suffix, nl, rest])
 
+
 def default_name_func(func, num, p):
     base_name = func.__name__
     name_suffix = "_%s" %(num, )
+
     if len(p.args) > 0 and isinstance(p.args[0], string_types):
         name_suffix += "_" + parameterized.to_safe_name(p.args[0])
     return base_name + name_suffix
@@ -271,6 +281,7 @@
     "_pytest": "pytest",
 }
 
+
 def set_test_runner(name):
     global _test_runner_override
     if name not in _test_runners:
@@ -280,6 +291,7 @@
         )
     _test_runner_override = name
 
+
 def detect_runner():
     """ Guess which test runner we're using by traversing the stack and looking
         for the first matching module. This *should* be reasonably safe, as
@@ -375,7 +387,7 @@
                     "`parameterized([], skip_on_empty=True)` to skip "
                     "this test when the input is empty)"
                 )
-            wrapper = wraps(test_func)(lambda: skip_on_empty_helper())
+            wrapper = wraps(test_func)(skip_on_empty_helper)
 
         wrapper.parameterized_input = input
         wrapper.parameterized_func = test_func
@@ -482,9 +494,9 @@
             frame = stack[1]
             frame_locals = frame[0].f_locals
 
-            paramters = cls.input_as_callable(input)()
+            parameters = cls.input_as_callable(input)()
 
-            if not paramters:
+            if not parameters:
                 if not skip_on_empty:
                     raise ValueError(
                         "Parameters iterable is empty (hint: use "
@@ -493,8 +505,8 @@
                     )
                 return wraps(f)(lambda: skip_on_empty_helper())
 
-            digits = len(str(len(paramters) - 1))
-            for num, p in enumerate(paramters):
+            digits = len(str(len(parameters) - 1))
+            for num, p in enumerate(parameters):
                 name = name_func(f, "{num:0>{digits}}".format(digits=digits, 
num=num), p)
                 # If the original function has patches applied by 'mock.patch',
                 # re-construct all patches on the just former decoration layer
@@ -536,7 +548,7 @@
         return str(re.sub("[^a-zA-Z0-9_]+", "_", s))
 
 
-def parameterized_class(attrs, input_values=None):
+def parameterized_class(attrs, input_values=None, class_name_func=None, 
classname_func=None):
     """ Parameterizes a test class by setting attributes on the class.
 
         Can be used in two ways:
@@ -569,25 +581,24 @@
         [dict(zip(attrs, vals)) for vals in input_values]
     )
 
+    class_name_func = class_name_func or default_class_name_func
+    
+    if classname_func:
+        warnings.warn(
+            "classname_func= is deprecated; use class_name_func= instead. "
+            "See: 
https://github.com/wolever/parameterized/pull/74#issuecomment-613577057";,
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        class_name_func = lambda cls, idx, input: classname_func(cls, idx, 
input_dicts)
+
     def decorator(base_class):
         test_class_module = sys.modules[base_class.__module__].__dict__
         for idx, input_dict in enumerate(input_dicts):
             test_class_dict = dict(base_class.__dict__)
             test_class_dict.update(input_dict)
 
-            name_suffix = input_values and input_values[idx]
-            if isinstance(name_suffix, (list, tuple)) and len(input_values) > 
0:
-                name_suffix = name_suffix[0]
-            name_suffix = (
-                "_%s" %(name_suffix, ) if isinstance(name_suffix, 
string_types) else
-                ""
-            )
-
-            name = "%s_%s%s" %(
-                base_class.__name__,
-                idx,
-                name_suffix,
-            )
+            name = class_name_func(base_class, idx, input_dict)
 
             test_class_module[name] = type(name, (base_class, ), 
test_class_dict)
 
@@ -603,3 +614,26 @@
         return base_class
 
     return decorator
+
+
+def get_class_name_suffix(params_dict):
+    if "name" in params_dict:
+        return parameterized.to_safe_name(params_dict["name"])
+
+    params_vals = (
+        params_dict.values() if PY3 else
+        (v for (_, v) in sorted(params_dict.items()))
+    )
+    return parameterized.to_safe_name(next((
+        v for v in params_vals
+        if isinstance(v, string_types)
+    ), ""))
+
+
+def default_class_name_func(cls, num, params_dict):
+    suffix = get_class_name_suffix(params_dict)
+    return "%s_%s%s" %(
+        cls.__name__,
+        num,
+        suffix and "_" + suffix,
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/parameterized/test.py 
new/parameterized-0.7.4/parameterized/test.py
--- old/parameterized-0.7.1/parameterized/test.py       2019-11-19 
23:04:03.000000000 +0100
+++ new/parameterized-0.7.4/parameterized/test.py       2020-04-14 
19:26:48.000000000 +0200
@@ -249,7 +249,10 @@
         f_locals = stack[3][0].f_locals
         test_method = (
             f_locals.get("testMethod") or # Py27
-            f_locals.get("function") # Py33
+            f_locals.get("function") or # Py33
+            f_locals.get("method") or # Py38
+            f_locals.get("testfunction") or # Py382
+            None
         )
         if test_method is None:
             raise AssertionError("uh oh, unittest changed a local variable 
name")
@@ -444,17 +447,14 @@
 
 @parameterized_class(("a", "b", "c"), [
     ("foo", 1, 2),
-    ("bar", 3, 0),
     (0, 1, 2),
 ])
 class TestParameterizedClass(TestCase):
     expect([
         "TestParameterizedClass_0_foo:test_method_a('foo', 1, 2)",
         "TestParameterizedClass_0_foo:test_method_b('foo', 1, 2)",
-        "TestParameterizedClass_1_bar:test_method_a('bar', 3, 0)",
-        "TestParameterizedClass_1_bar:test_method_b('bar', 3, 0)",
-        "TestParameterizedClass_2:test_method_a(0, 1, 2)",
-        "TestParameterizedClass_2:test_method_b(0, 1, 2)",
+        "TestParameterizedClass_1:test_method_a(0, 1, 2)",
+        "TestParameterizedClass_1:test_method_b(0, 1, 2)",
     ])
 
     def _assertions(self, test_name):
@@ -475,22 +475,43 @@
         self._assertions("test_method_b")
 
 
+@parameterized_class(("a", ), [
+    (1, ),
+    (2, ),
+], class_name_func=lambda cls, idx, attrs: "%s_custom_func_%s" %(cls.__name__, 
attrs["a"]))
+class TestNamedParameterizedClass(TestCase):
+    expect([
+        "TestNamedParameterizedClass_custom_func_1:test_method(1)",
+        "TestNamedParameterizedClass_custom_func_2:test_method(2)",
+    ])
+
+    def test_method(self):
+        missing_tests.remove("%s:test_method(%r)" %(
+            self.__class__.__name__,
+            self.a,
+        ))
+
+
 @parameterized_class([
-    {"foo": 1},
-    {"bar": 1},
+    {"foo": 42},
+    {"bar": "some stuff"},
+    {"bar": "other stuff", "name": "some name", "foo": 12},
 ])
 class TestParameterizedClassDict(TestCase):
     expect([
-        "TestParameterizedClassDict_0:setUp(1, 0)",
-        "TestParameterizedClassDict_0:tearDown(1, 0)",
-        "TestParameterizedClassDict_0:test_method(1, 0)",
-        "TestParameterizedClassDict_1:test_method(0, 1)",
-        "TestParameterizedClassDict_1:setUp(0, 1)",
-        "TestParameterizedClassDict_1:tearDown(0, 1)",
+        "TestParameterizedClassDict_0:setUp(42, 'empty')",
+        "TestParameterizedClassDict_0:test_method(42, 'empty')",
+        "TestParameterizedClassDict_0:tearDown(42, 'empty')",
+        "TestParameterizedClassDict_1_some_stuff:setUp(0, 'some stuff')",
+        "TestParameterizedClassDict_1_some_stuff:test_method(0, 'some stuff')",
+        "TestParameterizedClassDict_1_some_stuff:tearDown(0, 'some stuff')",
+        "TestParameterizedClassDict_2_some_name:setUp(12, 'other stuff')",
+        "TestParameterizedClassDict_2_some_name:test_method(12, 'other 
stuff')",
+        "TestParameterizedClassDict_2_some_name:tearDown(12, 'other stuff')",
     ])
 
     foo = 0
-    bar = 0
+    bar = 'empty'
 
     def setUp(self):
         # Ensure that super() works (issue #73)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/parameterized.egg-info/PKG-INFO 
new/parameterized-0.7.4/parameterized.egg-info/PKG-INFO
--- old/parameterized-0.7.1/parameterized.egg-info/PKG-INFO     2019-11-19 
23:04:22.000000000 +0100
+++ new/parameterized-0.7.4/parameterized.egg-info/PKG-INFO     2020-04-14 
19:59:42.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: parameterized
-Version: 0.7.1
+Version: 0.7.4
 Summary: Parameterized testing with any Python test framework
 Home-page: https://github.com/wolever/parameterized
 Author: David Wolever
@@ -9,15 +9,14 @@
 Description: Parameterized testing with any Python test framework
         ====================================================
         
-        |pypi| |travis|
-        
-        .. |pypi| image:: https://img.shields.io/pypi/v/parameterized.svg
+        .. image:: https://img.shields.io/pypi/v/parameterized.svg
             :alt: PyPI
             :target: https://pypi.org/project/parameterized/
         
-        .. |travis| image:: 
https://travis-ci.org/wolever/parameterized.svg?branch=master
-            :alt: Travis CI
-            :target: https://travis-ci.org/wolever/parameterized
+        .. image:: https://circleci.com/gh/wolever/parameterized.svg?style=svg
+            :alt: Circle CI
+            :target: https://circleci.com/gh/wolever/parameterized
+        
         
         Parameterized testing in Python sucks.
         
@@ -197,6 +196,8 @@
              - Py3.5
              - Py3.6
              - Py3.7
+             - Py3.8
+             - Py3.9
              - PyPy
              - ``@mock.patch``
            * - nose
@@ -208,6 +209,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - nose2
              - yes
              - yes
@@ -217,6 +220,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 2
              - yes
              - yes
@@ -226,6 +231,8 @@
              - no*
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 3
              - yes
              - yes
@@ -235,6 +242,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - py.test 4
              - no**
              - no**
@@ -244,6 +253,8 @@
              - no**
              - no**
              - no**
+             - no**
+             - no**
            * - py.test fixtures
              - no†
              - no†
@@ -253,6 +264,8 @@
              - no†
              - no†
              - no†
+             - no†
+             - no†
            * - | unittest
                | (``@parameterized.expand``)
              - yes
@@ -263,6 +276,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
            * - | unittest2
                | (``@parameterized.expand``)
              - yes
@@ -273,6 +288,8 @@
              - yes
              - yes
              - yes
+             - yes
+             - yes
         
         \*: py.test 2 does `does not appear to work (#71)`__ under Python 3. 
Please comment on the related issues if you are affected.
         
@@ -397,7 +414,7 @@
         ``test_add_0_2_and_3`` and ``test_add_1_3_and_5``.
         
         The names of the test cases generated by ``@parameterized.expand`` can 
be
-        customized using the ``testcase_func_name`` keyword argument. The 
value should
+        customized using the ``name_func`` keyword argument. The value should
         be a function which accepts three arguments: ``testcase_func``, 
``param_num``,
         and ``params``, and it should return the name of the test case.
         ``testcase_func`` will be the function to be tested, ``param_num`` 
will be the
@@ -419,7 +436,7 @@
                 @parameterized.expand([
                     (2, 3, 5),
                     (2, 3, 5),
-                ], testcase_func_name=custom_name_func)
+                ], name_func=custom_name_func)
                 def test_add(self, a, b, expected):
                     assert_equal(a + b, expected)
         
@@ -495,41 +512,77 @@
         
         .. code:: python
         
-           from yourapp.models import User
-           from parameterized import parameterized_class
+            from yourapp.models import User
+            from parameterized import parameterized_class
         
-           @parameterized_class(("username", "access_level", 
"expected_status_code"), [
-              ("user_1", 1, 200),
-              ("user_2", 2, 404)
-           ])
-           class TestUserAccessLevel(TestCase):
-              def setUp(self):
-                 
self.client.force_login(User.objects.get(username=self.username)[0])
-        
-              def test_url_a(self):
-                 response = self.client.get("/url")
-                 self.assertEqual(response.status_code, 
self.expected_status_code)
+            @parameterized_class([
+               { "username": "user_1", "access_level": 1 },
+               { "username": "user_2", "access_level": 2, 
"expected_status_code": 404 },
+            ])
+            class TestUserAccessLevel(TestCase):
+               expected_status_code = 200
         
-              def tearDown(self):
-                 self.client.logout()
+               def setUp(self):
+                  
self.client.force_login(User.objects.get(username=self.username)[0])
         
+               def test_url_a(self):
+                  response = self.client.get('/url')
+                  self.assertEqual(response.status_code, 
self.expected_status_code)
         
-           @parameterized_class([
-              { "username": "user_1", "access_level": 1 },
-              { "username": "user_2", "access_level": 2, 
"expected_status_code": 404 },
-           ])
-           class TestUserAccessLevel(TestCase):
-              expected_status_code = 200
+               def tearDown(self):
+                  self.client.logout()
+        
+        
+            @parameterized_class(("username", "access_level", 
"expected_status_code"), [
+               ("user_1", 1, 200),
+               ("user_2", 2, 404)
+            ])
+            class TestUserAccessLevel(TestCase):
+               def setUp(self):
+                  
self.client.force_login(User.objects.get(username=self.username)[0])
+        
+               def test_url_a(self):
+                  response = self.client.get("/url")
+                  self.assertEqual(response.status_code, 
self.expected_status_code)
+        
+               def tearDown(self):
+                  self.client.logout()
+        
+        
+        The ``@parameterized_class`` decorator accepts a ``class_name_func`` 
argument,
+        which controls the name of the parameterized classes generated by
+        ``@parameterized_class``:
         
-              def setUp(self):
-                 
self.client.force_login(User.objects.get(username=self.username)[0])
+        .. code:: python
+        
+            from parameterized import parameterized, parameterized_class
+        
+            def get_class_name(cls, num, params_dict):
+                # By default the generated class named includes either the 
"name"
+                # parameter (if present), or the first string value. This 
example shows
+                # multiple parameters being included in the generated class 
name:
+                return "%s_%s_%s%s" %(
+                    cls.__name__,
+                    num,
+                    parameterized.to_safe_name(params_dict['a']),
+                    parameterized.to_safe_name(params_dict['b']),
+                )
+        
+            @parameterized_class([
+               { "a": "hello", "b": " world!", "expected": "hello world!" },
+               { "a": "say ", "b": " cheese :)", "expected": "say cheese :)" },
+            ], class_name_func=get_class_name)
+            class TestConcatenation(TestCase):
+              def test_concat(self):
+                  self.assertEqual(self.a + self.b, self.expected)
+        
+        ::
+        
+            $ nosetests -v test_math.py
+            test_concat (test_concat.TestConcatenation_0_hello_world_) ... ok
+            test_concat (test_concat.TestConcatenation_0_say_cheese__) ... ok
         
-              def test_url_a(self):
-                 response = self.client.get('/url')
-                 self.assertEqual(response.status_code, 
self.expected_status_code)
         
-              def tearDown(self):
-                 self.client.logout()
         
         Using with Single Parameters
         ............................
@@ -624,3 +677,4 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: License :: OSI Approved :: BSD License
+Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/parameterized-0.7.1/parameterized.egg-info/SOURCES.txt 
new/parameterized-0.7.4/parameterized.egg-info/SOURCES.txt
--- old/parameterized-0.7.1/parameterized.egg-info/SOURCES.txt  2019-11-19 
23:04:22.000000000 +0100
+++ new/parameterized-0.7.4/parameterized.egg-info/SOURCES.txt  2020-04-14 
19:59:42.000000000 +0200
@@ -16,4 +16,5 @@
 parameterized.egg-info/SOURCES.txt
 parameterized.egg-info/dependency_links.txt
 parameterized.egg-info/pbr.json
+parameterized.egg-info/requires.txt
 parameterized.egg-info/top_level.txt
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/parameterized.egg-info/pbr.json 
new/parameterized-0.7.4/parameterized.egg-info/pbr.json
--- old/parameterized-0.7.1/parameterized.egg-info/pbr.json     2019-11-19 
23:04:22.000000000 +0100
+++ new/parameterized-0.7.4/parameterized.egg-info/pbr.json     2020-04-14 
19:59:42.000000000 +0200
@@ -1 +1 @@
-{"is_release": false, "git_version": "4d73fbe"}
\ No newline at end of file
+{"is_release": false, "git_version": "ff5a1da"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/parameterized-0.7.1/parameterized.egg-info/requires.txt 
new/parameterized-0.7.4/parameterized.egg-info/requires.txt
--- old/parameterized-0.7.1/parameterized.egg-info/requires.txt 1970-01-01 
01:00:00.000000000 +0100
+++ new/parameterized-0.7.4/parameterized.egg-info/requires.txt 2020-04-14 
19:59:42.000000000 +0200
@@ -0,0 +1,3 @@
+
+[dev]
+jinja2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/setup.py 
new/parameterized-0.7.4/setup.py
--- old/parameterized-0.7.1/setup.py    2019-11-19 23:04:03.000000000 +0100
+++ new/parameterized-0.7.4/setup.py    2020-04-14 19:59:14.000000000 +0200
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+import io
 import os
 import sys
 
@@ -8,13 +9,13 @@
 os.chdir(os.path.dirname(sys.argv[0]) or ".")
 
 try:
-    long_description = open("README.rst", "U").read()
+    long_description = io.open("README.rst", encoding="utf-8").read()
 except IOError:
     long_description = "See https://github.com/wolever/parameterized";
 
 setup(
     name="parameterized",
-    version="0.7.1",
+    version="0.7.4",
     url="https://github.com/wolever/parameterized";,
     license="FreeBSD",
     author="David Wolever",
@@ -26,5 +27,10 @@
         'License :: OSI Approved :: BSD License',
     ],
     packages=find_packages(),
+    extras_require={
+        'dev': [
+            'jinja2',
+        ]
+    },
     long_description=long_description,
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parameterized-0.7.1/tox.ini 
new/parameterized-0.7.4/tox.ini
--- old/parameterized-0.7.1/tox.ini     2019-11-19 21:26:37.000000000 +0100
+++ new/parameterized-0.7.4/tox.ini     2020-04-12 23:07:48.000000000 +0200
@@ -1,5 +1,5 @@
 [tox]
-envlist=py{27,35,36,py}-{nose,nose2,pytest2,pytest3,unit,unit2},py37-{nose,nose2,pytest3,unit,unit2}
+envlist=py{27,35,36,py}-{nose,nose2,pytest2,pytest3,unit,unit2},py{37,38,39}-{nose,nose2,pytest3,unit,unit2}
 [testenv]
 deps=
     nose


Reply via email to