X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update test_super.py from 3.13.9
  • Loading branch information
ShaharNaveh committed Nov 29, 2025
commit c2ea003bc160b187f8d6f3f197029d6df68e680f
310 changes: 268 additions & 42 deletions Lib/test/test_super.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
"""Unit tests for zero-argument super() & related machinery."""

import textwrap
import threading
import unittest
from unittest.mock import patch
from test.support import import_helper, threading_helper


ADAPTIVE_WARMUP_DELAY = 2


class A:
Expand Down Expand Up @@ -84,41 +91,43 @@ def nested():

self.assertEqual(E().f(), 'AE')

# SyntaxError
# def test_various___class___pathologies(self):
# # See issue #12370
# class X(A):
# def f(self):
# return super().f()
# __class__ = 413
# x = X()
# self.assertEqual(x.f(), 'A')
# self.assertEqual(x.__class__, 413)
# class X:
# x = __class__
# def f():
# __class__
# self.assertIs(X.x, type(self))
# with self.assertRaises(NameError) as e:
# exec("""class X:
# __class__
# def f():
# __class__""", globals(), {})
# self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
# class X:
# global __class__
# __class__ = 42
# def f():
# __class__
# self.assertEqual(globals()["__class__"], 42)
# del globals()["__class__"]
# self.assertNotIn("__class__", X.__dict__)
# class X:
# nonlocal __class__
# __class__ = 42
# def f():
# __class__
# self.assertEqual(__class__, 42)
# TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before global declaration
'''
def test_various___class___pathologies(self):
# See issue #12370
class X(A):
def f(self):
return super().f()
__class__ = 413
x = X()
self.assertEqual(x.f(), 'A')
self.assertEqual(x.__class__, 413)
class X:
x = __class__
def f():
__class__
self.assertIs(X.x, type(self))
with self.assertRaises(NameError) as e:
exec("""class X:
__class__
def f():
__class__""", globals(), {})
self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
class X:
global __class__
__class__ = 42
def f():
__class__
self.assertEqual(globals()["__class__"], 42)
del globals()["__class__"]
self.assertNotIn("__class__", X.__dict__)
class X:
nonlocal __class__
__class__ = 42
def f():
__class__
self.assertEqual(__class__, 42)
'''

def test___class___instancemethod(self):
# See issue #14857
Expand Down Expand Up @@ -182,8 +191,7 @@ def f():
B = type("B", (), test_namespace)
self.assertIs(B.f(), B)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test___class___mro(self):
# See issue #23722
test_class = None
Expand All @@ -201,8 +209,7 @@ def f():

self.assertIs(test_class, A)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test___classcell___expected_behaviour(self):
# See issue #23722
class Meta(type):
Expand Down Expand Up @@ -288,17 +295,28 @@ def f(self):
def test_obscure_super_errors(self):
def f():
super()
self.assertRaises(RuntimeError, f)
with self.assertRaisesRegex(RuntimeError, r"no arguments"):
f()

class C:
def f():
super()
with self.assertRaisesRegex(RuntimeError, r"no arguments"):
C.f()

def f(x):
del x
super()
self.assertRaises(RuntimeError, f, None)
with self.assertRaisesRegex(RuntimeError, r"arg\[0\] deleted"):
f(None)

class X:
def f(x):
nonlocal __class__
del __class__
super()
self.assertRaises(RuntimeError, X().f)
with self.assertRaisesRegex(RuntimeError, r"empty __class__ cell"):
X().f()

def test_cell_as_self(self):
class X:
Expand All @@ -322,6 +340,214 @@ def test_super_init_leaks(self):
for i in range(1000):
super.__init__(sp, int, i)

def test_super_argcount(self):
with self.assertRaisesRegex(TypeError, "expected at most"):
super(int, int, int)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "argument 1 must be a type" does not match "Expected type 'type' but 'int' found."
def test_super_argtype(self):
with self.assertRaisesRegex(TypeError, "argument 1 must be a type"):
super(1, int)

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: module 'test.support.import_helper' has no attribute 'ready_to_import'
def test_shadowed_global(self):
source = textwrap.dedent(
"""
class super:
msg = "truly super"

class C:
def method(self):
return super().msg
""",
)
with import_helper.ready_to_import(name="shadowed_super", source=source):
import shadowed_super
self.assertEqual(shadowed_super.C().method(), "truly super")
import_helper.unload("shadowed_super")

