You can attach data only to objects, which have __dict__-member. Not all objects have it - for example builtin classes like int, float, list and so on do not. This is an optimization, because otherwise instances of those classes would need too much memory - a dictionary has a quite large memory footprint.
Also for normal classes one could use __slots__, thus removing __dict__-member and prohibiting dynamic addition of attributes to an object of this class. E.g.
class A:
    pass
setattr(A(),'b', 2)
works, but
class B:
    __slots__ = 'b'
setattr(B(),'c', 2)
doesn't work, as class B has no slot with name c and no __dict__.
Thus, the answer to your question is: for some classes (as the tuple_iterator) you cannot.
If you really need to, you can wrap tuple_iterator in a class with __dict__ and append the new attribute to the wrapper-object:
class IterWrapper:
    def __init__(self, it):
        self.it=it
    def __next__(self):
        return next(self.it)   
    def __iter__(self): # for testing
        return self
and now:
iw=IterWrapper(iter((1,2,3)))
setattr(iw, "a", 2)
print(iw.a)          # prints 2
print(list(iw))      # prints [1,2,3]
has the desired behavior.