classification
Title: Make PyNumber_Index() always returning an exact int instance
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: barry, mark.dickinson, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2020-05-27 07:57 by serhiy.storchaka, last changed 2020-05-28 07:36 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 20443 merged serhiy.storchaka, 2020-05-27 08:04
Messages (4)
msg370054 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-27 07:57
Currently PyNumber_Index() can return something that's an instance of a strict subclass of int. For example PyNumber_Index(Py_True) returns Py_True. The same for operator.index():

>>> import operator
>>> operator.index(True)
True

The proposed PR makes it always return an int.

To avoid possible overhead for creating temporary integer object, added private function _PyNumber_Index() with the past behavior. It can be used for short-living integer objects which for which only its value will be used, but not its methods. For example in the implementation of PyLong_AsLong() and similar functions.

See also issue17576.
msg370064 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-27 11:28
This change conflicts with the test added in issue26202. We perhaps should revert issue26202. This can also affect the user code which depends on range() attributes start, stop and step being instances of the int subclass.
msg370071 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2020-05-27 12:41
The behaviour change for range sounds reasonable to me.

Just to make sure I understand the impact of the change:

- For Python < 3.10, we sometimes convert the range inputs to Python ints, and sometimes don't. For example, a start value of `np.int64(5)` would be converted, but a value of `True` would not be.

- With this change, we'd always convert a non-int to an int, so both `np.int64(1)` and `True` would be converted to a `1` of exact type int.

IMO this is fine; the new behaviour seems more consistent than the old.

>>> import numpy as np
>>> start = np.int64(2)
>>> range(start, 5).start is start
False
>>> start = True
>>> range(start, 5).start is start
True
msg370168 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-28 07:34
New changeset 5f4b229df7812f1788287095eb6b138bb21876a4 by Serhiy Storchaka in branch 'master':
bpo-40792: Make the result of PyNumber_Index() always having exact type int. (GH-20443)
https://github.com/python/cpython/commit/5f4b229df7812f1788287095eb6b138bb21876a4
History
Date User Action Args
2020-05-28 07:36:23serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-05-28 07:34:43serhiy.storchakasetmessages: + msg370168
2020-05-27 12:41:25mark.dickinsonsetmessages: + msg370071
2020-05-27 11:28:38serhiy.storchakasetmessages: + msg370064
2020-05-27 08:04:31serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request19699
2020-05-27 07:57:47serhiy.storchakacreate