# special Stack for integers
from stack import Stack


class IntStack(Stack):

    """
    Stack that accepts only integer elements.

    push - raise Exception if non-int pushed
    pop - raise Exception to pop on empty.
    >>>
    """

    def __init__(self: 'IntStack', data: list =None) -> None:
        """Create a new integer stack using data.

        data --- initial contents of list        

        >>> s1 = IntStack()
        >>> s1.push(3)
        >>> s2 = IntStack([3])
        >>> s1 == s2
        True
        """
        # initialize superclass Stack
        Stack.__init__(self)
        
        # use push to ensure elements of data are ints
        if data:
            for element in data:
                self.push(element)

    def push(self: 'IntStack', n: int) -> None:
        """
        Push n if it is an integer, otherwise raise an Exception.

        >>> i = IntStack()
        >>> i.push(3)
        >>> i.pop()
        3
        """

        if isinstance(n, int):
            Stack.push(self, n)
        else:
            raise PushNonIntegerException

    def pop(self: 'IntStack') -> int:
        """
        Remove and return top element.  Raise exception if empty.

        >>> i = IntStack()
        >>> i.push(3)
        >>> i.pop()
        3
        """

        if self.is_empty():
            raise PopEmptyStackException
        else:
            return Stack.pop(self)


class PushNonIntegerException(Exception):
    """Raised when non-integer push attempted"""
    pass


class PopEmptyStackException(Exception):
    """Raised when pop from empty stack attempted"""
    pass


if __name__ == '__main__':
    import doctest
    doctest.testmod()
