""" Checks that classes uses valid __slots__ """

# pylint: disable=too-few-public-methods, missing-docstring
# pylint: disable=using-constant-test, wrong-import-position, no-else-return, line-too-long, unused-private-member
from collections import deque

def func():
    if True:
        return ("a", "b", "c")
    else:
        return [str(var) for var in range(3)]


class NotIterable:
    def __iter_(self):
        """ do nothing """

class Good:
    __slots__ = ()

class SecondGood:
    __slots__ = []

class ThirdGood:
    __slots__ = ['a']

class FourthGood:
    __slots__ = (f'a{i}' for i in range(10))

class FifthGood:
    __slots__ = deque(["a", "b", "c"])

class SixthGood:
    __slots__ = {"a": "b", "c": "d"}

class SeventhGood:
    """type-annotated __slots__ with no value"""
    __slots__: str

class EigthGood:
    """Multiple __slots__ declared in the class"""
    x = 1
    if x:
        __slots__: str
    else:
        __slots__ = ("y",)

class Bad: # [invalid-slots]
    __slots__ = list

class SecondBad:  # [invalid-slots]
    __slots__ = 1

class ThirdBad:
    __slots__ = ('a', 2)  # [invalid-slots-object]

class FourthBad:  # [invalid-slots]
    __slots__ = NotIterable()

class FifthBad:
    __slots__ = ("a", "b", "")  # [invalid-slots-object]

class SixthBad:  # [single-string-used-for-slots]
    __slots__ = "a"

class SeventhBad:  # [single-string-used-for-slots]
    __slots__ = ('foo')  # [superfluous-parens]

class EighthBad:  # [single-string-used-for-slots]
    __slots__ = deque.__name__

class NinthBad:
    __slots__ = [str]  # [invalid-slots-object]

class TenthBad:
    __slots__ = [1 + 2 + 3]  # [invalid-slots-object]

class EleventhBad:  # [invalid-slots]
    __slots__ = None

class TwelfthBad:  # [invalid-slots]
    """One valid & one invalid __slots__ value"""
    x = 1
    if x:
        __slots__ = ("y",)
    else:
        __slots__ = None

class PotentiallyGood:
    __slots__ = func()

class PotentiallySecondGood:
    __slots__ = ('a', deque.__name__)


class Metaclass(type):

    def __iter__(cls):
        for value in range(10):
            yield str(value)


class IterableClass(metaclass=Metaclass):
    pass

class PotentiallyThirdGood:
    __slots__ = IterableClass

class PotentiallyFourthGood:
    __slots__ = Good.__slots__


class ValueInSlotConflict:
    __slots__ = ('first', 'second', 'third', 'fourth') # [class-variable-slots-conflict, class-variable-slots-conflict, class-variable-slots-conflict]
    first = None

    @property
    def third(self):
        return 42

    def fourth(self):
        return self.third


class Parent:
    first = 42


class ChildNotAffectedByValueInSlot(Parent):
    __slots__ = ('first', )
