summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorGuido van Rossum <guido@dropbox.com>2015-09-05 22:20:57 (GMT)
committerGuido van Rossum <guido@dropbox.com>2015-09-05 22:20:57 (GMT)
commitba5f59089a1ee2761cacd8b207701f1698d3e6e6 (patch)
tree838ddaae925e0d8dfa7136a7ce3341c2738b7a2b /Lib/test
parent6727b3c23511816e61297040f372319239b186ef (diff)
parent37fdcbc4c38ed79f9abc319bdedb26982abccd93 (diff)
downloadcpython-ba5f59089a1ee2761cacd8b207701f1698d3e6e6.zip
cpython-ba5f59089a1ee2761cacd8b207701f1698d3e6e6.tar.gz
cpython-ba5f59089a1ee2761cacd8b207701f1698d3e6e6.tar.bz2
Issue #24912: Prevent __class__ assignment to immutable built-in objects. (Merge 3.5 -> 3.6)
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_descr.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 0ef1a31..c74ebae 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1036,6 +1036,51 @@ order (MRO) for bases """
self.assertTrue(m.__class__ is types.ModuleType)
self.assertFalse(hasattr(m, "a"))
+ # Make sure that builtin immutable objects don't support __class__
+ # assignment, because the object instances may be interned.
+ # We set __slots__ = () to ensure that the subclasses are
+ # memory-layout compatible, and thus otherwise reasonable candidates
+ # for __class__ assignment.
+
+ # The following types have immutable instances, but are not
+ # subclassable and thus don't need to be checked:
+ # NoneType, bool
+
+ class MyInt(int):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ (1).__class__ = MyInt
+
+ class MyFloat(float):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ (1.0).__class__ = MyFloat
+
+ class MyComplex(complex):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ (1 + 2j).__class__ = MyComplex
+
+ class MyStr(str):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ "a".__class__ = MyStr
+
+ class MyBytes(bytes):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ b"a".__class__ = MyBytes
+
+ class MyTuple(tuple):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ ().__class__ = MyTuple
+
+ class MyFrozenSet(frozenset):
+ __slots__ = ()
+ with self.assertRaises(TypeError):
+ frozenset().__class__ = MyFrozenSet
+
def test_slots(self):
# Testing __slots__...
class C0(object):