FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Confused traceback while `floordiv` or `mod` happens between `Fraction` and `complex` objects · Issue #102840 · python/cpython · GitHub

Repository navigation

Confused traceback while floordiv or mod happens between Fraction and complex objects #102840

Closed

Description

from fractions import Fraction
a = Fraction(1, 2)
b = a // 1j
>
Traceback (most recent call last):
  File "C:\Users\KIRILL-1\CLionProjects\cpython\example.py", line 5, in <module>
    b = a // 1j
        ~~^^~~~
  File "C:\Users\KIRILL-1\AppData\Local\Programs\Python\Python311\Lib\fractions.py", line 363, in forward
    return fallback_operator(complex(a), b)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported operand type(s) for //: 'complex' and 'complex'

This traceback really confused me.
However, it's easy to fix, just need change these lines:

cpython/Lib/fractions.py

Lines 620 to 621 in 5e6661b

elif isinstance(b, complex):
return fallback_operator(complex(a), b)

To this:

elif isinstance(b, complex):
    try:
        return fallback_operator(complex(a), b)
    except TypeError:
        raise TypeError(
            "unsupported operand type(s) for %r: %r and %r" % (
                fallback_operator.__name__,
                type(a).__qualname__,
                type(b).__qualname__)
        ) from None

So, after that, we have a pretty nice traceback:

Traceback (most recent call last):
  File "C:\Users\KIRILL-1\CLionProjects\cpython\example.py", line 5, in <module>
    b = a // 1j
        ~~^^~~~
  File "C:\Users\KIRILL-1\CLionProjects\cpython\Lib\fractions.py", line 624, in forward
    raise TypeError(
TypeError: unsupported operand type(s) for 'floordiv': 'Fraction' and 'complex'

But, here a one problem - would be nice to have in traceback originally // instead of floordiv. I have no idea how to do it, without create a mapping with names. Theoretically - we can add a special attribute for it in operator, but it should be a another discussion.

Linked PRs

Activity

  1. Eclips4 commented on Mar 20, 2023

    MemberAuthor

    In fact, this case is also suitable for mod.

  2. changed the title [-]Confused traceback while floor division happens between `Fraction` and `complex` objects[/-] [+]Confused traceback while `floordiv` or `mod` happens between `Fraction` and `complex` objects[/+] on Mar 20, 2023
  3. skirpichev commented on Mar 20, 2023

    Member

    Maybe it could be fixed on this way...

    diff --git a/Lib/fractions.py b/Lib/fractions.py
    index c95db0730e..fe3a5d137b 100644
    --- a/Lib/fractions.py
    +++ b/Lib/fractions.py
    @@ -611,16 +611,18 @@ class doesn't subclass a concrete type, there's no
     
             """
             def forward(a, b):
    -            if isinstance(b, Fraction):
    -                return monomorphic_operator(a, b)
    -            elif isinstance(b, int):
    -                return monomorphic_operator(a, Fraction(b))
    -            elif isinstance(b, float):
    -                return fallback_operator(float(a), b)
    -            elif isinstance(b, complex):
    -                return fallback_operator(complex(a), b)
    -            else:
    -                return NotImplemented
    +            try:
    +                if isinstance(b, Fraction):
    +                    return monomorphic_operator(a, b)
    +                elif isinstance(b, int):
    +                    return monomorphic_operator(a, Fraction(b))
    +                elif isinstance(b, float):
    +                    return fallback_operator(float(a), b)
    +                elif isinstance(b, complex):
    +                    return fallback_operator(complex(a), b)
    +            except TypeError:
    +                pass
    +            return NotImplemented
             forward.__name__ = '__' + fallback_operator.__name__ + '__'
             forward.__doc__ = monomorphic_operator.__doc__
     

    (Ditto for the reverse().)

    Here is a traceback:

    >>> fractions.Fraction(1,2)//1j
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported operand type(s) for //: 'Fraction' and 'complex'
  4. Eclips4 commented on Mar 20, 2023

    MemberAuthor

    Thanks!
    Thats looking more pythonic, and this solves the problem, btw, tests are green. I'll send a PR.

  5. ericvsmith commented on Mar 20, 2023

    Member

    As a rule we don't do type checking like this. Is the original traceback really that confusing?

  6. Eclips4 commented on Mar 20, 2023

    MemberAuthor

    Docs/fractions say nothing about convert Fraction to complex.
    For new user, traceback which says that floordiv cannot be applied between two complex, really confusing.
    User try to floordiv Fraction and complex, but in traceback he saw a two complex objects.
    IMO

  7. ericvsmith commented on Mar 20, 2023

    Member

    Yes, but the code in the traceback shows that it's converting one argument to complex, so that explains one of them. But maybe I overestimate what people can figure out from the traceback.

  8. Eclips4 commented on Mar 20, 2023

    MemberAuthor

    Assessment of what can be understood by humans within traceback - really hard and subjective thing, so I can't say anything about this at all.
    However, PR which related with this issue, doesn't break backward compatibility, just make prettier traceback, I think, we should take in account that.

  9. terryjreedy commented on Mar 20, 2023

    Member

    @ericvsmith: "As a rule we don't do type checking like this. " We already are doing 'this' as the proposal just wraps an existing isinstance chain in try: except. I definitely like the revised message better.

  10. ericvsmith commented on Mar 21, 2023

    Member

    @terryjreedy: Thanks. I was trying to get across that in general we don't try to improve messages where duck typing fails.

    But you're correct, in this case we are already dispatching based on the type of a parameter, so my argument is weak. I think the better solution here might be to not try to convert the numerator to a complex value, since we know that a_complex // b_complex isn't going to work. But that would require some surgery to make // a special case, different from say a_complex * a_float.

  11. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Mar 22, 2023
  12. mdickinson commented on Mar 22, 2023

    Member

    I'm not convinced that this is worth the effort; it seems like an unlikely case to even hit in the first place.

  13. added a commit that references this issue on Feb 10, 2024
  14. serhiy-storchaka commented on Feb 10, 2024

    Member

    I would like to backport this change (the final version), but other coredevs were skeptical. Confusing error message is not a large bug.

  15. added a commit that references this issue on Feb 14, 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

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL