def eval_power(parse_result):
        """
        Exponentiate a list of numbers, right to left. Can also have minus signs
        interspersed, which means to flip the sign of the exponent.

        Arguments:
            parse_result: A list of numbers and "-" strings, to be read as exponentiated
            [a, b, c, d] = a^b^c^d
            [a, "-", c, d] = a^(-(c^d))

        Usage
        =====
        >>> MathExpression.eval_power([4,3,2])  # Evaluate 4^3^2
        262144
        >>> MathExpression.eval_power([2,"-",2,2])  # Evaluate 2^(-(2^2))
        0.0625
        """

        data = parse_result[:]
        result = data.pop()
        while data:
            # Result contains the current exponent
            working = data.pop()
            if isinstance(working, six.text_type) and working == "-":
                result = -result
            else:
                # working is base, result is exponent
                result = robust_pow(working, result)

        return result
    def __rpow__(self, other):
        if is_numberlike_array(self) and isinstance(other, Number):
            return robust_pow(other, self.item())

        if isinstance(other, Number):
            raise ShapeError("Cannot raise a scalar to power of a {self.shape_name}."
                                 .format(self=self))
        raise TypeError("Cannot raise {type} to power of {self.shape_name}."
                        .format(type=type(other), self=self))
    def __pow__(self, other):
        """
        Matrix powers for MathArrays of dimension 0 and 2.
        """
        if is_numberlike_array(self):
            if isinstance(other, Number):
                return robust_pow(self.item(), other)
            elif isinstance(other, MathArray):
                return other.__rpow__(self.item())
            else:
                raise TypeError("Cannot raise a scalar to a {type} power".format(type=type(other)))

        elif not self.ndim == 2:
            raise ShapeError("Cannot raise a {self.shape_name} to powers.".format(
                self=self))

        elif not is_square(self):
            raise ShapeError("Cannot raise a non-square matrix to powers.")

        # Henceforth, self is a square matrix.
        if isinstance(other, Number):
            exponent = other
        elif isinstance(other, MathArray):
            if is_numberlike_array(other):
                exponent = other.item()
            else:
                raise ShapeError("Cannot raise a matrix to {other.shape_name} powers.".format(
                    other=other))
        else:
            raise TypeError("Cannot raise matrix to power of type {type}.".format(
                type=type(other)))

        # Henceforth:
        # - self is a square matrix, AND
        # - exponent is a number
        integer_like = (isinstance(exponent, int) or
                        isinstance(exponent, float) and exponent.is_integer())
        if not integer_like:
            raise MathArrayError("Cannot raise a matrix to non-integer powers.")
        elif exponent < 0 and not MathArray._negative_powers:
            raise MathArrayError('Negative matrix powers have been disabled.')
        else:
            # just in case it had been an integer-like float
            exponent = int(exponent)
            try:
                return np.linalg.matrix_power(self, exponent)
            except np.linalg.linalg.LinAlgError as error:
                if error.message.startswith('Singular'):
                    raise MathArrayError('Cannot raise singular matrix to negative powers.')
                else:
                    # Not sure what could cause this...
                    raise # pragma: no cover