Infinitely iterable list class in Python itertools.cycle is cool, but it has an internal "storage" that uses up memory. And I wanted to practice "tampering" with built-in methods of classes, which is a new field for me. I tried to implement a class which mostly behaves like a list, but when we try to iterate over it (with for loop, for example), it would jump back to the beginning when it reaches the end, therefore cycling indefinitely. Here's what I've come up with:

class InfiniteListEmptyError(Exception):
    pass


class InfiniteList(list):
    """
    Pretty much a regular list, but when iterated over, it does not stop in the end. 
    Instead, it iterates indefinitely.
    """

    def __init__(self, arg):
        super(InfiniteList, self).__init__(arg)

    def __getattr__(self, name):
        if name == "it":
            # get iterator
            result = object.__getattribute__(self, name)
        else:
            try:
                result = super(InfiniteList, self).__getattribute__(name)
            except AttributeError:
                try:
                    result = self.it.__getattribute__(name)
                except AttributeError:
                    # Initialize iterator cuz it's not initialized
                    self.__iter__()
                    result = self.it.__getattribute__(name)
        return result

    def __iter__(self):
        it = super(InfiniteList, self).__iter__()
        self.it = it
        return self

    def __next__(self):
        try:
            result = next(self.it)
        except StopIteration:
            self.__iter__()
            try:
                result = next(self.it)
            except StopIteration:
                raise InfiniteListEmptyError("Could not iterate. List is empty!")

        return result

# TESTS

a = InfiniteList(tuple()) #empty list

print(a)
print(a.__length_hint__()) #testing iterator attributes
print(a.__eq__([1,3,5])) # false

# should raise exception, since the list is empty
try:
    for i in a:
        print(i)
except InfiniteListEmptyError:
    print("List is empty!")

a.append(1)
a.extend([3,5])
print(a)
print(a.__eq__([1,3,5])) #true

# infinite loop
for i in a:
    print(i)


It works fine, it does not store an auxiliary list, so it does not consume twice as much memory, like itertools.cycle. But I'm not sure about the possible caveats when it comes to handling attributes. And yeah, I had to implement iterator within the InfiniteList class itself, so I had to redirect the calls to iterator's methods (like __length_hint__) to the saved iterator self.it.
This seems kind of complicated compared to something like this:

def cycle(seq):
    "Generator that yields the elements of a non-empty sequence cyclically."
    i = 0
    while True:
        yield seq[i]
        i = (i + 1) % len(seq)


Or, as Joe Wallis points out in comments:

def cycle(seq):
    "Generator that yields the elements of a non-empty sequence cyclically."
    while True:
        yield from seq