'Return self ** n (mod modulo)
If modulo is None (default), don\'t take it mod modulo.'

def __pow__(self, n, modulo=None, context=None):

    n = _convert_other(n)
    if (context is None):
        context = getcontext()
    if (self._is_special or n._is_special or (n.adjusted() > 8)):
        if (n._isinfinity() or (n.adjusted() > 8)):
            return context._raise_error(InvalidOperation, 'x    **    INF')
        ans = self._check_nans(n, context)
        if ans:
            return ans
    if (not n._isinteger()):
        return context._raise_error(InvalidOperation, 'x    **    (non-integer)')
    if ((not self) and (not n)):
        return context._raise_error(InvalidOperation, '0    **    0')
    if (not n):
        return Decimal(1)
    if (self == Decimal(1)):
        return Decimal(1)
    sign = (self._sign and (not n._iseven()))
    n = int(n)
    if self._isinfinity():
        if modulo:
            return context._raise_error(InvalidOperation, 'INF    %    x')
        if (n > 0):
            return Infsign[sign]
        return Decimal((sign, (0,), 0))
    if ((not modulo) and (n > 0) and ((((self._exp + len(self._int)) - 1) * n) > context.Emax) and self):
        tmp = Decimal('inf')
        tmp._sign = sign
        context._raise_error(Rounded)
        context._raise_error(Inexact)
        context._raise_error(Overflow, 'Big    power', sign)
        return tmp
    elength = len(str(abs(n)))
    firstprec = context.prec
    if ((not modulo) and (((firstprec + elength) + 1) > DefaultContext.Emax)):
        return context._raise_error(Overflow, 'Too    much    precision.', sign)
    mul = Decimal(self)
    val = Decimal(1)
    context = context._shallow_copy()
    context.prec = ((firstprec + elength) + 1)
    if (n < 0):
        n = (- n)
        mul = Decimal(1).__div__(mul, context=context)
    spot = 1
    while (spot <= n):
        spot <<= 1
    spot >>= 1
    while spot:
        val = val.__mul__(val, context=context)
        if val._isinfinity():
            val = Infsign[sign]
            break
        if (spot & n):
            val = val.__mul__(mul, context=context)
        if (modulo is not None):
            val = val.__mod__(modulo, context=context)
        spot >>= 1
    context.prec = firstprec
    if (context._rounding_decision == ALWAYS_ROUND):
        return val._fix(context)
    return val
