class_delattr_setattr.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. # test __delattr__ and __setattr__
  2. # feature test for __setattr__/__delattr__
  3. try:
  4. class Test():
  5. def __delattr__(self, attr): pass
  6. del Test().noexist
  7. except AttributeError:
  8. print('SKIP')
  9. raise SystemExit
  10. # this class just prints the calls to see if they were executed
  11. class A():
  12. def __getattr__(self, attr):
  13. print('get', attr)
  14. return 1
  15. def __setattr__(self, attr, val):
  16. print('set', attr, val)
  17. def __delattr__(self, attr):
  18. print('del', attr)
  19. a = A()
  20. # check basic behaviour
  21. print(getattr(a, 'foo'))
  22. setattr(a, 'bar', 2)
  23. delattr(a, 'baz')
  24. # check meta behaviour
  25. getattr(a, '__getattr__') # should not call A.__getattr__
  26. getattr(a, '__setattr__') # should not call A.__getattr__
  27. getattr(a, '__delattr__') # should not call A.__getattr__
  28. setattr(a, '__setattr__', 1) # should call A.__setattr__
  29. delattr(a, '__delattr__') # should call A.__delattr__
  30. # this class acts like a dictionary
  31. class B:
  32. def __init__(self, d):
  33. # store the dict in the class, not instance, so
  34. # we don't get infinite recursion in __getattr_
  35. B.d = d
  36. def __getattr__(self, attr):
  37. if attr in B.d:
  38. return B.d[attr]
  39. else:
  40. raise AttributeError(attr)
  41. def __setattr__(self, attr, value):
  42. B.d[attr] = value
  43. def __delattr__(self, attr):
  44. del B.d[attr]
  45. a = B({"a":1, "b":2})
  46. print(a.a, a.b)
  47. a.a = 3
  48. print(a.a, a.b)
  49. del a.a
  50. try:
  51. print(a.a)
  52. except AttributeError:
  53. print("AttributeError")