Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

assigning_non_slot.py 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. """ Checks assigning attributes not found in class slots
  2. will trigger assigning-non-slot warning.
  3. """
  4. # pylint: disable=too-few-public-methods, no-init, missing-docstring, no-absolute-import, import-error
  5. from collections import deque
  6. from missing import Unknown
  7. class Empty(object):
  8. """ empty """
  9. class Bad(object):
  10. """ missing not in slots. """
  11. __slots__ = ['member']
  12. def __init__(self):
  13. self.missing = 42 # [assigning-non-slot]
  14. class Bad2(object):
  15. """ missing not in slots """
  16. __slots__ = [deque.__name__, 'member']
  17. def __init__(self):
  18. self.deque = 42
  19. self.missing = 42 # [assigning-non-slot]
  20. class Bad3(Bad):
  21. """ missing not found in slots """
  22. __slots__ = ['component']
  23. def __init__(self):
  24. self.component = 42
  25. self.member = 24
  26. self.missing = 42 # [assigning-non-slot]
  27. super(Bad3, self).__init__()
  28. class Good(Empty):
  29. """ missing not in slots, but Empty doesn't
  30. specify __slots__.
  31. """
  32. __slots__ = ['a']
  33. def __init__(self):
  34. self.missing = 42
  35. class Good2(object):
  36. """ Using __dict__ in slots will be safe. """
  37. __slots__ = ['__dict__', 'comp']
  38. def __init__(self):
  39. self.comp = 4
  40. self.missing = 5
  41. class PropertyGood(object):
  42. """ Using properties is safe. """
  43. __slots__ = ['tmp', '_value']
  44. @property
  45. def test(self):
  46. return self._value
  47. @test.setter
  48. def test(self, value):
  49. # pylint: disable=attribute-defined-outside-init
  50. self._value = value
  51. def __init__(self):
  52. self.test = 42
  53. class PropertyGood2(object):
  54. """ Using properties in the body of the class is safe. """
  55. __slots__ = ['_value']
  56. def _getter(self):
  57. return self._value
  58. def _setter(self, value):
  59. # pylint: disable=attribute-defined-outside-init
  60. self._value = value
  61. test = property(_getter, _setter)
  62. def __init__(self):
  63. self.test = 24
  64. class UnicodeSlots(object):
  65. """Using unicode objects in __slots__ is okay.
  66. On Python 3.3 onward, u'' is equivalent to '',
  67. so this test should be safe for both versions.
  68. """
  69. __slots__ = (u'first', u'second')
  70. def __init__(self):
  71. self.first = 42
  72. self.second = 24
  73. class DataDescriptor(object):
  74. def __init__(self, name, default=''):
  75. self.__name = name
  76. self.__default = default
  77. def __get__(self, inst, cls):
  78. return getattr(inst, self.__name, self.__default)
  79. def __set__(self, inst, value):
  80. setattr(inst, self.__name, value)
  81. class NonDataDescriptor(object):
  82. def __get__(self, inst, cls):
  83. return 42
  84. class SlotsWithDescriptor(object):
  85. __slots__ = ['_err']
  86. data_descriptor = DataDescriptor('_err')
  87. non_data_descriptor = NonDataDescriptor()
  88. missing_descriptor = Unknown()
  89. def dont_emit_for_descriptors():
  90. inst = SlotsWithDescriptor()
  91. # This should not emit, because attr is
  92. # a data descriptor
  93. inst.data_descriptor = 'foo'
  94. inst.non_data_descriptor = 'lala' # [assigning-non-slot]
  95. return
  96. class ClassWithSlots(object):
  97. __slots__ = ['foobar']
  98. class ClassReassigningDunderClass(object):
  99. __slots__ = ['foobar']
  100. def release(self):
  101. self.__class__ = ClassWithSlots
  102. class ClassReassingingInvalidLayoutClass(object):
  103. __slots__ = []
  104. def release(self):
  105. self.__class__ = ClassWithSlots # [assigning-non-slot]