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.

unpacking_non_sequence.py 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. """Check unpacking non-sequences in assignments. """
  2. # pylint: disable=too-few-public-methods, invalid-name, attribute-defined-outside-init, unused-variable, no-absolute-import
  3. # pylint: disable=using-constant-test, no-init, missing-docstring, wrong-import-order,wrong-import-position,no-else-return
  4. from os import rename as nonseq_func
  5. from six import with_metaclass
  6. from functional.unpacking import nonseq
  7. __revision__ = 0
  8. # Working
  9. class Seq(object):
  10. """ sequence """
  11. def __init__(self):
  12. self.items = range(2)
  13. def __getitem__(self, item):
  14. return self.items[item]
  15. def __len__(self):
  16. return len(self.items)
  17. class Iter(object):
  18. """ Iterator """
  19. def __iter__(self):
  20. for number in range(2):
  21. yield number
  22. def good_unpacking():
  23. """ returns should be unpackable """
  24. if True:
  25. return [1, 2]
  26. else:
  27. return (3, 4)
  28. def good_unpacking2():
  29. """ returns should be unpackable """
  30. return good_unpacking()
  31. class MetaIter(type):
  32. "metaclass that makes classes that use it iterables"
  33. def __iter__(cls):
  34. return iter((1, 2))
  35. class IterClass(with_metaclass(MetaIter)):
  36. "class that is iterable (and unpackable)"
  37. class AbstrClass(object):
  38. "abstract class"
  39. pair = None
  40. def setup_pair(self):
  41. "abstract method"
  42. raise NotImplementedError
  43. def __init__(self):
  44. "error should not be emitted because setup_pair is abstract"
  45. self.setup_pair()
  46. x, y = self.pair
  47. a, b = [1, 2]
  48. a, b = (1, 2)
  49. a, b = set([1, 2])
  50. a, b = {1: 2, 2: 3}
  51. a, b = "xy"
  52. a, b = Seq()
  53. a, b = Iter()
  54. a, b = (number for number in range(2))
  55. a, b = good_unpacking()
  56. a, b = good_unpacking2()
  57. a, b = IterClass
  58. # Not working
  59. class NonSeq(object):
  60. """ does nothing """
  61. a, b = NonSeq() # [unpacking-non-sequence]
  62. a, b = ValueError # [unpacking-non-sequence]
  63. a, b = None # [unpacking-non-sequence]
  64. a, b = 1 # [unpacking-non-sequence]
  65. a, b = nonseq # [unpacking-non-sequence]
  66. a, b = nonseq() # [unpacking-non-sequence]
  67. a, b = nonseq_func # [unpacking-non-sequence]
  68. class ClassUnpacking(object):
  69. """ Check unpacking as instance attributes. """
  70. def test(self):
  71. """ test unpacking in instance attributes. """
  72. self.a, self.b = 1, 2
  73. self.a, self.b = {1: 2, 2: 3}
  74. self.a, self.b = "xy"
  75. self.a, c = "xy"
  76. c, self.a = good_unpacking()
  77. self.a, self.b = Iter()
  78. self.a, self.b = NonSeq() # [unpacking-non-sequence]
  79. self.a, self.b = ValueError # [unpacking-non-sequence]
  80. self.a, c = nonseq_func # [unpacking-non-sequence]
  81. class TestBase(object):
  82. 'base class with `test` method implementation'
  83. @staticmethod
  84. def test(data):
  85. 'default implementation'
  86. return data
  87. class Test(TestBase):
  88. 'child class that overrides `test` method'
  89. def __init__(self):
  90. # no error should be emitted here as `test` is overridden in this class
  91. (self.aaa, self.bbb, self.ccc) = self.test(None)
  92. @staticmethod
  93. def test(data):
  94. 'overridden implementation'
  95. return (1, 2, 3)
  96. import platform
  97. def flow_control_false_positive():
  98. # This used to trigger an unpacking-non-sequence error. The problem was
  99. # partially related to the fact that pylint does not understand flow control,
  100. # but now it does not emit anymore, for this example, due to skipping it when
  101. # determining an inference of multiple potential values.
  102. # In any case, it is good having this repro as a test.
  103. system, node, release, version, machine, processor = platform.uname()
  104. # The previous line raises W0633
  105. return system, node, release, version, machine, processor
  106. def flow_control_unpacking(var=None):
  107. if var is not None:
  108. var0, var1 = var
  109. return var0, var1
  110. return None