Author hroncok
Recipients hroncok, vstinner
Date 2020-01-31.12:52:20
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1580475142.21.0.179441510745.issue39350@roundup.psfhosted.org>
In-reply-to
Content
I believe there is a regression here.

numpy fails to build with Python 3.9.0a3.

________________________ TestMatmul.test_matmul_object _________________________
self = <numpy.core.tests.test_multiarray.TestMatmul object at 0x7ff9bc008ca0>
    def test_matmul_object(self):
        import fractions
    
        f = np.vectorize(fractions.Fraction)
        def random_ints():
            return np.random.randint(1, 1000, size=(10, 3, 3))
>       M1 = f(random_ints(), random_ints())
f          = <numpy.vectorize object at 0x7ff9bc6751f0>
fractions  = <module 'fractions' from '/usr/lib64/python3.9/fractions.py'>
random_ints = <function TestMatmul.test_matmul_object.<locals>.random_ints at 0x7ff9bcc2d700>
self       = <numpy.core.tests.test_multiarray.TestMatmul object at 0x7ff9bc008ca0>
numpy/core/tests/test_multiarray.py:6259: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
numpy/lib/function_base.py:2091: in __call__
    return self._vectorize_call(func=func, args=vargs)
numpy/lib/function_base.py:2161: in _vectorize_call
    ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
numpy/lib/function_base.py:2121: in _get_ufunc_and_otypes
    outputs = func(*inputs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
cls = <class 'fractions.Fraction'>, numerator = 483, denominator = 809
    def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
        """Constructs a Rational.
    
        Takes a string like '3/2' or '1.5', another Rational instance, a
        numerator/denominator pair, or a float.
    
        Examples
        --------
    
        >>> Fraction(10, -8)
        Fraction(-5, 4)
        >>> Fraction(Fraction(1, 7), 5)
        Fraction(1, 35)
        >>> Fraction(Fraction(1, 7), Fraction(2, 3))
        Fraction(3, 14)
        >>> Fraction('314')
        Fraction(314, 1)
        >>> Fraction('-35/4')
        Fraction(-35, 4)
        >>> Fraction('3.1415') # conversion from numeric string
        Fraction(6283, 2000)
        >>> Fraction('-47e-2') # string may include a decimal exponent
        Fraction(-47, 100)
        >>> Fraction(1.47)  # direct construction from float (exact conversion)
        Fraction(6620291452234629, 4503599627370496)
        >>> Fraction(2.25)
        Fraction(9, 4)
        >>> Fraction(Decimal('1.47'))
        Fraction(147, 100)
    
        """
        self = super(Fraction, cls).__new__(cls)
    
        if denominator is None:
            if type(numerator) is int:
                self._numerator = numerator
                self._denominator = 1
                return self
    
            elif isinstance(numerator, numbers.Rational):
                self._numerator = numerator.numerator
                self._denominator = numerator.denominator
                return self
    
            elif isinstance(numerator, (float, Decimal)):
                # Exact conversion
                self._numerator, self._denominator = numerator.as_integer_ratio()
                return self
    
            elif isinstance(numerator, str):
                # Handle construction from strings.
                m = _RATIONAL_FORMAT.match(numerator)
                if m is None:
                    raise ValueError('Invalid literal for Fraction: %r' %
                                     numerator)
                numerator = int(m.group('num') or '0')
                denom = m.group('denom')
                if denom:
                    denominator = int(denom)
                else:
                    denominator = 1
                    decimal = m.group('decimal')
                    if decimal:
                        scale = 10**len(decimal)
                        numerator = numerator * scale + int(decimal)
                        denominator *= scale
                    exp = m.group('exp')
                    if exp:
                        exp = int(exp)
                        if exp >= 0:
                            numerator *= 10**exp
                        else:
                            denominator *= 10**-exp
                if m.group('sign') == '-':
                    numerator = -numerator
    
            else:
                raise TypeError("argument should be a string "
                                "or a Rational instance")
    
        elif type(numerator) is int is type(denominator):
            pass # *very* normal case
    
        elif (isinstance(numerator, numbers.Rational) and
            isinstance(denominator, numbers.Rational)):
            numerator, denominator = (
                numerator.numerator * denominator.denominator,
                denominator.numerator * numerator.denominator
                )
        else:
            raise TypeError("both arguments should be "
                            "Rational instances")
    
        if denominator == 0:
            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
        if _normalize:
            if type(numerator) is int is type(denominator):
                # *very* normal case
                g = math.gcd(numerator, denominator)
                if denominator < 0:
                    g = -g
            else:
>               g = _gcd(numerator, denominator)
E               NameError: name '_gcd' is not defined
__class__  = <class 'fractions.Fraction'>
_normalize = True
cls        = <class 'fractions.Fraction'>
denominator = 809
numerator  = 483
self       = <[AttributeError("_numerator") raised in repr()] Fraction object at 0x7ff9bc6753a0>
/usr/lib64/python3.9/fractions.py:164: NameError


This removed _gcd, but it is still called in:

https://github.com/python/cpython/blob/58a4054760bffbb20aff90290dd0f3554f7bea42/Lib/fractions.py#L164
History
Date User Action Args
2020-01-31 12:52:22hroncoksetrecipients: + hroncok, vstinner
2020-01-31 12:52:22hroncoksetmessageid: <1580475142.21.0.179441510745.issue39350@roundup.psfhosted.org>
2020-01-31 12:52:22hroncoklinkissue39350 messages
2020-01-31 12:52:20hroncokcreate