1import unittest 2 3 4class TestLoadAttrCache(unittest.TestCase): 5 def test_descriptor_added_after_optimization(self): 6 class Descriptor: 7 pass 8 9 class C: 10 def __init__(self): 11 self.x = 1 12 x = Descriptor() 13 14 def f(o): 15 return o.x 16 17 o = C() 18 for i in range(1025): 19 assert f(o) == 1 20 21 Descriptor.__get__ = lambda self, instance, value: 2 22 Descriptor.__set__ = lambda *args: None 23 24 self.assertEqual(f(o), 2) 25 26 def test_metaclass_descriptor_added_after_optimization(self): 27 class Descriptor: 28 pass 29 30 class Metaclass(type): 31 attribute = Descriptor() 32 33 class Class(metaclass=Metaclass): 34 attribute = True 35 36 def __get__(self, instance, owner): 37 return False 38 39 def __set__(self, instance, value): 40 return None 41 42 def f(): 43 return Class.attribute 44 45 for _ in range(1025): 46 self.assertTrue(f()) 47 48 Descriptor.__get__ = __get__ 49 Descriptor.__set__ = __set__ 50 51 for _ in range(1025): 52 self.assertFalse(f()) 53 54 def test_metaclass_descriptor_shadows_class_attribute(self): 55 class Metaclass(type): 56 @property 57 def attribute(self): 58 return True 59 60 class Class(metaclass=Metaclass): 61 attribute = False 62 63 def f(): 64 return Class.attribute 65 66 for _ in range(1025): 67 self.assertTrue(f()) 68 69 def test_metaclass_set_descriptor_after_optimization(self): 70 class Metaclass(type): 71 pass 72 73 class Class(metaclass=Metaclass): 74 attribute = True 75 76 @property 77 def attribute(self): 78 return False 79 80 def f(): 81 return Class.attribute 82 83 for _ in range(1025): 84 self.assertTrue(f()) 85 86 Metaclass.attribute = attribute 87 88 for _ in range(1025): 89 self.assertFalse(f()) 90 91 def test_metaclass_del_descriptor_after_optimization(self): 92 class Metaclass(type): 93 @property 94 def attribute(self): 95 return True 96 97 class Class(metaclass=Metaclass): 98 attribute = False 99 100 def f(): 101 return Class.attribute 102 103 for _ in range(1025): 104 self.assertTrue(f()) 105 106 del Metaclass.attribute 107 108 for _ in range(1025): 109 self.assertFalse(f()) 110 111 def test_type_descriptor_shadows_attribute_method(self): 112 class Class: 113 mro = None 114 115 def f(): 116 return Class.mro 117 118 for _ in range(1025): 119 self.assertIsNone(f()) 120 121 def test_type_descriptor_shadows_attribute_member(self): 122 class Class: 123 __base__ = None 124 125 def f(): 126 return Class.__base__ 127 128 for _ in range(1025): 129 self.assertIs(f(), object) 130 131 def test_type_descriptor_shadows_attribute_getset(self): 132 class Class: 133 __name__ = "Spam" 134 135 def f(): 136 return Class.__name__ 137 138 for _ in range(1025): 139 self.assertEqual(f(), "Class") 140 141 def test_metaclass_getattribute(self): 142 class Metaclass(type): 143 def __getattribute__(self, name): 144 return True 145 146 class Class(metaclass=Metaclass): 147 attribute = False 148 149 def f(): 150 return Class.attribute 151 152 for _ in range(1025): 153 self.assertTrue(f()) 154 155 def test_metaclass_swap(self): 156 class OldMetaclass(type): 157 @property 158 def attribute(self): 159 return True 160 161 class NewMetaclass(type): 162 @property 163 def attribute(self): 164 return False 165 166 class Class(metaclass=OldMetaclass): 167 pass 168 169 def f(): 170 return Class.attribute 171 172 for _ in range(1025): 173 self.assertTrue(f()) 174 175 Class.__class__ = NewMetaclass 176 177 for _ in range(1025): 178 self.assertFalse(f()) 179 180 def test_load_shadowing_slot_should_raise_type_error(self): 181 class Class: 182 __slots__ = ("slot",) 183 184 class Sneaky: 185 __slots__ = ("shadowed",) 186 shadowing = Class.slot 187 188 def f(o): 189 o.shadowing 190 191 o = Sneaky() 192 o.shadowed = 42 193 194 for _ in range(1025): 195 with self.assertRaises(TypeError): 196 f(o) 197 198 def test_store_shadowing_slot_should_raise_type_error(self): 199 class Class: 200 __slots__ = ("slot",) 201 202 class Sneaky: 203 __slots__ = ("shadowed",) 204 shadowing = Class.slot 205 206 def f(o): 207 o.shadowing = 42 208 209 o = Sneaky() 210 211 for _ in range(1025): 212 with self.assertRaises(TypeError): 213 f(o) 214 215 def test_load_borrowed_slot_should_not_crash(self): 216 class Class: 217 __slots__ = ("slot",) 218 219 class Sneaky: 220 borrowed = Class.slot 221 222 def f(o): 223 o.borrowed 224 225 o = Sneaky() 226 227 for _ in range(1025): 228 with self.assertRaises(TypeError): 229 f(o) 230 231 def test_store_borrowed_slot_should_not_crash(self): 232 class Class: 233 __slots__ = ("slot",) 234 235 class Sneaky: 236 borrowed = Class.slot 237 238 def f(o): 239 o.borrowed = 42 240 241 o = Sneaky() 242 243 for _ in range(1025): 244 with self.assertRaises(TypeError): 245 f(o) 246 247 248class TestLoadMethodCache(unittest.TestCase): 249 def test_descriptor_added_after_optimization(self): 250 class Descriptor: 251 pass 252 253 class Class: 254 attribute = Descriptor() 255 256 def __get__(self, instance, owner): 257 return lambda: False 258 259 def __set__(self, instance, value): 260 return None 261 262 def attribute(): 263 return True 264 265 instance = Class() 266 instance.attribute = attribute 267 268 def f(): 269 return instance.attribute() 270 271 for _ in range(1025): 272 self.assertTrue(f()) 273 274 Descriptor.__get__ = __get__ 275 Descriptor.__set__ = __set__ 276 277 for _ in range(1025): 278 self.assertFalse(f()) 279 280 def test_metaclass_descriptor_added_after_optimization(self): 281 class Descriptor: 282 pass 283 284 class Metaclass(type): 285 attribute = Descriptor() 286 287 class Class(metaclass=Metaclass): 288 def attribute(): 289 return True 290 291 def __get__(self, instance, owner): 292 return lambda: False 293 294 def __set__(self, instance, value): 295 return None 296 297 def f(): 298 return Class.attribute() 299 300 for _ in range(1025): 301 self.assertTrue(f()) 302 303 Descriptor.__get__ = __get__ 304 Descriptor.__set__ = __set__ 305 306 for _ in range(1025): 307 self.assertFalse(f()) 308 309 def test_metaclass_descriptor_shadows_class_attribute(self): 310 class Metaclass(type): 311 @property 312 def attribute(self): 313 return lambda: True 314 315 class Class(metaclass=Metaclass): 316 def attribute(): 317 return False 318 319 def f(): 320 return Class.attribute() 321 322 for _ in range(1025): 323 self.assertTrue(f()) 324 325 def test_metaclass_set_descriptor_after_optimization(self): 326 class Metaclass(type): 327 pass 328 329 class Class(metaclass=Metaclass): 330 def attribute(): 331 return True 332 333 @property 334 def attribute(self): 335 return lambda: False 336 337 def f(): 338 return Class.attribute() 339 340 for _ in range(1025): 341 self.assertTrue(f()) 342 343 Metaclass.attribute = attribute 344 345 for _ in range(1025): 346 self.assertFalse(f()) 347 348 def test_metaclass_del_descriptor_after_optimization(self): 349 class Metaclass(type): 350 @property 351 def attribute(self): 352 return lambda: True 353 354 class Class(metaclass=Metaclass): 355 def attribute(): 356 return False 357 358 def f(): 359 return Class.attribute() 360 361 for _ in range(1025): 362 self.assertTrue(f()) 363 364 del Metaclass.attribute 365 366 for _ in range(1025): 367 self.assertFalse(f()) 368 369 def test_type_descriptor_shadows_attribute_method(self): 370 class Class: 371 def mro(): 372 return ["Spam", "eggs"] 373 374 def f(): 375 return Class.mro() 376 377 for _ in range(1025): 378 self.assertEqual(f(), ["Spam", "eggs"]) 379 380 def test_type_descriptor_shadows_attribute_member(self): 381 class Class: 382 def __base__(): 383 return "Spam" 384 385 def f(): 386 return Class.__base__() 387 388 for _ in range(1025): 389 self.assertNotEqual(f(), "Spam") 390 391 def test_metaclass_getattribute(self): 392 class Metaclass(type): 393 def __getattribute__(self, name): 394 return lambda: True 395 396 class Class(metaclass=Metaclass): 397 def attribute(): 398 return False 399 400 def f(): 401 return Class.attribute() 402 403 for _ in range(1025): 404 self.assertTrue(f()) 405 406 def test_metaclass_swap(self): 407 class OldMetaclass(type): 408 @property 409 def attribute(self): 410 return lambda: True 411 412 class NewMetaclass(type): 413 @property 414 def attribute(self): 415 return lambda: False 416 417 class Class(metaclass=OldMetaclass): 418 pass 419 420 def f(): 421 return Class.attribute() 422 423 for _ in range(1025): 424 self.assertTrue(f()) 425 426 Class.__class__ = NewMetaclass 427 428 for _ in range(1025): 429 self.assertFalse(f()) 430 431 432if __name__ == "__main__": 433 import unittest 434 unittest.main() 435