| 266 | ) |
| 267 | |
| 268 | def test_pickleness(self): |
| 269 | instrumentation.register_class(MyTest) |
| 270 | instrumentation.register_class(MyTest2) |
| 271 | _register_attribute(MyTest, "user_id", uselist=False, useobject=False) |
| 272 | _register_attribute( |
| 273 | MyTest, "user_name", uselist=False, useobject=False |
| 274 | ) |
| 275 | _register_attribute( |
| 276 | MyTest, "email_address", uselist=False, useobject=False |
| 277 | ) |
| 278 | _register_attribute(MyTest2, "a", uselist=False, useobject=False) |
| 279 | _register_attribute(MyTest2, "b", uselist=False, useobject=False) |
| 280 | |
| 281 | # shouldn't be pickling callables at the class level |
| 282 | |
| 283 | def somecallable(state, passive): |
| 284 | return None |
| 285 | |
| 286 | _register_attribute( |
| 287 | MyTest, |
| 288 | "mt2", |
| 289 | uselist=True, |
| 290 | trackparent=True, |
| 291 | callable_=somecallable, |
| 292 | useobject=True, |
| 293 | ) |
| 294 | |
| 295 | o = MyTest() |
| 296 | o.mt2.append(MyTest2()) |
| 297 | o.user_id = 7 |
| 298 | o.mt2[0].a = "abcde" |
| 299 | pk_o = pickle.dumps(o) |
| 300 | |
| 301 | o2 = pickle.loads(pk_o) |
| 302 | pk_o2 = pickle.dumps(o2) |
| 303 | |
| 304 | # the above is kind of distrurbing, so let's do it again a little |
| 305 | # differently. the string-id in serialization thing is just an |
| 306 | # artifact of pickling that comes up in the first round-trip. |
| 307 | # a -> b differs in pickle memoization of 'mt2', but b -> c will |
| 308 | # serialize identically. |
| 309 | |
| 310 | o3 = pickle.loads(pk_o2) |
| 311 | pk_o3 = pickle.dumps(o3) |
| 312 | o4 = pickle.loads(pk_o3) |
| 313 | |
| 314 | # and lastly make sure we still have our data after all that. |
| 315 | # identical serialization is great, *if* it's complete :) |
| 316 | self.assert_(o4.user_id == 7) |
| 317 | self.assert_(o4.user_name is None) |
| 318 | self.assert_(o4.email_address is None) |
| 319 | self.assert_(len(o4.mt2) == 1) |
| 320 | self.assert_(o4.mt2[0].a == "abcde") |
| 321 | self.assert_(o4.mt2[0].b is None) |
| 322 | |
| 323 | @testing.requires.predictable_gc |
| 324 | def test_state_gc(self): |