GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — float() can return not exact float instance · Issue #71170 · python/cpython

float() can return not exact float instance #71170

New issue
Copy link
New issue
Copy link
Closed
Closed
float() can return not exact float instance#71170
Copy link
Assignees
serhiy-storchaka
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@serhiy-storchaka
serhiy-storchaka
opened on May 9, 2016
Issue body actions
BPO 26983
Nosy @mdickinson, @serhiy-storchaka
Dependencies
  • bpo-26995: Add tests for parsing float and object arguments
  • Files
  • float_exact.patch
  • float_exact2.patch
  • issue26983.diff
  • 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 = 'https://github.com/serhiy-storchaka'
    closed_at = <Date 2016-06-06.10:01:54.560>
    created_at = <Date 2016-05-09.13:46:33.061>
    labels = ['interpreter-core', 'type-bug']
    title = 'float() can return not exact float instance'
    updated_at = <Date 2016-06-06.10:01:54.558>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2016-06-06.10:01:54.558>
    actor = 'serhiy.storchaka'
    assignee = 'serhiy.storchaka'
    closed = True
    closed_date = <Date 2016-06-06.10:01:54.560>
    closer = 'serhiy.storchaka'
    components = ['Interpreter Core']
    creation = <Date 2016-05-09.13:46:33.061>
    creator = 'serhiy.storchaka'
    dependencies = ['26995']
    files = ['42807', '42815', '43256']
    hgrepos = []
    issue_num = 26983
    keywords = ['patch']
    message_count = 15.0
    messages = ['265191', '265267', '265295', '265297', '265298', '265299', '265316', '265318', '267096', '267101', '267129', '267130', '267521', '267523', '267524']
    nosy_count = 4.0
    nosy_names = ['mark.dickinson', 'SilentGhost', 'python-dev', 'serhiy.storchaka']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'commit review'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue26983'
    versions = ['Python 3.6']

    Activity

    1. serhiy-storchaka commented on May 9, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on May 9, 2016
      MemberAuthor
      More actions

      The float constructor can return an instance of float subclass.

      >>> class FloatSubclass(float):
      ...     pass
      ... 
      >>> class BadFloat:
      ...     def __float__(self):
      ...         return FloatSubclass(1.2)
      ... 
      >>> type(float(BadFloat()))
      <class '__main__.FloatSubclass'>

      Comparing with other types, complex() always returns complex:

      >>> class ComplexSubclass(complex):
      ...     pass
      ... 
      >>> class BadComplex:
      ...     def __complex__(self):
      ...         return ComplexSubclass(1.2, 3.4)
      ... 
      >>> type(complex(BadComplex()))
      <class 'complex'>

      And int() can return an instance of int subclass, but this behavior is deprecated:

      >>> class BadInt:
      ...     def __int__(self):
      ...         return True
      ... 
      >>> int(BadInt())
      __main__:1: DeprecationWarning: __int__ returned non-int (type bool).  The ability to return an instance of a strict subclass of int is deprecated, and may be removed in a future version of Python.
      True

      May be we should either deprecate __float__ returning non-float (as for int), or convert the result to exact float (as for complex).

      The constructor of float subclass always returns an instance of correct type.

      >>> class FloatSubclass2(float):
      ...     pass
      ... 
      >>> type(FloatSubclass2(BadFloat()))
      <class '__main__.FloatSubclass2'>
    2. serhiy-storchaka
      added
      interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      on May 9, 2016
    3. serhiy-storchaka commented on May 10, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on May 10, 2016
      MemberAuthor
      More actions

      Proposed patch makes float() always returning exact float.

    4. mdickinson commented on May 11, 2016

      @mdickinson
      mdickinson
      on May 11, 2016
      Member
      More actions

      +1 for the idea, and the patch LGTM.

      I was initially a bit confused by the wording of the warning: presumably, we're not going to change Python to make returning an instance of a strict float subclass from __float__ illegal (I don't really see how that would be possible); we're just going to check the return type at the internal call sites to __float__ and raise if we get something other than an exact float. That is, I'd still expect this code to work on future versions of Python:

      >>> class MyFloat(float): pass
      ... 
      >>> class A:
      ...     def __float__(self): return MyFloat()
      ... 
      >>> a = A()
      >>> a.__float__()
      0.0

      But these would both become an error in Python 3.7 (say):

      >>> float(a)
      0.0
      >>> math.sqrt(a)
      0.0

      Does that match your thinking?

      We should probably add issues for checking and fixing other places that __float__ is used internally (like the math module).

    5. serhiy-storchaka commented on May 11, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on May 11, 2016
      MemberAuthor
      More actions

      The warning message is copied from __int__. As I understand, the conclusion of the Python-Dev discussion is that __int__, __float__, __complex__, etc should return exact int, float, complex, not subclasses. I have another patch that adds a warning for __complex__, and I am working on patches for other special methods. If my understanding is wrong, we should remove the deprecation warning for __int__.

    6. mdickinson commented on May 11, 2016

      @mdickinson
      mdickinson
      on May 11, 2016
      Member
      More actions

      As I understand, the conclusion of the Python-Dev discussion is that __int__, __float__, __complex__, etc should return exact int, float, complex, not subclasses.

      Agreed; that matches my understanding. I'm only observing that it would be difficult (and likely undesirable) to actually enforce that __int__ itself always returns an exact int: I'm not sure where that check would/could take place, and I'd expect that a direct user-level call to my_object.__int__ probably wouldn't be subject to such a check. What we can do is check that the result of the nb_int call is always an int in the places we use it.

      Or we could even go further, and write custom slot_nb_float and slot_nb_int functions in Objects/typeobject.c that incorporates those checks. What I don't think we can do is check that a direct call to __int__ or __float__ always returns something of the exact type.

    7. serhiy-storchaka commented on May 11, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on May 11, 2016
      MemberAuthor
      More actions

      Here is updated patch. Differences:

      • Deprecation warning is now emitted in functions accepting floats (like math.sqrt).
      • Improved error messages. Now reported wrong type name and a type of wrong __float__ method.
      • float() now returns the same object for exact float argument.

      Could you propose better warning message?

    8. mdickinson commented on May 11, 2016

      @mdickinson
      mdickinson
      on May 11, 2016
      Member
      More actions

      Can you please attach the new patch?

    9. serhiy-storchaka commented on May 11, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on May 11, 2016
      MemberAuthor
      More actions

      Oh, sorry, how could I miss it?

    10. serhiy-storchaka commented on Jun 3, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on Jun 3, 2016
      MemberAuthor
      More actions

      Ping.

    11. mdickinson commented on Jun 3, 2016

      @mdickinson
      mdickinson
      on Jun 3, 2016
      Member
      More actions

      float_exact2.patch LGTM

    12. python-dev commented on Jun 3, 2016

      @python-dev
      python-devmannequin
      on Jun 3, 2016
      Mannequin
      More actions

      New changeset 050e5f803999 by Serhiy Storchaka in branch 'default':
      Issue bpo-26983: float() now always return an instance of exact float.
      https://hg.python.org/cpython/rev/050e5f803999

    13. serhiy-storchaka commented on Jun 3, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on Jun 3, 2016
      MemberAuthor
      More actions

      Thank you for your review Mark.

    14. serhiy-storchaka
      closed this as completedon Jun 3, 2016
    15. SilentGhost commented on Jun 6, 2016

      @SilentGhost
      SilentGhostmannequin
      on Jun 6, 2016
      Mannequin
      More actions

      test_format resulted in semi-failure due to this change. The attached patch fixes the issue.

    16. SilentGhost
      reopened this on Jun 6, 2016
    17. SilentGhost
      assigned
      serhiy-storchaka
      on Jun 6, 2016
    18. python-dev commented on Jun 6, 2016

      @python-dev
      python-devmannequin
      on Jun 6, 2016
      Mannequin
      More actions

      New changeset 6216fb8afa53 by Serhiy Storchaka in branch 'default':
      Issue bpo-26983: Fixed test_format failure.
      https://hg.python.org/cpython/rev/6216fb8afa53

    19. serhiy-storchaka commented on Jun 6, 2016

      @serhiy-storchaka
      serhiy-storchaka
      on Jun 6, 2016
      MemberAuthor
      More actions

      My failure. Thank you for your report and patch SilentGhost.

    20. serhiy-storchaka
      closed this as completedon Jun 6, 2016
    21. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    • @serhiy-storchaka
      serhiy-storchaka

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.