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 — time.sleep() should support objects with __float__ · Issue #79888 · python/cpython

time.sleep() should support objects with __float__ #79888

New issue
Copy link
New issue
Copy link
Closed as duplicate
Closed as duplicate
time.sleep() should support objects with __float__#79888
Copy link
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

@jdemeyer
jdemeyer
opened on Jan 10, 2019
Issue body actions
BPO 35707
Nosy @ronaldoussoren, @ncoghlan, @abalkin, @vstinner, @serhiy-storchaka, @jdemeyer, @MojoVampire, @pganssle, @remilapeyre
PRs
  • bpo-26669: Reject float infinity in time functions #11507
  • bpo-26669: Reject float infinity in time functions #11507
  • gh-79888: support __index__ and __float__ in time functions #11636
  • gh-79888: support __index__ and __float__ in time functions #11636
  • gh-79888: support __index__ and __float__ in time functions #11636
  • 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-01-10.15:58:39.782>
    labels = ['interpreter-core', '3.10']
    title = 'time.sleep() should support objects with __float__'
    updated_at = <Date 2020-05-23.00:14:27.187>
    user = 'https://github.com/jdemeyer'

    bugs.python.org fields:

    activity = <Date 2020-05-23.00:14:27.187>
    actor = 'cheryl.sabella'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Interpreter Core']
    creation = <Date 2019-01-10.15:58:39.782>
    creator = 'jdemeyer'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 35707
    keywords = ['patch', 'patch']
    message_count = 29.0
    messages = ['333391', '333395', '333396', '333397', '333401', '333404', '333416', '333547', '333550', '333554', '333555', '333961', '333963', '333968', '333969', '334120', '334121', '334122', '334125', '334128', '334129', '334131', '334136', '334480', '334486', '334509', '339123', '349004', '349560']
    nosy_count = 10.0
    nosy_names = ['ronaldoussoren', 'ncoghlan', 'belopolsky', 'vstinner', 'serhiy.storchaka', 'jdemeyer', 'josh.r', 'p-ganssle', 'remi.lapeyre', 'AVINASH MISHRA']
    pr_nums = ['11507', '11507', '11636', '11636', '11636']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue35707'
    versions = ['Python 3.10']

    Linked PRs

    • gh-79888 support object with __float__ defined in time.sleep #142990

    Activity

    Next
    1. jdemeyer commented on Jan 10, 2019

      @jdemeyer
      jdemeyer
      on Jan 10, 2019
      ContributorAuthor
      More actions

      This used to work correctly in Python 2:

      class Half(object):
          def __float__(self):
              return 0.5
      import time
      time.sleep(Half())

      With Python 3.6, one gets instead

      Traceback (most recent call last):
        File "test.py", line 6, in <module>
          time.sleep(Half())
      TypeError: an integer is required (got type Half)
    2. jdemeyer
      added
      3.7 (EOL)end of lifeend of life
      3.8 (EOL)end of lifeend of life
      on Jan 10, 2019
    3. AVINASHMISHRA commented on Jan 10, 2019

      @AVINASHMISHRA
      AVINASHMISHRAmannequin
      on Jan 10, 2019
      Mannequin
      More actions

      hey i am a total newbie to open source contribution.
      can you help me understand this issue and can i help solve this issue?

    4. remilapeyre commented on Jan 10, 2019

      @remilapeyre
      remilapeyremannequin
      on Jan 10, 2019
      Mannequin
      More actions

      time.sleep() is probably not the only function to have such a bug.

      Maybe __int__() should default to:

          def __int__(self):
              return int(self.__float__())

      when __float__ is defined and not __int__.

      Nick Coghlan suggested something similar for __int__ and __index__.

    5. remilapeyre commented on Jan 10, 2019

      @remilapeyre
      remilapeyremannequin
      on Jan 10, 2019
      Mannequin
      More actions

      See bpo-33039 for the proposed change to __int__.

    6. vstinner commented on Jan 10, 2019

      @vstinner
      vstinner
      on Jan 10, 2019
      Member
      More actions

      The problem comes from the private C function _PyTime_FromObject() of Python/pytime.c. This function must use the proper conversion to minimize the precision loss. Lib/test/test_time.py contains a lot of tests on conversions from different types and ensure that values are rounded correctly. See also my PEP-564 "Add new time functions with nanosecond resolution".

      The correct code works for float and int (and maybe decimal.Decimal, I don't recall!), but it seems like it doesn't support types with __float__(). You have to explicitly cast such objects using float(value).

      PyNumber_Float() can be used to convert arbitrary object to a float, but I'm not sure in which order the conversion should be tried to avoid/reduce precision loss during the conversion.

      Example:

      >>> x=2**53+1; x - int(float(x))
      1

      If we convert 'x' (int) to float, we introduce an error of 1.

    7. vstinner commented on Jan 10, 2019

      @vstinner
      vstinner
      on Jan 10, 2019
      Member
      More actions

      PR 11507 is not directly related to this issue, see bpo-26669. But I wrote this PR when trying to fix this issue :-)

    8. jdemeyer commented on Jan 10, 2019

      @jdemeyer
      jdemeyer
      on Jan 10, 2019
      ContributorAuthor
      More actions

      I'm not sure in which order the conversion should be tried to avoid/reduce precision loss during the conversion.

      I would suggest the order

      1. __index__ to ensure exact conversion of exact integers
      2. __float__ to ensure correct conversion of floating-point numbers
      3. __int__
    9. ncoghlan commented on Jan 13, 2019

      @ncoghlan
      ncoghlan
      on Jan 13, 2019
      Contributor
      More actions

      Deriving __int__ from __float__ wouldn't be the right answer, as that can easily lead to unwanted OverflowError exceptions and other issues.

      However, Jeroen's suggested order of checking __index__ then __float__ then __int__ in _PyTime_FromObject makes sense to me, as that addresses Victor's desire to use the most precise conversion available.

    10. serhiy-storchaka commented on Jan 13, 2019

      @serhiy-storchaka
      serhiy-storchaka
      on Jan 13, 2019
      Member
      More actions

      This can cause a loss of precision for Decimal.

      If we want to support other numerical types with loss in double rounding, the most reliable way is to represent them as fractions (x.as_integer_ratio() or (x.numerator, x.denominator)) and use precise integer arithmetic.

    11. jdemeyer commented on Jan 13, 2019

      @jdemeyer
      jdemeyer
      on Jan 13, 2019
      ContributorAuthor
      More actions

      the most reliable way is to represent them as fractions (x.as_integer_ratio() or (x.numerator, x.denominator))

      I don't think that we can rely on non-dunder names like that. They are not reserved names, so classes can give them any semantics that they like. This is not just hypothetical: SageMath for example uses numerator() and denominator() methods, not properties.

      If you really want to go through with this, probably a special method like __as_integer_ratio__ should be defined.

      Anyway, I personally consider the double rounding for time.sleep() a non-issue. We are not trying to write a precise math library here, nobody will complain about sleeping a femtosecond too long.

    12. jdemeyer commented on Jan 13, 2019

      @jdemeyer
      jdemeyer
      on Jan 13, 2019
      ContributorAuthor
      More actions

      The correct code works for float and int (and maybe decimal.Decimal, I don't recall!)

      Not for Decimal! In fact sleep(Decimal("0.99")) is interpreted as sleep(0) because __int__ is used to convert.

    13. jdemeyer commented on Jan 18, 2019

      @jdemeyer
      jdemeyer
      on Jan 18, 2019
      ContributorAuthor
      More actions

      My proposal vastly improves the situation for Decimal. I will write a PR for this and I hope that it won't be rejected just because it's not perfect.

    14. vstinner commented on Jan 18, 2019

      @vstinner
      vstinner
      on Jan 18, 2019
      Member
      More actions

      Not for Decimal! In fact sleep(Decimal("0.99")) is interpreted as sleep(0) because __int__ is used to convert.

      Oh oh. I didn't know that. It should be fixed.

    15. 14 remaining items

    16. jdemeyer commented on Mar 29, 2019

      @jdemeyer
      jdemeyer
      on Mar 29, 2019
      ContributorAuthor
      More actions

      Is anybody willing to review PR 11636?

    17. jdemeyer commented on Aug 4, 2019

      @jdemeyer
      jdemeyer
      on Aug 4, 2019
      ContributorAuthor
      More actions

      If we want to support other numerical types with loss in double rounding, the most reliable way is to represent them as fractions (x.as_integer_ratio() or (x.numerator, x.denominator))

      See https://discuss.python.org/t/pep-3141-ratio-instead-of-numerator-denominator/2037/24?u=jdemeyer for a proposal to define __ratio__ for this.

    18. vstinner commented on Aug 13, 2019

      @vstinner
      vstinner
      on Aug 13, 2019
      Member
      More actions

      See also bpo-20861.

    19. csabella
      added
      3.10 (EOL)end of lifeend of life
      and removed
      3.7 (EOL)end of lifeend of life
      3.8 (EOL)end of lifeend of life
      on May 23, 2020
    20. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    21. ald-extrahop commented on Aug 3, 2023

      @ald-extrahop
      ald-extrahop
      on Aug 3, 2023
      More actions

      If this issue is covering all the _PyTime_FromObject() uses, the change to PyLong_AsLongLong() in Python 3.10 (#80229) increased the severity. Many time functions that accept floats by design raise TypeError when passed (e.g.) a decimal.Decimal (they previously just printed a DeprecationWarning).

    22. serhiy-storchaka
      added this to Date and time issues 🕰️on Jun 27, 2025
    23. StanFromIreland commented on Aug 12, 2025

      @StanFromIreland
      StanFromIreland
      on Aug 12, 2025
      Member
      More actions

      The error message now contradicts the behavior:

      >>> class Half(object):
      ...     def __float__(self):
      ...         return 0.5
      ... import time
      ... time.sleep(Half())
      ... 
      Traceback (most recent call last):
        File "<python-input-5>", line 5, in <module>
          time.sleep(Half())
          ~~~~~~~~~~^^^^^^^^
      TypeError: 'Half' object cannot be interpreted as an integer or float
      
    24. StanFromIreland
      added
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      and removed
      3.10 (EOL)end of lifeend of life
      on Aug 12, 2025
    25. StanFromIreland commented on Dec 20, 2025

      @StanFromIreland
      StanFromIreland
      on Dec 20, 2025
      Member
      More actions

      This was fixed by Serhiy in 1a2e00c:

      >>> class Half(object):
      ...     def __float__(self):
      ...         return 0.5
      ... import time
      ... time.sleep(Half())
      ... 
      >>> 
      
    26. StanFromIreland
      closed this as a duplicateof Inconsistency in datetime.utcfromtimestamp(Decimal) #67795 on Dec 20, 2025
    27. github-project-automation
      moved this to Done in Date and time issues 🕰️on Dec 20, 2025
    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

      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

      • Date and time issues 🕰️
        Status
        Done
        Show more project fields

      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.