Repository: sympy/sympy
File: sympy/core/power.py (Python)

Code before:
                expanded = self.expand(deep, **hints)
                if hints.get('ignore') == expanded:
                    return None
                else:
                    return (re(expanded), im(expanded))
            else:
                return re(self), im(self)

    def _eval_derivative(self, s):
        from sympy.functions.elementary.exponential import log
        dbase = self.base.diff(s)
        dexp = self.exp.diff(s)

        if not self.base.is_commutative:
            exp_is_constant = dexp.is_zero is True
            exp_is_integer_const = isinstance(self.exp, Integer)

            if exp_is_constant and exp_is_integer_const:
                n = int(self.exp)
                base = self.base

                if n > 0:
                    return Add(*[
                        Mul(Pow(base, i), dbase, Pow(base, n - 1 - i))
                        for i in range(n)
                    ])
                elif n < 0:
                    m = -n
                    return -Add(*[
                        Mul(Pow(base, -(i + 1)), dbase, Pow(base, -(m - i)))
                        for i in range(m)
                    ])
                else:
                    return S.Zero

            return None

        return self * (dexp * log(self.base) + dbase * self.exp / self.base)

    def _eval_evalf(self, prec):
        base, exp = self.as_base_exp()
        if base == S.Exp1:
            # Use mpmath function associated to class "exp":
            from sympy.functions.elementary.exponential import exp as exp_function
            return exp_function(self.exp, evaluate=False)._eval_evalf(prec)
        base = base._evalf(prec)
        if not exp.is_Integer:
            exp = exp._evalf(prec)
        if exp.is_negative and base.is_number and base.is_extended_real is False:
            base = base.conjugate() / (base * base.conjugate())._evalf(prec)
            exp = -exp

Review comment (bug):
I'm not sure it is a good idea to do this since `n` could be large.

A simpler fix would just be to say that if the base is noncommutative then it just returns None and the derivative is unevaluated.

Alternatively it could explicitly handle only very small powers like `x**n` for n in `[-1, 0, 1, 2]` but it is probably better just to fix the bug here by returning None.

Code after:
                expanded = self.expand(deep, **hints)
                if hints.get('ignore') == expanded:
                    return None
                else:
                    return (re(expanded), im(expanded))
            else:
                return re(self), im(self)

    def _eval_derivative(self, s):
        from sympy.functions.elementary.exponential import log
        if not self.base.is_commutative:
            return None
        dbase = self.base.diff(s)
        dexp = self.exp.diff(s)

        return self * (dexp * log(self.base) + dbase * self.exp/self.base)

    def _eval_evalf(self, prec):
        base, exp = self.as_base_exp()
        if base == S.Exp1:
            # Use mpmath function associated to class "exp":
            from sympy.functions.elementary.exponential import exp as exp_function
            return exp_function(self.exp, evaluate=False)._eval_evalf(prec)
        base = base._evalf(prec)
        if not exp.is_Integer:
            exp = exp._evalf(prec)
        if exp.is_negative and base.is_number and base.is_extended_real is False:
            base = base.conjugate() / (base * base.conjugate())._evalf(prec)
            exp = -exp
            return self.func(base, exp).expand()
        return self.func(base, exp)

    def _eval_is_polynomial(self, syms):
        if self.exp.has(*syms):
            return False

        if self.base.has(*syms):
            return bool(self.base._eval_is_polynomial(syms) and
                self.exp.is_Integer and (self.exp >= 0))
        else:
            return True

    def _eval_is_rational(self):
        # The evaluation of self.func below can be very expensive in the case
        # of integer**integer if the exponent is large.  We should try to exit
        # before that if possible:
        if (self.exp.is_integer and self.base.is_rational
                and fuzzy_not(fuzzy_and([self.exp.is_negative, self.base.is_zero]))):
            return True
        p = self.func(*self.as_base_exp())  # in case it's unevaluated
        if not p.is_Pow: