Skip to content
Merged
Changes from all commits
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
94 changes: 81 additions & 13 deletions Lib/test/test_super.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""Unit tests for zero-argument super() & related machinery."""

import copy
import pickle
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:
def f(self):
return 'A'
Expand Down Expand Up @@ -91,8 +90,7 @@ def nested():

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

# TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before global declaration
'''
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_various___class___pathologies(self):
# See issue #12370
class X(A):
Expand All @@ -114,20 +112,19 @@ def f():
__class__""", globals(), {})
self.assertIs(type(e.exception), NameError) # Not UnboundLocalError
class X:
global __class__
# global __class__ # TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before global declaration
__class__ = 42
def f():
__class__
self.assertEqual(globals()["__class__"], 42)
del globals()["__class__"]
self.assertNotIn("__class__", X.__dict__)
class X:
nonlocal __class__
# nonlocal __class__ # TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before nonlocal declaration
__class__ = 42
def f():
__class__
self.assertEqual(__class__, 42)
'''

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

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test___class___mro(self):
# See issue #23722
test_class = None
Expand Down Expand Up @@ -449,7 +446,7 @@ def method(self):

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

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: type 'super' is not an acceptable base type
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: type 'super' is not an acceptable base type
def test_super_subclass___class__(self):
class mysuper(super):
pass
Expand All @@ -469,7 +466,8 @@ def test(name):
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
self.assertEqual(mytype.bar, 1)

for _ in range(ADAPTIVE_WARMUP_DELAY):
_testinternalcapi = import_helper.import_module("_testinternalcapi")
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
test("foo1")

def test_reassigned_new(self):
Expand All @@ -488,7 +486,8 @@ class C(B):
def __new__(cls):
return super().__new__(cls)

for _ in range(ADAPTIVE_WARMUP_DELAY):
_testinternalcapi = import_helper.import_module("_testinternalcapi")
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
C()

def test_mixed_staticmethod_hierarchy(self):
Expand All @@ -508,7 +507,8 @@ class C(B):
def some(cls):
return super().some(cls)

for _ in range(ADAPTIVE_WARMUP_DELAY):
_testinternalcapi = import_helper.import_module("_testinternalcapi")
for _ in range(_testinternalcapi.SPECIALIZATION_THRESHOLD):
C.some(C)

@threading_helper.requires_working_threading()
Expand Down Expand Up @@ -544,6 +544,74 @@ def work():
for thread in threads:
thread.join()

def test_special_methods(self):
for e in E(), E:
s = super(C, e)
self.assertEqual(s.__reduce__, e.__reduce__)
self.assertEqual(s.__reduce_ex__, e.__reduce_ex__)
self.assertEqual(s.__getstate__, e.__getstate__)
self.assertNotHasAttr(s, '__getnewargs__')
self.assertNotHasAttr(s, '__getnewargs_ex__')
self.assertNotHasAttr(s, '__setstate__')
self.assertNotHasAttr(s, '__copy__')
self.assertNotHasAttr(s, '__deepcopy__')

def test_pickling(self):
e = E()
e.x = 1
s = super(C, e)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
u = pickle.loads(pickle.dumps(s, proto))
self.assertEqual(u.f(), s.f())
self.assertIs(type(u), type(s))
self.assertIs(type(u.__self__), E)
self.assertEqual(u.__self__.x, 1)
self.assertIs(u.__thisclass__, C)
self.assertIs(u.__self_class__, E)

s = super(C, E)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
with self.subTest(proto=proto):
u = pickle.loads(pickle.dumps(s, proto))
self.assertEqual(u.cm(), s.cm())
self.assertEqual(u.f, s.f)
self.assertIs(type(u), type(s))
self.assertIs(u.__self__, E)
self.assertIs(u.__thisclass__, C)
self.assertIs(u.__self_class__, E)

def test_shallow_copying(self):
s = super(C, E())
self.assertIs(copy.copy(s), s)
s = super(C, E)
self.assertIs(copy.copy(s), s)

def test_deep_copying(self):
e = E()
e.x = [1]
s = super(C, e)
u = copy.deepcopy(s)
self.assertEqual(u.f(), s.f())
self.assertIs(type(u), type(s))
self.assertIsNot(u, s)
self.assertIs(type(u.__self__), E)
self.assertIsNot(u.__self__, e)
self.assertIsNot(u.__self__.x, e.x)
self.assertEqual(u.__self__.x, [1])
self.assertIs(u.__thisclass__, C)
self.assertIs(u.__self_class__, E)

s = super(C, E)
u = copy.deepcopy(s)
self.assertEqual(u.cm(), s.cm())
self.assertEqual(u.f, s.f)
self.assertIsNot(u, s)
self.assertIs(type(u), type(s))
self.assertIs(u.__self__, E)
self.assertIs(u.__thisclass__, C)
self.assertIs(u.__self_class__, E)


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