This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Improve conversions for fractions
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Martin.Teichmann, mark.dickinson, rhettinger, serhiy.storchaka, veky
Priority: normal Keywords: patch

Created on 2021-05-12 13:09 by Martin.Teichmann, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 26064 open Martin.Teichmann, 2021-05-12 13:16
Messages (4)
msg393507 - (view) Author: Martin Teichmann (Martin.Teichmann) * Date: 2021-05-12 13:09
Currently, fraction.Fractions can be generated from floats via their as_integer_ratio method. This had been extended to also work with the Decimals class. It would be more generic - and IMHO more Pythonic - to just allow any data type, as long as it has an as_integer_ratio method.

As an example, this allows numpy floats to be converted into fractions.
msg393554 - (view) Author: Vedran Čačić (veky) * Date: 2021-05-13 02:36
Absolutely. I think that's a big part of the reason that as_integer_ratio is there.
msg393559 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-05-13 07:07
Note for posterity:   I tried out pattern matching here but it was a little tricky and it slowed down the code a bit.  At at least it worked.

        if denominator is None:
            match numerator:
                case int(x) if type(numerator) is int:
                    self._numerator = numerator
                    self._denominator = 1
                    return self
                case numbers.Rational(numerator=numerator, denominator=denominator):
                    self._numerator = numerator
                    self._denominator = denominator
                    return self
                case object(as_integer_ratio=_):
                    self._numerator, self._denominator = numerator.as_integer_ratio()
                    return self
                case str(x):
                    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
                case _:
                    raise TypeError("argument should be a string "
                                    "or a Rational instance")
msg393560 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-05-13 07:33
It was proposed before in issue37884.
History
Date User Action Args
2022-04-11 14:59:45adminsetgithub: 88281
2021-05-15 04:21:37rhettingersetassignee: rhettinger ->
2021-05-13 11:10:01mark.dickinsonsetnosy: + mark.dickinson
2021-05-13 07:33:32serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg393560
2021-05-13 07:07:25rhettingersetmessages: + msg393559
2021-05-13 04:30:48rhettingersetassignee: rhettinger

nosy: + rhettinger
2021-05-13 02:36:17vekysetnosy: + veky
messages: + msg393554
2021-05-12 13:16:48Martin.Teichmannsetkeywords: + patch
stage: patch review
pull_requests: + pull_request24705
2021-05-12 13:09:37Martin.Teichmanncreate