this repo has no description
at trunk 1438 lines 46 kB view raw
1#!/usr/bin/env python3 2import sys 3import unittest 4 5from test_support import pyro_only 6 7try: 8 from builtins import _non_heaptype 9 10 from _builtins import _gc 11except ImportError: 12 pass 13 14 15Py_TPFLAGS_HEAPTYPE = 1 << 9 16Py_TPFLAGS_BASETYPE = 1 << 10 17Py_TPFLAGS_READY = 1 << 12 18Py_TPFLAGS_READYING = 1 << 13 19Py_TPFLAGS_IS_ABSTRACT = 1 << 20 20Py_TPFLAGS_LONG_SUBCLASS = 1 << 24 21Py_TPFLAGS_LIST_SUBCLASS = 1 << 25 22Py_TPFLAGS_TUPLE_SUBCLASS = 1 << 26 23Py_TPFLAGS_BYTES_SUBCLASS = 1 << 27 24Py_TPFLAGS_UNICODE_SUBCLASS = 1 << 28 25Py_TPFLAGS_DICT_SUBCLASS = 1 << 29 26Py_TPFLAGS_BASE_EXC_SUBCLASS = 1 << 30 27Py_TPFLAGS_TYPE_SUBCLASS = 1 << 31 28 29 30class TypeTests(unittest.TestCase): 31 def test_abstract_methods_get_with_builtin_type_raises_attribute_error(self): 32 with self.assertRaises(AttributeError) as context: 33 type.__abstractmethods__ 34 self.assertEqual(str(context.exception), "__abstractmethods__") 35 36 def test_abstract_methods_get_with_type_subclass_raises_attribute_error(self): 37 class Foo(type): 38 pass 39 40 with self.assertRaises(AttributeError) as context: 41 Foo.__abstractmethods__ 42 self.assertEqual(str(context.exception), "__abstractmethods__") 43 44 def test_abstract_methods_get_with_non_type_raises_type_error(self): 45 with self.assertRaises(TypeError): 46 type.__dict__["__abstractmethods__"].__get__(42) 47 48 def test_abstract_methods_set_with_builtin_type_raises_type_error(self): 49 with self.assertRaises(TypeError) as context: 50 int.__abstractmethods__ = ["foo"] 51 self.assertEqual( 52 str(context.exception), 53 "can't set attributes of built-in/extension type 'int'", 54 ) 55 56 def test_abstract_methods_get_with_type_subclass_sets_attribute(self): 57 class Foo(type): 58 pass 59 60 Foo.__abstractmethods__ = 1 61 self.assertEqual(Foo.__abstractmethods__, 1) 62 63 def test_abstract_methods_del_with_builtin_type_raises_type_error(self): 64 with self.assertRaises(TypeError) as context: 65 del str.__abstractmethods__ 66 self.assertEqual( 67 str(context.exception), 68 "can't set attributes of built-in/extension type 'str'", 69 ) 70 71 def test_abstract_methods_del_unset_with_type_subclass_raises_attribute_error(self): 72 class Foo(type): 73 pass 74 75 with self.assertRaises(AttributeError) as context: 76 del Foo.__abstractmethods__ 77 self.assertEqual(str(context.exception), "__abstractmethods__") 78 79 def test_abstract_methods_del_with_non_type_raises_type_error(self): 80 with self.assertRaises(TypeError): 81 type.__dict__["__abstractmethods__"].__delete__(42) 82 83 def test_abstract_methods_set_with_non_type_raises_type_error(self): 84 with self.assertRaises(TypeError): 85 type.__dict__["__abstractmethods__"].__set__(42, []) 86 87 def test_builtin_types_have_no_module_attribute(self): 88 from types import FrameType 89 90 self.assertNotIn("__module__", int.__dict__) 91 self.assertNotIn("__module__", object.__dict__) 92 self.assertNotIn("__module__", tuple.__dict__) 93 self.assertNotIn("__module__", FrameType.__dict__) 94 95 def test_delattr_deletes_class_attribute(self): 96 class C: 97 fld = 4 98 99 self.assertTrue(hasattr(C, "fld")) 100 self.assertIs(type.__delattr__(C, "fld"), None) 101 self.assertFalse(hasattr(C, "fld")) 102 103 def test_delattr_raises_type_error_with_instance(self): 104 class C: 105 fld = 4 106 107 c = C() 108 self.assertRaisesRegex( 109 TypeError, 110 "'__delattr__' .* 'type' object.* a 'C'", 111 type.__delattr__, 112 c, 113 "fld", 114 ) 115 116 def test_dunder_base_with_object_type_returns_none(self): 117 self.assertIs(object.__base__, None) 118 119 def test_dunder_base_with_builtin_type_returns_supertype(self): 120 self.assertIs(bool.__base__, int) 121 self.assertIs(int.__base__, object) 122 self.assertIs(str.__base__, object) 123 self.assertIs(type.__base__, object) 124 125 def test_dunder_base_with_user_type_returns_best_base(self): 126 class A: 127 pass 128 129 class B(A, str): 130 pass 131 132 class C(B): 133 pass 134 135 self.assertIs(A.__base__, object) 136 self.assertIs(B.__base__, str) 137 self.assertIs(C.__base__, B) 138 139 def test_dunder_bases_del_with_builtin_type_raises_type_error(self): 140 with self.assertRaises(TypeError) as context: 141 del object.__bases__ 142 self.assertEqual( 143 str(context.exception), 144 "can't set attributes of built-in/extension type 'object'", 145 ) 146 147 def test_dunder_bases_del_with_user_type_raises_type_error(self): 148 class C: 149 pass 150 151 with self.assertRaises(TypeError) as context: 152 del C.__bases__ 153 self.assertEqual(str(context.exception), "can't delete C.__bases__") 154 155 def test_dunder_bases_del_with_non_type_raises_type_error(self): 156 with self.assertRaises(TypeError): 157 type.__dict__["__bases__"].__delete__(42) 158 159 def test_dunder_bases_get_with_builtin_type_returns_tuple(self): 160 self.assertEqual(object.__bases__, ()) 161 self.assertEqual(type.__bases__, (object,)) 162 self.assertEqual(int.__bases__, (object,)) 163 self.assertEqual(bool.__bases__, (int,)) 164 165 def test_dunder_bases_get_with_user_type_returns_tuple(self): 166 class A: 167 pass 168 169 class B: 170 pass 171 172 class C(A): 173 pass 174 175 class D(C, B): 176 pass 177 178 self.assertEqual(A.__bases__, (object,)) 179 self.assertEqual(B.__bases__, (object,)) 180 self.assertEqual(C.__bases__, (A,)) 181 self.assertEqual(D.__bases__, (C, B)) 182 183 def test_dunder_bases_get_with_non_type_raises_type_error(self): 184 with self.assertRaises(TypeError): 185 type.__dict__["__bases__"].__get__(42) 186 187 def test_dunder_basicsize_get_with_non_type_raises_type_error(self): 188 with self.assertRaises(TypeError): 189 type.__dict__["__basicsize__"].__get__(42) 190 191 def test_dunder_call_with_non_type_self_raises_type_error(self): 192 self.assertRaisesRegex( 193 TypeError, 194 "'__call__' .* 'type' object.* a 'int'", 195 type.__call__, 196 5, 197 ) 198 199 def test_dunder_dir_with_non_type_object_raises_type_error(self): 200 with self.assertRaises(TypeError): 201 type.__dir__(None) 202 203 def test_dunder_doc_on_empty_class_is_none(self): 204 class C: 205 pass 206 207 self.assertIsNone(C.__doc__) 208 instance = C() 209 self.assertIsNone(instance.__doc__) 210 211 def test_dunder_doc_accessible_via_instance(self): 212 class C: 213 """docstring""" 214 215 pass 216 217 self.assertEqual(C.__doc__, "docstring") 218 instance = C() 219 self.assertEqual(instance.__doc__, "docstring") 220 221 def test_type_dunder_doc_is_not_inheritable(self): 222 class C: 223 """docstring""" 224 225 pass 226 227 class D(C): 228 pass 229 230 self.assertEqual(C.__doc__, "docstring") 231 self.assertIsNone(D.__doc__) 232 233 def test_dunder_flags_returns_basetype_set(self): 234 class C: 235 pass 236 237 self.assertTrue(object.__flags__ & Py_TPFLAGS_BASETYPE) 238 self.assertTrue(float.__flags__ & Py_TPFLAGS_BASETYPE) 239 self.assertTrue(C.__flags__ & Py_TPFLAGS_BASETYPE) 240 241 def test_dunder_flags_returns_basetype_clear(self): 242 self.assertFalse(bool.__flags__ & Py_TPFLAGS_BASETYPE) 243 str_iter_type = type(iter("")) 244 self.assertFalse(str_iter_type.__flags__ & Py_TPFLAGS_BASETYPE) 245 246 def test_dunder_flags_with_managed_type_is_heap_type(self): 247 class C: 248 pass 249 250 self.assertTrue(C.__flags__ & Py_TPFLAGS_HEAPTYPE) 251 252 def test_dunder_flags_with_managed_type_is_ready(self): 253 class C: 254 pass 255 256 self.assertTrue(C.__flags__ & Py_TPFLAGS_READY) 257 self.assertFalse(C.__flags__ & Py_TPFLAGS_READYING) 258 259 def test_dunder_flags_without_dunder_abstractmethods_returns_false(self): 260 class C: 261 pass 262 263 with self.assertRaises(AttributeError): 264 C.__abstractmethods__ 265 266 self.assertFalse(C.__flags__ & Py_TPFLAGS_IS_ABSTRACT) 267 268 def test_dunder_flags_with_empty_dunder_abstractmethods_returns_false(self): 269 import abc 270 271 class C(metaclass=abc.ABCMeta): 272 pass 273 274 self.assertEqual(len(C.__abstractmethods__), 0) 275 self.assertFalse(C.__flags__ & Py_TPFLAGS_IS_ABSTRACT) 276 277 def test_dunder_flags_with_non_empty_dunder_abstractmethods_returns_true(self): 278 import abc 279 280 class C(metaclass=abc.ABCMeta): 281 @abc.abstractmethod 282 def foo(self): 283 pass 284 285 self.assertEqual(len(C.__abstractmethods__), 1) 286 self.assertTrue(C.__flags__ & Py_TPFLAGS_IS_ABSTRACT) 287 288 def test_dunder_flags_with_non_type_raises_type_error(self): 289 with self.assertRaises(TypeError): 290 type.__dict__["__flags__"].__get__(42) 291 292 def test_dunder_flags_sets_long_subclass_if_int_subclass(self): 293 class C: 294 pass 295 296 self.assertFalse(C.__flags__ & Py_TPFLAGS_LONG_SUBCLASS) 297 298 class D(int): 299 pass 300 301 self.assertTrue(int.__flags__ & Py_TPFLAGS_LONG_SUBCLASS) 302 self.assertTrue(D.__flags__ & Py_TPFLAGS_LONG_SUBCLASS) 303 304 def test_dunder_flags_sets_list_subclass_if_list_subclass(self): 305 class C: 306 pass 307 308 self.assertFalse(C.__flags__ & Py_TPFLAGS_LIST_SUBCLASS) 309 310 class D(list): 311 pass 312 313 self.assertTrue(list.__flags__ & Py_TPFLAGS_LIST_SUBCLASS) 314 self.assertTrue(D.__flags__ & Py_TPFLAGS_LIST_SUBCLASS) 315 316 def test_dunder_flags_sets_tuple_subclass_if_tuple_subclass(self): 317 class C: 318 pass 319 320 self.assertFalse(C.__flags__ & Py_TPFLAGS_TUPLE_SUBCLASS) 321 322 class D(tuple): 323 pass 324 325 self.assertTrue(tuple.__flags__ & Py_TPFLAGS_TUPLE_SUBCLASS) 326 self.assertTrue(D.__flags__ & Py_TPFLAGS_TUPLE_SUBCLASS) 327 328 def test_dunder_flags_sets_bytes_subclass_if_bytes_subclass(self): 329 class C: 330 pass 331 332 self.assertFalse(C.__flags__ & Py_TPFLAGS_BYTES_SUBCLASS) 333 334 class D(bytes): 335 pass 336 337 self.assertTrue(bytes.__flags__ & Py_TPFLAGS_BYTES_SUBCLASS) 338 self.assertTrue(D.__flags__ & Py_TPFLAGS_BYTES_SUBCLASS) 339 340 def test_dunder_flags_sets_unicode_subclass_if_str_subclass(self): 341 class C: 342 pass 343 344 self.assertFalse(C.__flags__ & Py_TPFLAGS_UNICODE_SUBCLASS) 345 346 class D(str): 347 pass 348 349 self.assertTrue(str.__flags__ & Py_TPFLAGS_UNICODE_SUBCLASS) 350 self.assertTrue(D.__flags__ & Py_TPFLAGS_UNICODE_SUBCLASS) 351 352 def test_dunder_flags_sets_dict_subclass_if_dict_subclass(self): 353 class C: 354 pass 355 356 self.assertFalse(C.__flags__ & Py_TPFLAGS_DICT_SUBCLASS) 357 358 class D(dict): 359 pass 360 361 self.assertTrue(dict.__flags__ & Py_TPFLAGS_DICT_SUBCLASS) 362 self.assertTrue(D.__flags__ & Py_TPFLAGS_DICT_SUBCLASS) 363 364 def test_dunder_flags_sets_base_exc_subclass_if_base_exception_subclass(self): 365 class C: 366 pass 367 368 self.assertFalse(C.__flags__ & Py_TPFLAGS_BASE_EXC_SUBCLASS) 369 370 class D(BaseException): 371 pass 372 373 self.assertTrue(BaseException.__flags__ & Py_TPFLAGS_BASE_EXC_SUBCLASS) 374 self.assertTrue(D.__flags__ & Py_TPFLAGS_BASE_EXC_SUBCLASS) 375 self.assertTrue(MemoryError.__flags__ & Py_TPFLAGS_BASE_EXC_SUBCLASS) 376 377 def test_dunder_flags_sets_type_subclass_if_type_subclass(self): 378 class C: 379 pass 380 381 self.assertFalse(C.__flags__ & Py_TPFLAGS_TYPE_SUBCLASS) 382 383 class D(type): 384 pass 385 386 self.assertTrue(type.__flags__ & Py_TPFLAGS_TYPE_SUBCLASS) 387 self.assertTrue(D.__flags__ & Py_TPFLAGS_TYPE_SUBCLASS) 388 389 def test_dunder_init_with_no_name_or_object_param_raises_type_error(self): 390 with self.assertRaises(TypeError) as context: 391 type.__init__(type) 392 393 self.assertIn("type.__init__() takes 1 or 3 arguments", str(context.exception)) 394 395 def test_dunder_init_with_too_many_args_raises_type_error(self): 396 with self.assertRaises(TypeError) as context: 397 type.__init__(type, "C", (), {}, 1, 2, 3, 4, 5, foobar=42) 398 399 self.assertIn("type.__init__() takes 1 or 3 arguments", str(context.exception)) 400 401 def test_dunder_init_with_kwargs_does_not_raise(self): 402 type.__init__(type, "C", (), {}, foobar=42) 403 404 def test_dunder_instancecheck_with_instance_returns_true(self): 405 self.assertIs(int.__instancecheck__(3), True) 406 self.assertIs(int.__instancecheck__(False), True) 407 self.assertIs(object.__instancecheck__(type), True) 408 self.assertIs(str.__instancecheck__("123"), True) 409 self.assertIs(type.__instancecheck__(type, int), True) 410 self.assertIs(type.__instancecheck__(type, object), True) 411 412 def test_dunder_instancecheck_with_non_instance_returns_false(self): 413 self.assertIs(bool.__instancecheck__(3), False) 414 self.assertIs(int.__instancecheck__("123"), False) 415 self.assertIs(str.__instancecheck__(b"123"), False) 416 self.assertIs(type.__instancecheck__(type, 3), False) 417 418 def test_dunder_subclasscheck_with_subclass_returns_true(self): 419 self.assertIs(int.__subclasscheck__(int), True) 420 self.assertIs(int.__subclasscheck__(bool), True) 421 self.assertIs(object.__subclasscheck__(int), True) 422 self.assertIs(object.__subclasscheck__(type), True) 423 424 def test_dunder_subclasscheck_with_non_subclass_returns_false(self): 425 self.assertIs(bool.__subclasscheck__(int), False) 426 self.assertIs(int.__subclasscheck__(object), False) 427 self.assertIs(str.__subclasscheck__(object), False) 428 self.assertIs(type.__subclasscheck__(type, object), False) 429 430 def test_dunder_module_set_on_builtin_raises_type_error(self): 431 with self.assertRaisesRegex(TypeError, ".*int.*"): 432 int.__module__ = "foo" 433 with self.assertRaisesRegex(TypeError, ".*int.*"): 434 type.__dict__["__module__"].__set__(int, "foo") 435 436 def test_dunder_module_sets_module(self): 437 class C: 438 pass 439 440 type.__dict__["__module__"].__set__(C, "foo") 441 self.assertEqual(type.__dict__["__module__"].__get__(C), "foo") 442 self.assertEqual(C.__dict__["__module__"], "foo") 443 self.assertEqual(C.__module__, "foo") 444 445 def test_dunder_module_set_accepts_anything(self): 446 class C: 447 pass 448 449 type.__dict__["__module__"].__set__(C, 42.42) 450 self.assertEqual(C.__module__, 42.42) 451 452 C.__module__ = None 453 self.assertIsNone(type.__dict__["__module__"].__get__(C)) 454 455 def test_dunder_module_with_builtin_type_returns_builtins(self): 456 self.assertEqual(int.__module__, "builtins") 457 self.assertEqual(dict.__module__, "builtins") 458 self.assertEqual(OSError.__module__, "builtins") 459 self.assertEqual(type.__module__, "builtins") 460 461 def test_dunder_name_returns_name(self): 462 class FooBar: 463 pass 464 465 self.assertEqual(FooBar.__name__, "FooBar") 466 self.assertEqual(type.__dict__["__name__"].__get__(FooBar), "FooBar") 467 468 def test_dunder_name_sets_name(self): 469 class C: 470 pass 471 472 type.__dict__["__name__"].__set__(C, "foo") 473 self.assertEqual(type.__dict__["__name__"].__get__(C), "foo") 474 self.assertEqual(C.__name__, "foo") 475 476 def test_dunder_name_set_with_non_string_raises_type_error(self): 477 class C: 478 pass 479 480 with self.assertRaisesRegex( 481 TypeError, "can only assign string to C.__name__, not 'int'" 482 ): 483 C.__name__ = 42 484 with self.assertRaisesRegex( 485 TypeError, "can only assign string to C.__name__, not 'float'" 486 ): 487 type.__dict__["__name__"].__set__(C, 1.2) 488 489 def test_dunder_name_set_on_builtin_raises_type_error(self): 490 with self.assertRaisesRegex(TypeError, ".*int.*"): 491 int.__name__ = "foo" 492 with self.assertRaisesRegex(TypeError, ".*int.*"): 493 type.__dict__["__name__"].__set__(int, "foo") 494 495 def test_dunder_new_with_one_arg_returns_type_of_arg(self): 496 class C: 497 pass 498 499 self.assertIs(type.__new__(type, 1), int) 500 self.assertIs(type.__new__(type, "hello"), str) 501 self.assertIs(type.__new__(type, C()), C) 502 503 def test_dunder_new_with_non_type_cls_raises_type_error(self): 504 with self.assertRaises(TypeError): 505 type.__new__(1, "X", (object,), {}) 506 507 def test_dunder_new_with_non_str_name_raises_type_error(self): 508 with self.assertRaises(TypeError): 509 type.__new__(type, 1, (object,), {}) 510 511 def test_dunder_new_with_non_tuple_bases_raises_type_error(self): 512 with self.assertRaises(TypeError): 513 type.__new__(type, "X", [object], {}) 514 515 def test_dunder_new_with_non_basetype_raises_type_error(self): 516 with self.assertRaisesRegex( 517 TypeError, "type 'bool' is not an acceptable base type" 518 ): 519 type.__new__(type, "X", (bool,), {}) 520 521 def test_dunder_new_with_non_dict_type_dict_raises_type_error(self): 522 with self.assertRaises(TypeError): 523 type.__new__(type, "X", (object,), 1) 524 525 def test_dunder_new_with_duplicated_base_raises_type_error(self): 526 class C: 527 pass 528 529 error_msg = "duplicate base class C" 530 with self.assertRaisesRegex(TypeError, error_msg): 531 type.__new__(type, "X", (C, C), {}) 532 533 def test_dunder_new_returns_type_instance(self): 534 X = type.__new__(type, "X", (object,), {}) 535 self.assertIsInstance(X, type) 536 self.assertEqual(X.__name__, "X") 537 self.assertEqual(X.__qualname__, "X") 538 self.assertTrue(X.__flags__ & Py_TPFLAGS_HEAPTYPE) 539 540 def test_dunder_new_sets_dunder_module(self): 541 globals = {"__name__": 8.13} 542 X = eval("type('X', (), {})", globals) # noqa: P204 543 self.assertEqual(X.__module__, 8.13) 544 self.assertEqual(X.__dict__["__module__"], 8.13) 545 546 def test_dunder_new_does_not_override_dunder_module(self): 547 X = type.__new__(type, "X", (), {"__module__": "foobar"}) 548 self.assertEqual(X.__module__, "foobar") 549 self.assertEqual(X.__dict__["__module__"], "foobar") 550 551 def test_dunder_new_sets_qualname(self): 552 X = type.__new__(type, "foo.bar", (), {}) 553 self.assertEqual(X.__qualname__, "foo.bar") 554 self.assertNotIn("__qualname__", X.__dict__) 555 556 def test_dunder_new_sets_qualname_from_dict(self): 557 namespace = {"__qualname__": "quux"} 558 X = type.__new__(type, "X", (), namespace) 559 self.assertEqual(X.__qualname__, "quux") 560 self.assertNotIn("__qualname__", X.__dict__) 561 self.assertEqual(namespace["__qualname__"], "quux") 562 563 def test_dunder_new_with_non_string_qualname_raises_type_error(self): 564 with self.assertRaisesRegex( 565 TypeError, "type __qualname__ must be a str, not float" 566 ): 567 type.__new__(type, "X", (), {"__qualname__": 2.3}) 568 569 def test_dunder_new_adds_to_base_dunder_subclasses(self): 570 A = type.__new__(type, "A", (object,), {}) 571 B = type.__new__(type, "B", (object,), {}) 572 C = type.__new__(type, "C", (A, B), {}) 573 D = type.__new__(type, "D", (A,), {}) 574 self.assertEqual(A.__subclasses__(), [C, D]) 575 self.assertEqual(B.__subclasses__(), [C]) 576 self.assertEqual(C.__subclasses__(), []) 577 self.assertEqual(D.__subclasses__(), []) 578 579 @unittest.skipIf( 580 sys.version_info < (3, 10) and sys.implementation.name != "skybison", 581 "Union requrires CPython 3.10", 582 ) 583 def test_dunder_or_returns_union(self): 584 from types import Union 585 586 t = int | float 587 self.assertIs(type(t), Union) 588 self.assertEqual(t.__args__, (int, float)) 589 t = float | int 590 self.assertIs(type(t), Union) 591 self.assertEqual(t.__args__, (float, int)) 592 t = str | None 593 self.assertIs(type(t), Union) 594 self.assertEqual(t.__args__, (str, type(None))) 595 596 @unittest.skipIf( 597 sys.version_info < (3, 10) and sys.implementation.name != "skybison", 598 "Union requrires CPython 3.10", 599 ) 600 def test_dunder_ror_returns_union(self): 601 from types import Union 602 603 t = None | bytes 604 self.assertIs(type(t), Union) 605 self.assertEqual(t.__args__, (type(None), bytes)) 606 607 def test_dunder_qualname_returns_qualname(self): 608 class C: 609 __qualname__ = "bar" 610 611 self.assertEqual(C.__qualname__, "bar") 612 self.assertEqual(type.__dict__["__qualname__"].__get__(C), "bar") 613 614 def test_dunder_qualname_sets_qualname(self): 615 class C: 616 pass 617 618 type.__dict__["__qualname__"].__set__(C, "baz") 619 self.assertEqual(C.__qualname__, "baz") 620 C.__qualname__ = "bam" 621 self.assertEqual(type.__dict__["__qualname__"].__get__(C), "bam") 622 623 def test_dunder_qualname_set_with_non_string_raises_type_error(self): 624 class C: 625 pass 626 627 with self.assertRaisesRegex( 628 TypeError, "can only assign string to C.__qualname__, not 'int'" 629 ): 630 C.__qualname__ = 42 631 with self.assertRaisesRegex( 632 TypeError, "can only assign string to C.__qualname__, not 'float'" 633 ): 634 type.__dict__["__qualname__"].__set__(C, 1.2) 635 636 def test_dunder_qualname_set_on_builtin_raises_type_error(self): 637 with self.assertRaisesRegex(TypeError, ".*list.*"): 638 list.__qualname__ = "foo" 639 with self.assertRaisesRegex(TypeError, ".*list.*"): 640 type.__dict__["__qualname__"].__set__(list, "foo") 641 642 def test_dunder_repr_with_bytes_raises_type_error(self): 643 with self.assertRaises(TypeError): 644 type.__repr__(b"") 645 646 def test_dunder_repr_returns_string_with_module_and_name(self): 647 class C: 648 pass 649 650 self.assertEqual( 651 type.__repr__(C), 652 "<class '__main__.TypeTests.test_dunder_repr_returns_string_with_module_and_name.<locals>.C'>", 653 ) 654 655 def test_dunder_repr_for_builtins_returns_string_with_only_name(self): 656 self.assertEqual(type.__repr__(list), "<class 'list'>") 657 self.assertEqual(type.__repr__(type), "<class 'type'>") 658 self.assertEqual(type.__repr__(TypeError), "<class 'TypeError'>") 659 660 def test_dunder_repr_for_imported_class_returns_string_with_module_and_name(self): 661 self.assertEqual( 662 type.__repr__(unittest.case.TestCase), "<class 'unittest.case.TestCase'>" 663 ) 664 665 def test_dunder_subclasses_with_leaf_type_returns_empty_list(self): 666 class C: 667 pass 668 669 self.assertEqual(C.__subclasses__(), []) 670 671 def test_dunder_subclasses_with_supertype_returns_list(self): 672 class C: 673 pass 674 675 class D(C): 676 pass 677 678 self.assertEqual(C.__subclasses__(), [D]) 679 680 def test_dunder_subclasses_returns_new_list(self): 681 class C: 682 pass 683 684 self.assertIsNot(C.__subclasses__(), C.__subclasses__()) 685 686 @pyro_only 687 def test_dunder_subclasses_does_not_return_dead_types(self): 688 class C: 689 pass 690 691 class D(C): 692 pass 693 694 D = None # noqa: F811, F841 695 _gc() 696 self.assertEqual(type.__subclasses__(C), []) 697 698 @pyro_only 699 def test_dunder_subclasses_with_multiple_subclasses_returns_list(self): 700 class B: 701 pass 702 703 class S0(B): 704 pass 705 706 class S1(B): 707 pass 708 709 class S2(B): 710 pass 711 712 class S3(B): 713 pass 714 715 class S4(B): 716 pass 717 718 S1 = None # noqa: F811, F841 719 S3 = None # noqa: F811, F841 720 _gc() 721 self.assertEqual(len(type.__subclasses__(B)), 3) 722 S0 = None # noqa: F811, F841 723 _gc() 724 self.assertEqual(type.__subclasses__(B), [S2, S4]) 725 726 def test_mro_returns_list(self): 727 class C: 728 pass 729 730 mro = C.mro() 731 self.assertIsInstance(mro, list) 732 self.assertEqual(mro, [C, object]) 733 734 def test_mro_with_multiple_inheritance_returns_linearization(self): 735 class A: 736 pass 737 738 class B: 739 pass 740 741 class C(A, B): 742 pass 743 744 mro = type.mro(C) 745 self.assertIsInstance(mro, list) 746 self.assertEqual(mro, [C, A, B, object]) 747 748 def test_mro_with_invalid_linearization_raises_type_error(self): 749 class A: 750 pass 751 752 class B(A): 753 pass 754 755 with self.assertRaisesRegex( 756 TypeError, 757 r"Cannot create a consistent method resolution\s+order \(MRO\) for bases A, B", 758 ): 759 760 class C(A, B): 761 pass 762 763 def test_mro_with_custom_method_propagates_exception(self): 764 class Meta(type): 765 def mro(cls): 766 raise KeyError 767 768 with self.assertRaises(KeyError): 769 770 class Foo(metaclass=Meta): 771 pass 772 773 def test_new_calculates_metaclass_and_calls_dunder_new(self): 774 class M0(type): 775 def __new__(metacls, name, bases, type_dict, **kwargs): 776 metacls.new_args = (metacls, name, bases, kwargs) 777 return type.__new__(metacls, name, bases, type_dict) 778 779 class M1(M0): 780 foo = 7 781 782 class A(metaclass=M0): 783 pass 784 785 class B(metaclass=M1): 786 pass 787 788 C = type.__new__(type, "C", (A, B), {}, bar=8) 789 self.assertIs(type(C), M1) 790 self.assertEqual(C.new_args, (M1, "C", (A, B), {"bar": 8})) 791 self.assertEqual(C.foo, 7) 792 793 def test_new_with_mro_entries_base_raises_type_error(self): 794 class X: 795 def __mro_entries__(self, bases): 796 return (object,) 797 798 pseudo_base = X() 799 with self.assertRaises(TypeError) as ctx: 800 type.__new__(type, "C", (pseudo_base,), {}) 801 self.assertEqual( 802 str(ctx.exception), 803 "type() doesn't support MRO entry resolution; use types.new_class()", 804 ) 805 806 def test_mro_returning_iterable_returns_class_with_mro_tuple(self): 807 class A: 808 foo = 42 809 810 class X: 811 def __init__(self, cls): 812 self.cls = cls 813 814 def __iter__(self): 815 return iter((self.cls, A)) 816 817 class Meta(type): 818 def mro(cls): 819 return X(cls) 820 821 C = Meta.__new__(Meta, "C", (object,), {}) 822 self.assertIs(type(C.__mro__), tuple) 823 self.assertEqual(C.__mro__, (C, A)) 824 self.assertEqual(C.foo, 42) 825 826 def test_new_calls_init_subclass(self): 827 class Foo: 828 def __init_subclass__(cls, *args, **kwargs): 829 cls.called_init = True 830 831 self.assertIsInstance(cls, type) 832 self.assertIn("foo", kwargs) 833 834 class Bar(Foo, foo=True): 835 pass 836 837 self.assertTrue(Bar.called_init) 838 839 def test_new_duplicates_dict(self): 840 d = {"foo": 42, "bar": 17} 841 T = type("T", (object,), d) 842 d["foo"] = -7 843 del d["bar"] 844 self.assertEqual(T.foo, 42) 845 self.assertEqual(T.bar, 17) 846 T.foo = 20 847 self.assertEqual(d["foo"], -7) 848 self.assertFalse("bar" in d) 849 850 @pyro_only 851 def test_non_heaptype_returns_non_heaptype(self): 852 X = _non_heaptype("X", (), {}) 853 self.assertFalse(X.__flags__ & Py_TPFLAGS_HEAPTYPE) 854 with self.assertRaises(TypeError): 855 X.foo = 1 856 857 def test_non_heaptype_has_no_module_attribute(self): 858 from types import SimpleNamespace 859 860 self.assertNotIn("__module__", SimpleNamespace.__dict__) 861 self.assertNotIn("__module__", zip.__dict__) 862 self.assertNotIn("__module__", map.__dict__) 863 864 def test_setattr_with_metaclass_does_not_abort(self): 865 class Meta(type): 866 pass 867 868 class C(metaclass=Meta): 869 __slots__ = "attr" 870 871 def __init__(self, data): 872 self.attr = data 873 874 m = C("foo") 875 self.assertEqual(m.attr, "foo") 876 m.attr = "bar" 877 self.assertEqual(m.attr, "bar") 878 879 def test_type_new_sets_name_on_attributes(self): 880 class Descriptor: 881 def __set_name__(self, owner, name): 882 self.owner = owner 883 self.name = name 884 885 class A: 886 d = Descriptor() 887 888 self.assertEqual(A.d.name, "d") 889 self.assertIs(A.d.owner, A) 890 891 def test_type_new_propagates_set_name_error(self): 892 class Descriptor: 893 def __set_name__(self, owner, name): 894 raise Exception("I prefer to remain unnamed.") 895 896 with self.assertRaises(RuntimeError) as context: 897 898 class A: 899 d = Descriptor() 900 901 self.assertIn("A", str(context.exception)) 902 self.assertIn("Descriptor", str(context.exception)) 903 904 def test_type_new_with_metaclass_sets_name(self): 905 class Meta(type): 906 def __new__(metacls, name, bases, ns): 907 ret = super().__new__(metacls, name, bases, ns) 908 self.assertEqual(ret.d.name, "d") 909 self.assertIs(ret.d.owner, ret) 910 return 0 911 912 class Descriptor: 913 def __set_name__(self, owner, name): 914 self.owner = owner 915 self.name = name 916 917 class A(metaclass=Meta): 918 d = Descriptor() 919 920 self.assertEqual(A, 0) 921 922 def test_type_new_with_set_name_raising_error_propagates_exception(self): 923 class SetNameDescriptor: 924 def __get__(self, instance, owner): 925 raise ValueError("Don't call, please.") 926 927 class Descriptor: 928 __set_name__ = SetNameDescriptor() 929 930 with self.assertRaises(ValueError): 931 932 class A: 933 d = Descriptor() 934 935 def test_non_type_with_type_getattribute(self): 936 class C: 937 __getattribute__ = type.__getattribute__ 938 939 c = C() 940 with self.assertRaises(TypeError): 941 c.foo 942 943 944class TypeProxyTests(unittest.TestCase): 945 def setUp(self): 946 class A: 947 placeholder = "placeholder_value" 948 949 class B(A): 950 pass 951 952 def make_placeholder(): 953 b = B() 954 return b.placeholder 955 956 self.tested_type = B 957 self.type_proxy = B.__dict__ 958 self.assertEqual(make_placeholder(), "placeholder_value") 959 960 def test_dunder_contains_with_non_type_proxy_raises_type_error(self): 961 with self.assertRaises(TypeError): 962 type(self.type_proxy).__contains__(None, None) 963 964 def test_dunder_contains_returns_true_for_existing_item(self): 965 self.tested_type.x = 40 966 self.assertTrue(self.type_proxy.__contains__("x")) 967 968 def test_dunder_contains_returns_false_for_not_existing_item(self): 969 self.assertFalse(self.type_proxy.__contains__("x")) 970 971 def test_dunder_contains_returns_false_for_placeholder(self): 972 self.assertFalse(self.type_proxy.__contains__("placeholder")) 973 974 def test_copy_with_non_type_proxy_raises_type_error(self): 975 with self.assertRaises(TypeError): 976 type(self.type_proxy).copy(None) 977 978 def test_copy_returns_dict_copy(self): 979 self.tested_type.x = 40 980 result = self.type_proxy.copy() 981 self.assertEqual(type(result), dict) 982 self.assertEqual(result["x"], 40) 983 self.tested_type.y = 50 984 self.assertNotIn("y", result) 985 986 def test_dunder_getitem_with_non_type_proxy_raises_type_error(self): 987 with self.assertRaises(TypeError): 988 type(self.type_proxy).__getitem__(None, None) 989 990 def test_dunder_getitem_for_existing_key_returns_that_item(self): 991 self.tested_type.x = 40 992 self.assertEqual(self.type_proxy.__getitem__("x"), 40) 993 994 def test_dunder_getitem_for_not_existing_key_raises_key_error(self): 995 with self.assertRaises(KeyError) as context: 996 self.type_proxy.__getitem__("x") 997 self.assertIn("'x'", str(context.exception)) 998 999 def test_dunder_getitem_for_placeholder_raises_key_error(self): 1000 with self.assertRaises(KeyError) as context: 1001 self.type_proxy.__getitem__("placeholder") 1002 self.assertIn("'placeholder'", str(context.exception)) 1003 1004 def test_dunder_iter_with_non_type_proxy_raises_type_error(self): 1005 with self.assertRaises(TypeError): 1006 type(self.type_proxy).__iter__(None) 1007 1008 def test_dunder_iter_returns_key_iterator(self): 1009 self.tested_type.x = 40 1010 self.tested_type.y = 50 1011 result = self.type_proxy.__iter__() 1012 self.assertTrue(hasattr(result, "__next__")) 1013 result_list = list(result) 1014 self.assertIn("x", result_list) 1015 self.assertIn("y", result_list) 1016 1017 def test_dunder_len_with_non_type_proxy_raises_type_error(self): 1018 with self.assertRaises(TypeError): 1019 type(self.type_proxy).__len__(None) 1020 1021 def test_dunder_len_returns_num_items(self): 1022 length = self.type_proxy.__len__() 1023 self.tested_type.x = 40 1024 self.assertEqual(self.type_proxy.__len__(), length + 1) 1025 1026 def test_dunder_len_returns_num_items_excluding_placeholder(self): 1027 length = self.type_proxy.__len__() 1028 # Overwrite the existing placeholder by creating a real one under the same name. 1029 self.tested_type.placeholder = 1 1030 self.assertEqual(self.type_proxy.__len__(), length + 1) 1031 1032 def test_dunder_repr_with_non_type_proxy_raises_type_error(self): 1033 with self.assertRaises(TypeError): 1034 type(self.type_proxy).__repr__(None) 1035 1036 def test_dunder_repr_returns_str_containing_existing_items(self): 1037 self.tested_type.x = 40 1038 self.tested_type.y = 50 1039 result = self.type_proxy.__repr__() 1040 self.assertIsInstance(result, str) 1041 self.assertIn("'x': 40", result) 1042 self.assertIn("'y': 50", result) 1043 1044 def test_dunder_repr_returns_str_not_containing_placeholder(self): 1045 result = self.type_proxy.__repr__() 1046 self.assertNotIn("'placeholder'", result) 1047 1048 def test_get_with_non_type_proxy_raises_type_error(self): 1049 with self.assertRaises(TypeError): 1050 type(self.type_proxy).get(None, None) 1051 1052 def test_get_returns_existing_item_value(self): 1053 self.tested_type.x = 40 1054 self.assertEqual(self.type_proxy.get("x"), 40) 1055 1056 def test_get_with_default_for_non_existing_item_value_returns_that_default(self): 1057 self.assertEqual(self.type_proxy.get("x", -1), -1) 1058 1059 def test_get_for_non_existing_item_returns_none(self): 1060 self.assertIs(self.type_proxy.get("x"), None) 1061 1062 def test_get_for_placeholder_returns_none(self): 1063 self.assertIs(self.type_proxy.get("placeholder"), None) 1064 1065 def test_items_with_non_type_proxy_raises_type_error(self): 1066 with self.assertRaises(TypeError): 1067 type(self.type_proxy).items(None) 1068 1069 def test_items_returns_container_for_key_value_pairs(self): 1070 self.tested_type.x = 40 1071 self.tested_type.y = 50 1072 result = self.type_proxy.items() 1073 self.assertTrue(hasattr(result, "__iter__")) 1074 result_list = list(iter(result)) 1075 self.assertIn(("x", 40), result_list) 1076 self.assertIn(("y", 50), result_list) 1077 1078 def test_keys_with_non_type_proxy_raises_type_error(self): 1079 with self.assertRaises(TypeError): 1080 type(self.type_proxy).keys(None) 1081 1082 def test_keys_returns_container_for_keys(self): 1083 self.tested_type.x = 40 1084 self.tested_type.y = 50 1085 result = self.type_proxy.keys() 1086 self.assertTrue(hasattr(result, "__iter__")) 1087 result_list = list(iter(result)) 1088 self.assertIn("x", result_list) 1089 self.assertIn("y", result_list) 1090 1091 def test_keys_returns_key_iterator_excluding_placeholder(self): 1092 result = self.type_proxy.keys() 1093 self.assertNotIn("placeholder", result) 1094 1095 def test_values_with_non_type_proxy_raises_type_error(self): 1096 with self.assertRaises(TypeError): 1097 type(self.type_proxy).values(None) 1098 1099 def test_values_returns_container_for_values(self): 1100 self.tested_type.x = 1243314135 1101 self.tested_type.y = -1243314135 1102 result = self.type_proxy.values() 1103 self.assertTrue(hasattr(result, "__iter__")) 1104 result_list = list(iter(result)) 1105 self.assertIn(1243314135, result_list) 1106 self.assertIn(-1243314135, result_list) 1107 1108 def test_values_returns_iterator_excluding_placeholder_value(self): 1109 result = self.type_proxy.values() 1110 self.assertNotIn("placeholder_value", result) 1111 1112 1113class DunderSlotsTests(unittest.TestCase): 1114 def test_with_non_str_raises_type_error(self): 1115 with self.assertRaises(TypeError) as context: 1116 1117 class C: 1118 __slots__ = "a", 1 1119 1120 self.assertIn( 1121 "__slots__ items must be strings, not 'int'", str(context.exception) 1122 ) 1123 1124 def test_with_non_identifier_raises_type_error(self): 1125 with self.assertRaises(TypeError) as context: 1126 1127 class C: 1128 __slots__ = "a", ";;" 1129 1130 self.assertIn("__slots__ must be identifiers", str(context.exception)) 1131 1132 def test_with_duplicated_dunder_dict_raises_type_error(self): 1133 with self.assertRaises(TypeError) as context: 1134 1135 class C: 1136 __slots__ = "a", "__dict__", "__dict__" 1137 1138 self.assertIn( 1139 "__dict__ slot disallowed: we already got one", str(context.exception) 1140 ) 1141 1142 def test_with_conflicting_name_raises_value_error(self): 1143 with self.assertRaises(ValueError) as context: 1144 1145 class C: 1146 __slots__ = "a" 1147 a = "conflicting" 1148 1149 self.assertIn( 1150 "'a' in __slots__ conflicts with class variable", str(context.exception) 1151 ) 1152 1153 def test_without_dunder_dict_removes_dunder_dict_type_attribute(self): 1154 class C: 1155 __slots__ = "a" 1156 1157 self.assertNotIn("__dict__", C.__dict__) 1158 1159 def test_with_dunder_dict_keeps_dunder_dict_type_attribute(self): 1160 class C: 1161 __slots__ = "a", "__dict__" 1162 1163 self.assertIn("__dict__", C.__dict__) 1164 1165 def test_slot_descriptor_dunder_get_with_none_returns_type(self): 1166 class C: 1167 __slots__ = "a" 1168 1169 descriptor = C.__dict__["a"] 1170 slot_descriptor_type = type(descriptor) 1171 self.assertIs(descriptor.__get__(None, slot_descriptor_type), descriptor) 1172 1173 def test_slot_descriptor_dunder_get_with_instance_returns_attribute(self): 1174 class C: 1175 __slots__ = "a" 1176 1177 def __init__(self): 1178 self.a = 10 1179 1180 descriptor = C.__dict__["a"] 1181 instance = C() 1182 self.assertEqual(descriptor.__get__(instance), 10) 1183 1184 def test_slot_descriptor_dunder_get_with_instance_and_none_owner_returns_attribute( 1185 self, 1186 ): 1187 class C: 1188 __slots__ = "a" 1189 1190 def __init__(self): 1191 self.a = 10 1192 1193 descriptor = C.__dict__["a"] 1194 instance = C() 1195 self.assertEqual(descriptor.__get__(instance, None), 10) 1196 1197 def test_slot_descriptor_dunder_get_with_none_instance_and_none_owner_raises_type_error( 1198 self, 1199 ): 1200 class C: 1201 __slots__ = "a" 1202 1203 descriptor = C.__dict__["a"] 1204 1205 with self.assertRaises(TypeError) as context: 1206 descriptor.__get__(None, None) 1207 self.assertEqual( 1208 str(context.exception), 1209 "__get__(None, None) is invalid", 1210 ) 1211 1212 def test_slot_descriptor_dunder_delete_returns_none(self): 1213 class C: 1214 __slots__ = "a" 1215 1216 def __init__(self): 1217 self.a = 10 1218 1219 descriptor = C.__dict__["a"] 1220 instance = C() 1221 self.assertEqual(descriptor.__delete__(instance), None) 1222 1223 def test_slot_descriptor_dunder_delete_none_raises_type_error(self): 1224 class C: 1225 __slots__ = "a" 1226 1227 descriptor = C.__dict__["a"] 1228 1229 with self.assertRaises(TypeError) as context: 1230 descriptor.__delete__(None) 1231 self.assertEqual( 1232 str(context.exception), 1233 "descriptor 'a' for 'C' objects doesn't apply to a 'NoneType' object", 1234 ) 1235 1236 def test_creates_type_attributes(self): 1237 class C: 1238 __slots__ = "a", "b", "c" 1239 1240 self.assertIn("a", C.__dict__) 1241 self.assertIn("b", C.__dict__) 1242 self.assertIn("c", C.__dict__) 1243 1244 slot_descriptor_type = type(C.a) 1245 self.assertTrue(hasattr(slot_descriptor_type, "__get__")) 1246 self.assertTrue(hasattr(slot_descriptor_type, "__set__")) 1247 self.assertIsInstance(C.a, slot_descriptor_type) 1248 self.assertIsInstance(C.b, slot_descriptor_type) 1249 self.assertIsInstance(C.c, slot_descriptor_type) 1250 1251 def test_sharing_same_layout_base_can_servce_as_bases(self): 1252 class C: 1253 __slots__ = "x" 1254 1255 class D(C): 1256 pass 1257 1258 class E(C): 1259 __slots__ = "y" 1260 1261 class F(D, E): 1262 pass 1263 1264 self.assertTrue(hasattr(F, "x")) 1265 self.assertTrue(hasattr(F, "y")) 1266 1267 def test_attributes_raises_attribute_error_before_set(self): 1268 class C: 1269 __slots__ = "x" 1270 1271 c = C() 1272 self.assertFalse(hasattr(c, "x")) 1273 with self.assertRaises(AttributeError): 1274 c.x 1275 1276 def test_attributes_return_set_attributes(self): 1277 class C: 1278 __slots__ = "x" 1279 1280 c = C() 1281 c.x = 500 1282 self.assertEqual(c.x, 500) 1283 1284 def test_attributes_raises_attribute_error_after_deletion(self): 1285 class C: 1286 __slots__ = "x" 1287 1288 c = C() 1289 c.x = 50 1290 del c.x 1291 with self.assertRaises(AttributeError): 1292 c.x 1293 1294 def test_attributes_delete_raises_attribute_before_set(self): 1295 class C: 1296 __slots__ = "x" 1297 1298 c = C() 1299 with self.assertRaises(AttributeError): 1300 del c.x 1301 1302 def test_with_sealed_base_seals_type(self): 1303 class C: 1304 __slots__ = () 1305 1306 c = C() 1307 with self.assertRaises(AttributeError): 1308 c.x = 500 1309 self.assertFalse(hasattr(c, "__dict__")) 1310 1311 def test_with_unsealed_base_unseals_type(self): 1312 class C: 1313 pass 1314 1315 class D(C): 1316 __slots__ = () 1317 1318 d = D() 1319 d.x = 500 1320 self.assertEqual(d.x, 500) 1321 self.assertTrue(hasattr(d, "__dict__")) 1322 1323 def test_inherit_from_bases(self): 1324 class C: 1325 __slots__ = () 1326 1327 class D(C): 1328 __slots__ = "x", "y" 1329 1330 class E(D, C): 1331 __slots__ = "z" 1332 1333 e = E() 1334 e.x = 1 1335 e.y = 2 1336 e.z = 3 1337 self.assertEqual(e.x, 1) 1338 self.assertEqual(e.y, 2) 1339 self.assertEqual(e.z, 3) 1340 with self.assertRaises(AttributeError): 1341 e.w = 500 1342 self.assertFalse(hasattr(e, "__dict__")) 1343 1344 def test_inherit_from_builtin_type(self): 1345 class C(dict): 1346 __slots__ = "x" 1347 1348 c = C() 1349 c.x = 500 1350 c["p"] = 4 1351 c["q"] = 5 1352 self.assertEqual(c.x, 500) 1353 self.assertEqual(c["p"], 4) 1354 self.assertEqual(c["q"], 5) 1355 1356 def test_are_independent_from_inherited_slots(self): 1357 class C: 1358 __slots__ = ("a", "c") 1359 1360 class D(C): 1361 __slots__ = ("b", "c") 1362 1363 obj = D() 1364 obj.a = 1 1365 obj.b = 2 1366 obj.c = 3 1367 C.c.__set__(obj, 33) 1368 1369 self.assertEqual(obj.a, 1) 1370 self.assertEqual(C.a.__get__(obj), 1) 1371 self.assertEqual(D.a.__get__(obj), 1) 1372 self.assertEqual(obj.b, 2) 1373 with self.assertRaises(AttributeError): 1374 C.b 1375 self.assertEqual(D.b.__get__(obj), 2) 1376 self.assertEqual(obj.c, 3) 1377 self.assertEqual(C.c.__get__(obj), 33) 1378 self.assertEqual(D.c.__get__(obj), 3) 1379 1380 def test_member_descriptor_works_only_for_subtypes(self): 1381 class C: 1382 __slots__ = "x" 1383 1384 class D(C): 1385 __slots__ = "y" 1386 1387 class E: 1388 __slots__ = "x" 1389 1390 d = D() 1391 # C's member_descriptor for "x" works for D instances. 1392 C.x.__set__(d, 500) 1393 self.assertEqual(C.x.__get__(d), 500) 1394 self.assertEqual(d.x, 500) 1395 1396 e = E() 1397 with self.assertRaises(TypeError) as context: 1398 C.x.__set__(e, 500) 1399 self.assertEqual( 1400 str(context.exception), 1401 "descriptor 'x' for 'C' objects doesn't apply to a 'E' object", 1402 ) 1403 1404 e.x = 600 1405 with self.assertRaises(TypeError) as context: 1406 C.x.__get__(e) 1407 self.assertEqual( 1408 str(context.exception), 1409 "descriptor 'x' for 'C' objects doesn't apply to a 'E' object", 1410 ) 1411 1412 def test_private_names_are_mangled(self): 1413 class C: 1414 __slots__ = ("__priv", "__priv_") 1415 1416 def __init__(self): 1417 self.__priv = 42 1418 self.__priv_ = 8 1419 1420 c = C() 1421 self.assertEqual(c._C__priv, 42) 1422 self.assertEqual(c._C__priv_, 8) 1423 1424 def test_names_are_not_mangled(self): 1425 class C: 1426 __slots__ = ("_notpriv", "__notpriv__") 1427 1428 def __init__(self): 1429 self._notpriv = "foo" 1430 self.__notpriv__ = "bar" 1431 1432 c = C() 1433 self.assertEqual(c._notpriv, "foo") 1434 self.assertEqual(c.__notpriv__, "bar") 1435 1436 1437if __name__ == "__main__": 1438 unittest.main()