# Buggy code
def poly(expr, *gens, **args):
    """
    Efficiently transform an expression into a polynomial.

    Examples
    ========

    >>> from sympy import poly
    >>> from sympy.abc import x

    >>> poly(x*(x**2 + x - 1)**2)
    Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')

    """
    options.allowed_flags(args, [])

    def _poly(expr, opt):
        terms, poly_terms = [], []

        for term in Add.make_args(expr):
            factors, poly_factors = [], []

            for factor in Mul.make_args(term):
                if factor.is_Add:
                    poly_factors.append(_poly(factor, opt))
                elif factor.is_Pow and factor.base.is_Add and factor.exp.is_Integer:
                    poly_factors.append(_poly(factor.base, opt).pow(factor.exp))
                else:
                    factors.append(factor)

            if not poly_factors:
                terms.append(term)
            else:
                product = poly_factors[0]

                for factor in poly_factors[1:]:
                    product = product.mul(factor)

                if factors:
                    factor = Mul(*factors)

                    if factor.is_Number:
                        product = product.mul(factor)
                    else:
                        product = product.mul(Poly._from_expr(factor, opt))

                poly_terms.append(product)

        if not poly_terms:
            result = Poly._from_expr(expr, opt)
        else:
            result = poly_terms[0]

            for term in poly_terms[1:]:
                result = result.add(term)

            if terms:
                term = Add(*terms)

                if term.is_Number:
                    result = result.add(term)
                else:
                    result = result.add(Poly._from_expr(term, opt))

        return result.reorder(*opt.get("gens", ()), **args)

    expr = sympify(expr)

    if expr.is_Poly:
        return Poly(expr, *gens, **args)

    if "expand" not in args:
        args["expand"] = False

    opt = options.build_options(gens, args)

    return _poly(expr, opt)


# Traceback (ValueError)
Traceback (most recent call last):
File "Temp.py", line 2, in <module>
print(sympy.polys.polytools.poly(1 / (1 + sympy.sqrt(2)), sympy.Dummy('x')))
File "sympy\polys\polytools.py", line 6855, in poly
return _poly(expr, opt)
File "sympy\polys\polytools.py", line 6805, in _poly
_poly(factor.base, opt).pow(factor.exp))
File "sympy\polys\polytools.py", line 1404, in pow
result = f.rep.pow(n)
File "sympy\polys\polyclasses.py", line 446, in pow
return f.per(dmp_pow(f.rep, n, f.lev, f.dom))
File "sympy\polys\densearith.py", line 978, in dmp_pow
return dup_pow(f, n, K)
File "sympy\polys\densearith.py", line 943, in dup_pow
raise ValueError("can't raise polynomial to a negative power")
ValueError: can't raise polynomial to a negative power

# Fixed code
def poly(expr, *gens, **args):
    """
    Efficiently transform an expression into a polynomial.

    Examples
    ========

    >>> from sympy import poly
    >>> from sympy.abc import x

    >>> poly(x*(x**2 + x - 1)**2)
    Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')

    """
    options.allowed_flags(args, [])

    def _poly(expr, opt):
        terms, poly_terms = [], []

        for term in Add.make_args(expr):
            factors, poly_factors = [], []

            for factor in Mul.make_args(term):
                if factor.is_Add:
                    poly_factors.append(_poly(factor, opt))
                elif (
                    factor.is_Pow
                    and factor.base.is_Add
                    and factor.exp.is_Integer
                    and factor.exp >= 0
                ):
                    poly_factors.append(_poly(factor.base, opt).pow(factor.exp))
                else:
                    factors.append(factor)

            if not poly_factors:
                terms.append(term)
            else:
                product = poly_factors[0]

                for factor in poly_factors[1:]:
                    product = product.mul(factor)

                if factors:
                    factor = Mul(*factors)

                    if factor.is_Number:
                        product = product.mul(factor)
                    else:
                        product = product.mul(Poly._from_expr(factor, opt))

                poly_terms.append(product)

        if not poly_terms:
            result = Poly._from_expr(expr, opt)
        else:
            result = poly_terms[0]

            for term in poly_terms[1:]:
                result = result.add(term)

            if terms:
                term = Add(*terms)

                if term.is_Number:
                    result = result.add(term)
                else:
                    result = result.add(Poly._from_expr(term, opt))

        return result.reorder(*opt.get("gens", ()), **args)

    expr = sympify(expr)

    if expr.is_Poly:
        return Poly(expr, *gens, **args)

    if "expand" not in args:
        args["expand"] = False

    opt = options.build_options(gens, args)

    return _poly(expr, opt)