Skip to content

Modernize integer test/conversion in randrange() #86388

Description

@rhettinger
BPO 42222
Nosy @tim-one, @rhettinger, @terryjreedy, @encukou, @ambv, @serhiy-storchaka, @vedgar
PRs
  • bpo-42222: Modernize integer test/conversion in randrange() #23064
  • bpo-42222: Remove deprecated support for non-integer values #28983
  • bpo-42222: Improve tests for invalid argument types in randrange() #29021
  • 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/rhettinger'
    closed_at = <Date 2020-12-28.19:11:34.467>
    created_at = <Date 2020-10-31.17:27:12.134>
    labels = ['library', '3.11']
    title = 'Modernize integer test/conversion in randrange()'
    updated_at = <Date 2022-02-03.10:41:29.426>
    user = 'https://github.com/rhettinger'

    bugs.python.org fields:

    activity = <Date 2022-02-03.10:41:29.426>
    actor = 'petr.viktorin'
    assignee = 'rhettinger'
    closed = True
    closed_date = <Date 2020-12-28.19:11:34.467>
    closer = 'rhettinger'
    components = ['Library (Lib)']
    creation = <Date 2020-10-31.17:27:12.134>
    creator = 'rhettinger'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 42222
    keywords = ['patch']
    message_count = 16.0
    messages = ['380082', '380083', '380084', '380085', '380086', '380089', '380096', '380099', '380111', '380498', '380499', '383776', '383916', '404088', '404327', '412435']
    nosy_count = 7.0
    nosy_names = ['tim.peters', 'rhettinger', 'terry.reedy', 'petr.viktorin', 'lukasz.langa', 'serhiy.storchaka', 'veky']
    pr_nums = ['23064', '28983', '29021']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue42222'
    versions = ['Python 3.11']

    Activity

    1. rhettinger commented on Oct 31, 2020

      @rhettinger
      ContributorAuthor

      Move the int(x)==x test and conversion into the C code for operator.index().

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      on Oct 31, 2020
    3. rhettinger commented on Oct 31, 2020

      @rhettinger
      ContributorAuthor

      And, if we were willing to correct the exception type from ValueError to TypeError, the code could be made simpler, faster, and more in line with user expectations.

    4. rhettinger commented on Oct 31, 2020

      @rhettinger
      ContributorAuthor

      I had forgotten. It looks like float arguments were allowed:

          >>> randrange(10.0, 20.0, 2.0)
          16

      Is this worth going through a deprecation cycle to get the code cleaned-up or should we live with it as is?

    5. serhiy-storchaka commented on Oct 31, 2020

      @serhiy-storchaka
      Member

      It changes the behavior. Currently randrange(10.0) works, but with PR 23064 it would fail.

      See bpo-40046 with a ready PR for increasing coverage for the random module. If it would accepted, some tests would fail with PR 23064.

      If you want to deprecate accepting float arguments, there was bpo-40046 with a ready PR.

      These propositions were rejected by you. Have you reconsidered your decision?

    6. rhettinger commented on Oct 31, 2020

      @rhettinger
      ContributorAuthor

      These propositions were rejected by you.
      Have you reconsidered your decision?

      I was reluctant to break any existing code.
      Now, I'm unsure and am inclined to harmonize it with range().

      What do you think?
      Should we have ever supported float arguments
      for an integer domain function?

    7. serhiy-storchaka commented on Oct 31, 2020

      @serhiy-storchaka
      Member

      I think and always thought that integer domain functions should not accept non-integer arguments even with integer value. This is why I submitted numerous patches for deprecating and finally removing support of non-integer arguments in most of integer domain functions. C implemented functions which use PyArg_Parse("i") or PyLong_AsLong() for parsing arguments use now index() instead of int(). They emit a deprecation warning for non-integers in 3.8 and 3.9 and raise type error since 3.10. math.factorial() emits a warning only in 3.9.

      bpo-37319 (sorry, I wrote incorrect issue number in msg380085) was initially opened for 3.9, so we could convert warnings into errors in 3.10 or 3.11.

      Currently randrange(1e25) can return value larger than 10**25, because int(1e25) == 10000000000000000905969664 > 10**25.

    8. rhettinger commented on Oct 31, 2020

      @rhettinger
      ContributorAuthor

      User feedback concur with making the change: https://twitter.com/raymondh/status/1322607969754775552

    9. vedgar commented on Oct 31, 2020

      vedgarmannequin
      Mannequin

      Yes, the ability to write randrange(1e9) is sometimes nice. And the fact that it might give the number outside the intended range with probability 1e-17 is not really an important argument (people have bad intuitions about very small probabilities). But if we intend to be consistent with range, then of course this must go.

    10. rhettinger commented on Nov 1, 2020

      @rhettinger
      ContributorAuthor

      10**9 isn't much harder than 10E9 ;-)

    11. terryjreedy commented on Nov 7, 2020

      @terryjreedy
      Member

      To me, ValueError("non-integer arg 1 for randrange()") (ValueError('bad type') is a bit painful to read. We do sometime fix such bugs, when not documented, in future releases.

      Current the doc, "Return a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step))", implies that both accept the same values, which most would expect anyway from the names. Being selectively 'generous' in what is accepted is confusing.

      For the future: both range and math.factorial raise
      TypeError: 'float' object cannot be interpreted as an integer
      The consistency is nice. randrange should say the same after deprecation.

    12. terryjreedy commented on Nov 7, 2020

      @terryjreedy
      Member

      To put what I said another way: both items are mental paper cuts and I see benefit to both coredevs and users in getting rid of them. That is not to say 'no cost', but that there is a real benefit to be balanced against the real cost.

    13. rhettinger commented on Dec 25, 2020

      @rhettinger
      ContributorAuthor

      There is another randrange() oddity. If stop is None, the step argument is ignored:

          >>> randrange(100, stop=None, step=10)
          4

      If we want to fully harmonize with range(), then randrange() should only accept positional arguments and should not allow None for the stop argument. That would leave the unoptimized implementation equivalent to:

          def randrange(self, /, *args):
              return self.choice(range(*args))

      The actual implementation can retain its fast paths and have a nicer looking signature perhaps using __text_signature__.

    14. rhettinger commented on Dec 28, 2020

      @rhettinger
      ContributorAuthor

      New changeset a9621bb by Raymond Hettinger in branch 'master':
      bpo-42222: Modernize integer test/conversion in randrange() (bpo-23064)
      a9621bb

    15. rhettinger commented on Oct 16, 2021

      @rhettinger
      ContributorAuthor

      New changeset 5afa0a4 by Raymond Hettinger in branch 'main':
      bpo-42222: Remove deprecated support for non-integer values (GH-28983)
      5afa0a4

    16. ambv commented on Oct 19, 2021

      @ambv
      Contributor

      New changeset 5742416 by Serhiy Storchaka in branch 'main':
      bpo-42222: Improve tests for invalid argument types in randrange() (GH-29021)
      5742416

    17. added
      3.11only security fixes
      and removed on Oct 19, 2021
    18. encukou commented on Feb 3, 2022

      @encukou
      Member

      Since this is a user-visible change in 3.11, could you add a What's New entry?

    19. transferred this issue fromon Apr 10, 2022
    20. added a commit that references this issue on May 12, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.11only 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