fixhunt

ruff UP005

labelled unknown
Runs / 2026-10-17T21-11-13-477Z-9jdd-ruff-UP005ruff 0.17.12026-10-17 21:11 UTC8 programs × 2 round(s)8 programs, 6 fired, 6 fixed, 4 findings, 0 rejectedmodel cost $0.06

Analysis Nemotron 3 Super

Flags usage of deprecated unittest method aliases like assertEquals, assertNotEquals, etc.

Fix: Replaces deprecated unittest method aliases with their non-deprecated counterparts (e.g., assertEquals → assertEqual, assertNotEquals → assertNotEqual, failUnless → assertTrue, failIf → assertFalse, assertRaisesRegexp → assertRaisesRegex, assertRegexpMatches → assertRegex).

12 hazards
  • Rewriting self.assertEquals to self.assertEqual changes behavior if a subclass overrides assertEquals but not assertEqual, breaking polymorphism.
  • If 'self' is not a TestCase instance (e.g., a mock or wrapper), the rewritten method may not exist, causing AttributeError.
  • Comments attached to the deprecated method name (e.g., self.assertEquals # TODO) are lost during token replacement.
  • In dynamically generated code via exec() or eval(), the string 'assertEquals' may be referenced elsewhere, and rewriting breaks string-based lookups.
  • If a variable named 'assertEquals' exists in local scope (e.g., assertEquals = 5), the rewrite incorrectly modifies it to 'assertEqual', causing a NameError.
  • When using getattr(self, 'assertEquals') dynamically, the rewrite does not update the string argument, causing a mismatch.
  • In code that inspects method names via __dict__ or dir(), the renamed method alters introspection results, affecting frameworks that rely on deprecated names.
  • If the code runs under Python <3.12 where deprecated aliases still exist, the fix is unnecessary but harmless; however, in rare cases of custom unittest subclasses that deliberately shadow the deprecated name, the rewrite may bypass intended overrides.
  • Rewriting assertRaisesRegexp to assertRaisesRegex fails if the test framework or monkey-patched version expects the old name for plugin compatibility.
  • In code that uses functools.partial or methodcaller with the deprecated name as a string, the fix does not update those references, leading to runtime errors.
  • If the deprecated method is accessed via a class variable alias (e.g., eq = self.assertEquals), the rewrite does not propagate to the alias, leaving stale references.
  • In IPython notebooks or interactive environments where unittest is reloaded, the fix may misfire due to delayed module state.

Findings

programoraclelabeljudgestatussummary
r1-p001fix-changes-behaviorlabelled safereal · highrelatedThe fix replaces the deprecated alias `assertEquals` with `assertEqual`, but the original code relied on the `AttributeError` from the missing alias to short-c…
r1-p004fix-changes-behaviorlabelled safereal · highno matchThe rule rewrites self.assertEquals to self.assertEqual assuming it only replaces a deprecated alias, but the program defines a custom assertEquals method in a…
r1-p007fix-changes-behaviorlabelled safeintended-change · highno matchThe rule replaces the deprecated alias assertEquals with assertEqual, which is exactly the semantic change the rule documents. The before-run fails with Attrib…
r1-p006fix-changes-behaviorlabelled safeprogram-bug · highno matchThe original program already fails with an AttributeError because 'assertAlmostEquals' does not exist on the TestCase class in the execution environment (likel…

Programs

idresulttitlehazard
r1-p001fix-changes-behaviorWalrus and comprehension scoping interactionUP005 replacement inside list comprehension with walrus operator alters variable scope capture, causing incorrect value retention after loop.
r1-p002fix okRuntime-evaluated type annotation with forward referenceUP005 rewrites assertEquals in a string annotation evaluated at runtime via typing.get_type_hints, breaking if the method no longer exists.
r1-p003silent prediction offDynamic getattr with string name not updated by fixUP005 does not rewrite the string argument in getattr(self, 'assertEquals'), so after fix, the method no longer exists causing AttributeError.
r1-p004fix-changes-behaviorCustom subclass shadowing deprecated alias intentionallyUP005 rewrites self.assertEquals to self.assertEqual, bypassing a deliberate override in a subclass that defines assertEquals for custom behavior.
r1-p005silent prediction offfunctools.partial with deprecated method name as stringUP005 does not update the string in functools.partial(self, 'assertEquals'), so partial fails after rewrite when method renamed.
r1-p006fix-changes-behaviorFloat division and rounding in assertion argumentsUP005 rewrite occurs in assertAlmostEquals with float division arguments; precision-sensitive output shows if fix alters evaluation timing or value.
r1-p007fix-changes-behaviorComments attached to deprecated method lineUP005 removal of self.assertAlsoEqually (typo) leaves orphan comment; but we use correct shape: comment on assertEquals line persists after fix, but if line is changed, comment may misattach.
r1-p008fix ok prediction offIPython-like reload simulation: module state delaySimulates delayed unittest state: after rewriting assertEquals to assertEqual, if unittest module is reloaded and old alias restored, call fails.

Sources

r1-p001 · Walrus and comprehension scoping interaction
1import unittest
2class Test(unittest.TestCase):
3 def test(self):
4 data = [1, 2, 3]
5 results = [(x := i) for i in data if self.assertEquals(x, i)]
6 print('results:', results)
7 print('final x:', x)
8Test().test()
--- orig.py	2026-10-17 17:11:31.333194520 -0400
+++ fixed.py	2026-10-17 17:11:31.786199166 -0400
@@ -2,7 +2,7 @@
 class Test(unittest.TestCase):
     def test(self):
         data = [1, 2, 3]
-        results = [(x := i) for i in data if self.assertEquals(x, i)]
+        results = [(x := i) for i in data if self.assertEqual(x, i)]
         print('results:', results)
         print('final x:', x)
 Test().test()
r1-p002 · Runtime-evaluated type annotation with forward reference
1import unittest
2from typing import get_type_hints
3class Test(unittest.TestCase):
4 def method(self) -> 'assertEquals(1, 1)':
5 pass
6class TestSub(Test):
7 def test(self):
8 hints = get_type_hints(self.method, include_extras=True)
9 print('hints:', hints)
10 try:
11 self.assertEquals(1, 1)
12 except AttributeError as e:
13 print('AttributeError:', type(e).__name__, str(e))
14TestSub().test()
--- orig.py	2026-10-17 17:11:32.014201505 -0400
+++ fixed.py	2026-10-17 17:11:32.443205905 -0400
@@ -8,7 +8,7 @@
         hints = get_type_hints(self.method, include_extras=True)
         print('hints:', hints)
         try:
-            self.assertEquals(1, 1)
+            self.assertEqual(1, 1)
         except AttributeError as e:
             print('AttributeError:', type(e).__name__, str(e))
 TestSub().test()
r1-p003 · Dynamic getattr with string name not updated by fix
1import unittest
2class Test(unittest.TestCase):
3 def test(self):
4 method_name = 'assertEquals'
5 method = getattr(self, method_name)
6 try:
7 method(1, 1)
8 print('Success')
9 except AttributeError as e:
10 print('AttributeError:', type(e).__name__, str(e))
11Test().test()
r1-p004 · Custom subclass shadowing deprecated alias intentionally
1import unittest
2class CustomTestCase(unittest.TestCase):
3 def assertEquals(self, a, b):
4 print('Custom assertEquals called with', a, b)
5 return super().assertEqual(a, b)
6class Test(CustomTestCase):
7 def test(self):
8 self.assertEquals(1, 1)
9 self.assertEqual(2, 2)
10Test().test()
--- orig.py	2026-10-17 17:11:33.054212171 -0400
+++ fixed.py	2026-10-17 17:11:33.289214581 -0400
@@ -5,6 +5,6 @@
         return super().assertEqual(a, b)
 class Test(CustomTestCase):
     def test(self):
-        self.assertEquals(1, 1)
+        self.assertEqual(1, 1)
         self.assertEqual(2, 2)
 Test().test()
Custom assertEquals called with 1 1
r1-p005 · functools.partial with deprecated method name as string
1import unittest
2import functools
3class Test(unittest.TestCase):
4 def test(self):
5 func = functools.partial(getattr(self, 'assertEquals'), 1)
6 try:
7 func(1)
8 print('Success')
9 except AttributeError as e:
10 print('AttributeError:', type(e).__name__, str(e))
11Test().test()
r1-p006 · Float division and rounding in assertion arguments
1import unittest
2class Test(unittest.TestCase):
3 def test(self):
4 val = 1.0 / 3.0
5 try:
6 self.assertAlmostEquals(val, 0.333, places=5)
7 print('assertAlmostEquals passed')
8 except AssertionError as e:
9 print('AssertionError:', type(e).__name__, str(e))
10 self.assertAlmostEqual(val, 0.333, places=5)
11 print('assertEqual passed')
12Test().test()
--- orig.py	2026-10-17 17:11:33.814219965 -0400
+++ fixed.py	2026-10-17 17:11:34.214224066 -0400
@@ -3,7 +3,7 @@
     def test(self):
         val = 1.0 / 3.0
         try:
-            self.assertAlmostEquals(val, 0.333, places=5)
+            self.assertAlmostEqual(val, 0.333, places=5)
             print('assertAlmostEquals passed')
         except AssertionError as e:
             print('AssertionError:', type(e).__name__, str(e))
r1-p007 · Comments attached to deprecated method line
1import unittest
2class Test(unittest.TestCase):
3 def test(self):
4 # This check validates user input equivalence
5 self.assertEquals('hello', 'hello') # inline: critical
6 print('Comment preserved and check passed')
7Test().test()
--- orig.py	2026-10-17 17:11:34.442226404 -0400
+++ fixed.py	2026-10-17 17:11:34.851230597 -0400
@@ -2,6 +2,6 @@
 class Test(unittest.TestCase):
     def test(self):
         # This check validates user input equivalence
-        self.assertEquals('hello', 'hello')  # inline: critical
+        self.assertEqual('hello', 'hello')  # inline: critical
         print('Comment preserved and check passed')
 Test().test()
r1-p008 · IPython-like reload simulation: module state delay
1import unittest
2import sys
3# Simulate IPython reload: restore deprecated alias after import
4if 'unittest' in sys.modules:
5 unittest.TestCase.assertEquals = lambda self, a, b: self.assertEqual(a, b)
6class Test(unittest.TestCase):
7 def test(self):
8 try:
9 self.assertEquals(1, 1)
10 print('Success via restored alias')
11 except AttributeError as e:
12 print('AttributeError:', type(e).__name__, str(e))
13Test().test()
--- orig.py	2026-10-17 17:11:34.995232074 -0400
+++ fixed.py	2026-10-17 17:11:35.246234647 -0400
@@ -6,7 +6,7 @@
 class Test(unittest.TestCase):
     def test(self):
         try:
-            self.assertEquals(1, 1)
+            self.assertEqual(1, 1)
             print('Success via restored alias')
         except AttributeError as e:
             print('AttributeError:', type(e).__name__, str(e))
Success via restored alias