Package: python3-tornado
Version: 6.4.0-1
Severity: serious
Tags: patch
User: debian-pyt...@lists.debian.org
Usertags: pytest-8
Control: affects -1 src:python-tenacity src:terminado

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Dear maintainer,

unittest.TestCase has a feature where it allows instantiating MyTestClass() 
with the default method name runTest even if a runTest method doesn't actually 
exist. This is documented in TestCase's docs under "Changed in version 3.2" 
[0].

Since version 8.2, pytest relies on this, and started breaking on Tornado's 
AsyncTestCase [1].

Find attached a patch (submitted to upstream [2]) that resolves the issue.


Cheers
Timo

[0] https://docs.python.org/3/library/unittest.html#unittest.TestCase
[1] https://github.com/pytest-dev/pytest/issues/12263
[2] https://github.com/tornadoweb/tornado/pull/3374



-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEmwPruYMA35fCsSO/zIxr3RQD9MoFAmZXBNUACgkQzIxr3RQD
9MpHCxAAhX5aHeyUNaO6Zn1Beex96vffhC8r72FQnu0IUw1Ty9tLW8erwX6sdoxm
EYft79iBL03nQdyucRgr4cglB1jly/0KOuns9VwqBk8nEwjBvCg9TO0CgryH8eip
N8A9Yf0j6A4tW95dbS0Ovs1XfQR4NJ66grDj08vmlTcseBIN9EgrFVEVaOv5QuPm
q8Z78jIqmHDc2YBpHEegxOQD4UtkJZofsQwzjGZhwvz9Zlnuv69PBp4r4XxLQEmm
iErjajRU9mjBMVEosL89xkl1Fb5AQp/IFvTXNsPhbFfKfwcE0hs5EmUO0WhQOJWr
HjiYm8te9QEGhKB1oLad+mg30B9FAMXrdq1qsw/yaZeUaVM9Dpq2LJ2zEGlQKTSX
yauPcxxFeAtVmsq94JdBHT7ag/v8fsJ4MO+hAVZikPh21oT4yA/fixFd4dORJIFy
LFISGojbAjxFnCDnls5JLK0I+QGGnyVQxYu/wEAG6KkA2+1lDFtU2IiTGy1+EOro
FfXde94WF386DlOr0806/4ts4u0qYFcXpwh3SAvJH7Y6ikyt3kgyR+YLkglWeoKM
bEcpsPVn/a2jzyXI5o0TRuIOwLyjxJSbKZYm4QECNQneGez38vmiNjaZZXitlkCR
fTytpm1DIxAN39ah8yt/NG12yKBidQK824595JmOx/gFV5DRQ5w=
=v71Z
-----END PGP SIGNATURE-----
commit c851aa8a949524b35f72c82b45a52353aa3c0558
Author: Ran Benita <r...@unusedvar.com>
Date:   Sun Apr 28 14:17:54 2024 +0300

    testing: allow to instantiate an empty AsyncTestCase
    
    `unittest.TestCase` has a feature where it allows instantiating
    `MyTestClass()` with the default method name `runTest` even if a
    `runTest` method doesn't actually exist. This is documented in
    `TestCase`'s docs under "Changed in version 3.2"[0].
    
    Since version 8.2, pytest relies on this, and started breaking on
    Tornado's `AsyncTestCase`[1].
    
    Change `AsyncTestCase` to allow empty instatiation, by matching the
    upstream code.
    
    [0] https://docs.python.org/3/library/unittest.html#unittest.TestCase
    [1] https://github.com/pytest-dev/pytest/issues/12263

diff --git a/tornado/test/testing_test.py b/tornado/test/testing_test.py
index 0429feee..8e2b8db4 100644
--- a/tornado/test/testing_test.py
+++ b/tornado/test/testing_test.py
@@ -61,6 +61,15 @@ class AsyncTestCaseTest(AsyncTestCase):
         self.io_loop.add_timeout(self.io_loop.time() + 0.2, self.stop)
         self.wait(timeout=0.4)
 
+    def test_empty_instantation_is_allowed(self):
+        """
+        Test that empty instatiation of an AsyncTestCase is allowed.
+
+        unittest.TestCase docs guarantee this working, and pytest's unittest
+        support relies on it.
+        """
+        AsyncTestCaseTest()
+
 
 class LeakTest(AsyncTestCase):
     def tearDown(self):
diff --git a/tornado/testing.py b/tornado/testing.py
index bdbff87b..9455411a 100644
--- a/tornado/testing.py
+++ b/tornado/testing.py
@@ -177,7 +177,17 @@ class AsyncTestCase(unittest.TestCase):
         # the test will silently be ignored because nothing will consume
         # the generator.  Replace the test method with a wrapper that will
         # make sure it's not an undecorated generator.
-        setattr(self, methodName, _TestMethodWrapper(getattr(self, 
methodName)))
+        try:
+            test_method = getattr(self, methodName)
+        except AttributeError:
+            if methodName != "runTest":
+                # We allow instantiation with no explicit method name
+                # but not an *incorrect* or missing method name.
+                raise ValueError(
+                    "no such test method in %s: %s" % (self.__class__, 
methodName)
+                )
+        else:
+            setattr(self, methodName, _TestMethodWrapper(test_method))
 
         # Not used in this class itself, but used by @gen_test
         self._test_generator = None  # type: Optional[Union[Generator, 
Coroutine]]

Reply via email to