Python Stack Implementation This is my Stack implementation in Python.

class Stack:
    def __init__(self):
        self.head = None
        self.size = 0

    def push(self, item):
        node = Node(item)
        if not self.head:
            self.head = node
        else:
            node.next = self.head
            self.head = node
        self.size += 1

    def pop(self):
        if self.size == 0:
            raise ValueError('Popping off an empty stack!')
        item = self.head.val
        self.head = self.head.next
        return item

    def peek(self):
        if self.size == 0:
            raise ValueError('Peeking into an empty stack!')
        return self.head.val

    def __iter__(self):
        return self

    def __next__(self):
        if self.head:
            curr = self.head
        else:
            raise StopIteration()
        self.head = self.head.next
        return curr.val

class Node:
    def __init__(self, val):
        self.val = val
        self.next = None


Need comments on primarily 3 aspects -


Is there anything, just plain wrong?
How to improve efficiency of this design?
What more can I add to make it an actually usable data structure beyond the ADT specification?
In terms of implementation, and making it more efficient, I don't think the linked list adds any particular value. I would rather see you implement the stack using a built-in list, which will improve both memory performance and speed.

So far, you have implemented push, pop, peek and iteration. Why iteration? I'm glad that it's destructive, but I don't understand why you felt you needed that.

I would suggest that you look at Python's Common Sequence Operations to see which you can implement. If you choose not to make the stack transparent, that's okay, but it might limit applicability. A transparent stack should be able to support in, count, maybe indexing, etc.

Likewise, have a look at the Mutable Sequence Types section and common operations. Also, check out the Abstract Base Classes for collections, and add whatever parent class(es) you implement.

Keep in mind that Python is a "consenting adult language." There is not a great regard for private data and access control. Instead, the expectation is that you will implement as much as you can, and not be surprised if someone wants to peek. So, I'd suggest trying to build as transparent and well-integrated a class as possible: allow accessing items on the stack via s[i] notation, support things like .find() and .count(), and inherit from whatever ABCs you support. If your stack is iterable, make sure you implement an Iterable abc. (Or Sequence, or Collection, or ...)