def test_shadowed_local(self):
class super:
msg = "quite super"

class C:
def method(self):
return super().msg

self.assertEqual(C().method(), "quite super")

def test_shadowed_dynamic(self):
class MySuper:
msg = "super super"

class C:
def method(self):
return super().msg

with patch(f"{__name__}.super", MySuper) as m:
self.assertEqual(C().method(), "super super")

def test_shadowed_dynamic_two_arg(self):
call_args = []
class MySuper:
def __init__(self, *args):
call_args.append(args)
msg = "super super"

class C:
def method(self):
return super(1, 2).msg

with patch(f"{__name__}.super", MySuper) as m:
self.assertEqual(C().method(), "super super")
self.assertEqual(call_args, [(1, 2)])

def test_attribute_error(self):
class C:
def method(self):
return super().msg

with self.assertRaisesRegex(AttributeError, "'super' object has no attribute 'msg'"):
C().method()

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "argument 1 must be a type" does not match "Expected type 'type' but 'int' found."
def test_bad_first_arg(self):
class C:
def method(self):
return super(1, self).method()

with self.assertRaisesRegex(TypeError, "argument 1 must be a type"):
C().method()

def test_supercheck_fail(self):
class C:
def method(self, type_, obj):
return super(type_, obj).method()

c = C()
err_msg = (
r"super\(type, obj\): obj \({} {}\) is not "
r"an instance or subtype of type \({}\)."
)

cases = (
(int, c, int.__name__, C.__name__, "instance of"),
# obj is instance of type
(C, list(), C.__name__, list.__name__, "instance of"),
# obj is type itself
(C, list, C.__name__, list.__name__, "type"),
)

for case in cases:
with self.subTest(case=case):
type_, obj, type_str, obj_str, instance_or_type = case
regex = err_msg.format(instance_or_type, obj_str, type_str)

with self.assertRaisesRegex(TypeError, regex):
c.method(type_, obj)

def test_super___class__(self):
class C:
def method(self):
return super().__class__

self.assertEqual(C().method(), super)

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: type 'super' is not an acceptable base type
def test_super_subclass___class__(self):
class mysuper(super):
pass

class C:
def method(self):
return mysuper(C, self).__class__

self.assertEqual(C().method(), mysuper)

def test_unusual_getattro(self):
class MyType(type):
pass

def test(name):
mytype = MyType(name, (MyType,), {})
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
self.assertEqual(mytype.bar, 1)

for _ in range(ADAPTIVE_WARMUP_DELAY):
test("foo1")

def test_reassigned_new(self):
class A:
def __new__(cls):
pass

def __init_subclass__(cls):
if "__new__" not in cls.__dict__:
cls.__new__ = cls.__new__

class B(A):
pass

class C(B):
def __new__(cls):
return super().__new__(cls)

for _ in range(ADAPTIVE_WARMUP_DELAY):
C()

def test_mixed_staticmethod_hierarchy(self):
# This test is just a desugared version of `test_reassigned_new`
class A:
@staticmethod
def some(cls, *args, **kwargs):
self.assertFalse(args)
self.assertFalse(kwargs)

class B(A):
def some(cls, *args, **kwargs):
return super().some(cls, *args, **kwargs)

class C(B):
@staticmethod
def some(cls):
return super().some(cls)

for _ in range(ADAPTIVE_WARMUP_DELAY):
C.some(C)

@threading_helper.requires_working_threading()
def test___class___modification_multithreaded(self):
""" Note: this test isn't actually testing anything on its own.
It requires a sys audithook to be set to crash on older Python.
This should be the case anyways as our test suite sets
an audit hook.
"""

class Foo:
pass

class Bar:
pass

thing = Foo()
def work():
foo = thing
for _ in range(200):
foo.__class__ = Bar
type(foo)
foo.__class__ = Foo
type(foo)


threads = []
for _ in range(6):
thread = threading.Thread(target=work)
thread.start()
threads.append(thread)

for thread in threads:
thread.join()


if __name__ == "__main__":
unittest.main()
Loading
Loading
X Tutup