Skip to content

Support .as_integer_ratio() in fractions.Fraction #82017

Closed

Description

@jdemeyer
BPO 37836
Nosy @rhettinger, @mdickinson, @serhiy-storchaka, @jdemeyer
PRs
  • bpo-37836: support .as_integer_ratio() in Fraction #15327
  • bpo-37836: document as_integer_ratio() in the data model #15328
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2019-08-13.09:41:19.711>
    labels = ['library', '3.9']
    title = 'Support .as_integer_ratio() in fractions.Fraction'
    updated_at = <Date 2022-01-02.22:00:12.998>
    user = 'https://github.com/jdemeyer'

    bugs.python.org fields:

    activity = <Date 2022-01-02.22:00:12.998>
    actor = 'rhettinger'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2019-08-13.09:41:19.711>
    creator = 'jdemeyer'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 37836
    keywords = ['patch']
    message_count = 6.0
    messages = ['349536', '349933', '349940', '349942', '349945', '409531']
    nosy_count = 5.0
    nosy_names = ['rhettinger', 'mark.dickinson', 'stutzbach', 'serhiy.storchaka', 'jdemeyer']
    pr_nums = ['15327', '15328']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue37836'
    versions = ['Python 3.9']

    Linked PRs

    Activity

    1. jdemeyer commented on Aug 13, 2019

      @jdemeyer
      ContributorAuthor

      Currently, the fractions.Fraction constructor accepts an .as_integer_ratio() method only for the specific types "float" and "Decimal". It would be good to support this for arbitrary classes.

      This is part of what was proposed in bpo-37822, but without adding the math.operator() function.

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      on Aug 13, 2019
    3. serhiy-storchaka commented on Aug 19, 2019

      @serhiy-storchaka
      Member

      I afraid this can slow down the Fraction constructor.

    4. serhiy-storchaka commented on Aug 19, 2019

      @serhiy-storchaka
      Member

      See bpo-37884 which uses a C accelerator.

    5. jdemeyer commented on Aug 19, 2019

      @jdemeyer
      ContributorAuthor

      See bpo-37884 which uses a C accelerator.

      Note that that doesn't replace this issue, because I need to support as_integer_ratio both in the *numerator* and *denominator*.

    6. jdemeyer commented on Aug 19, 2019

      @jdemeyer
      ContributorAuthor

      I afraid this can slow down the Fraction constructor.

      No, it doesn't! It even speeds up the constructor in some cases:

      ./python -m perf timeit --duplicate 200 -s 'from fractions import Fraction; x = 1' 'Fraction(x)'
      BEFORE: Mean +- std dev: 826 ns +- 20 ns
      AFTER: Mean +- std dev: 814 ns +- 17 ns

      ./python -m perf timeit --duplicate 200 -s 'from fractions import Fraction; x = 1' 'Fraction(x, x)'
      BEFORE: Mean +- std dev: 1.44 us +- 0.03 us
      AFTER: Mean +- std dev: 1.46 us +- 0.02 us

      ./python -m perf timeit --duplicate 200 -s 'from fractions import Fraction; x = Fraction(1)' 'Fraction(x)'
      BEFORE: Mean +- std dev: 1.64 us +- 0.03 us
      AFTER: Mean +- std dev: 1.30 us +- 0.04 us

      ./python -m perf timeit --duplicate 200 -s 'from fractions import Fraction; x = Fraction(1)' 'Fraction(x, x)'
      BEFORE: Mean +- std dev: 3.03 us +- 0.05 us
      AFTER: Mean +- std dev: 2.34 us +- 0.06 us

      ./python -m perf timeit --duplicate 200 -s 'from fractions import Fraction; x = 1.0' 'Fraction(x)'
      BEFORE: Mean +- std dev: 1.82 us +- 0.02 us
      AFTER: Mean +- std dev: 1.29 us +- 0.04 us

    7. rhettinger commented on Jan 2, 2022

      @rhettinger
      Contributor

      I don't think this is a door we should open:

         >>> Fraction(3.5, 2.5)
         Fraction(7, 5)

      This currently raises a useful exception:

      TypeError: both arguments should be Rational instances

      That is especially helpful in avoiding cases like this:

          >>> Fraction(1.1, 3.3)
          Fraction(2476979795053773, 7430939385161318)

      If that output is desired, the two conversions should be explicit.

          >>> Fraction(1.1) / Fraction(3.3)
          Fraction(2476979795053773, 7430939385161318

      I recommend rejecting this feature request as being more likely to be hazardous than helpful.

    8. transferred this issue fromon Apr 10, 2022
    9. serhiy-storchaka commented on Apr 21, 2022

      @serhiy-storchaka
      Member

      Concur with @rhettinger.

    10. serhiy-storchaka commented on Jun 8, 2024

      @serhiy-storchaka
      Member

      This proposition was rejected because it used as_integer_ratio() in both single- and two-argument forms of the Fraction constructor. But these two forms have different roles. The former converts a number to a Fraction or parses a string representation of fraction. The latter creates a fraction from two rationals (and this is perhaps too much, it could be limited to integers). Conversion from integer supports not only rational numbers, but also float and Decimal. Supporting as_integer_ratio() here would allow to convert float128 and other non-rational numbers to Fraction.

      So I reopen this issue with more limited goal -- supporting as_integer_ratio() in a single-argument form of the Fraction constructor.

    11. added a commit that references this issue on Jun 8, 2024
    12. pfmoore commented on Jun 8, 2024

      @pfmoore
      Member

      Agreed this would be a nice generalisation for the case of converting a user-defined type to a fraction (the user defined type just has to define as_integer_ratio and then Fraction(value) works as expected). But it should not apply to the 2-argument case.

    13. added
      3.14bugs and security fixes
      and removed on Jul 17, 2024
    14. added a commit that references this issue on Jul 19, 2024
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directory

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions