This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2013年12月28日 19:56 by ethan.furman, last changed 2022年04月11日 14:57 by admin.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| test_index_not_int.py | amitava.b, 2014年06月22日 20:50 | |||
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 13108 | merged | serhiy.storchaka, 2019年05月06日 14:30 | |
| PR 13106 | closed | remi.lapeyre, 2019年05月06日 14:31 | |
| Messages (21) | |||
|---|---|---|---|
| msg207048 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年12月28日 19:56 | |
In order to create a coherent integer type class both __int__ and __index__ must be defined or the resulting instances will behave inconsistently in different places. For example, if __index__ is not defined then the class cannot be used in slices, and if __int__ is not defined then int(integer_type) will fail. At this point the programmer must remember to define both, but since they should return the same value we can have the type constructor automatically assign __int__ to __index__ when the latter is defined and the former is not. This would be similar to how we currently treat __ne__ when __eq__ is defined. |
|||
| msg207050 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2013年12月28日 20:08 | |
__ne__ is not "bound" to __eq__. The comparison code simply falls back onto __eq__ if __ne__ is not defined. |
|||
| msg207051 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年12月28日 20:23 | |
True. I meant similar in that Python will use what's available to fill in the blank: class has __eq__ but user tried != ? use __eq__ and invert result class has __index__ but user tried int() ? use __index__ as-is |
|||
| msg207065 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2013年12月29日 02:19 | |
It is not clear to me that that would be correct, though. Isn't the whole point of __index__ that some types can act as indicies even though they are *not* integers? Shouldn't it be up to the type to decide if converting them to int is a sensible thing to do? Maybe that's being silly/pendantic, though. On the gripping hand, it feels like this is another case of what you have pointed out elsewhere, that it is not clear that we actually have a consistent API here... |
|||
| msg207068 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年12月29日 08:11 | |
In issue19995, in msg206339, Guido exhorted: -------------------------------------------- >> [Ethan claimed] it is possible to want a type that can be used as an >> index or slice but that is still not a number > > I'm sorry, but this requirement is absurd. An index *is* a number. You > have to make up your mind. (I know, in the context of the example that > started this, this is funny, but I still stand by it.) > > Finally, the correct name should perhaps have been __integer__ but I don't > see enough reason to change it now. The de facto API that is forming is that if an actual int is needed from an actual integer type (not float, not complex, not etc.), then __index__ is used. If __index__ is not defined by some numeric type then it will not be considered a true int in certain key places in Python, such as as indices, arguments to hex(), etc. Making the change suggested in the title would help solidify the API. |
|||
| msg207072 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2013年12月29日 13:44 | |
Ah, I see. A link to that issue would have been helpful :). To summarize for anyone like me who didn't follow that issue: __index__ means the object can be losslessly converted to an int (is a true int), while __int__ may be an approximate conversion. Thus it makes sense for an object to have an __int__ but not __index__, but vice-versa does not make sense. Is someone updating the docs to reflect this, or should that be spun off as a separate issue as well? |
|||
| msg207075 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年12月29日 14:57 | |
I have the following as part of the patch for that issue: --------------------------------------------------------- diff -r b668c409c10a Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst Sat Dec 28 20:37:58 2013 +0100 +++ b/Doc/reference/datamodel.rst Sun Dec 29 06:55:11 2013 -0800 @@ -2073,23 +2073,31 @@ left undefined. builtin: float builtin: round Called to implement the built-in functions :func:`complex`, :func:`int`, :func:`float` and :func:`round`. Should return a value of the appropriate type. .. method:: object.__index__(self) - Called to implement :func:`operator.index`. Also called whenever Python needs - an integer object (such as in slicing, or in the built-in :func:`bin`, - :func:`hex` and :func:`oct` functions). Must return an integer. + Called to implement :func:`operator.index`, and whenever Python needs to + losslessly convert the numeric object to an integer object (such as in + slicing, or in the built-in :func:`bin`, :func:`hex` and :func:`oct` + functions). Presence of this method indicates that the numeric object is + an integer type. Must return an integer. + + .. note:: + + When :meth:`__index__` is defined, :meth:`__int__` should also be defined, + and both shuld return the same value, in order to have a coherent integer + type class. --------------------------------------------------------- If for some reason that patch doesn't make it into 3.4 I'll split the doc change off to its own issue, unless you think it should be split off anyway? |
|||
| msg207084 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2013年12月29日 20:06 | |
Nah, splitting it doesn't seem worth it unless you think the patch won't make it in. (Not that I looked at it earlier, but he patch on the issue doesn't look like what you just posted here...and here there's a typo: shuld). |
|||
| msg207085 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2013年12月29日 20:30 | |
I updated it as I liked your wording better. :) Doing more testing to see if anything else needs fixing before I make the next patch for the tracker on that issue. |
|||
| msg207263 - (view) | Author: Terry J. Reedy (terry.reedy) * (Python committer) | Date: 2014年01月04日 00:33 | |
I believe this is my suggestion 2) in msg206715 of #19995, and I think it better than 3) (and 1) alone). Thanks for moving this forward. I believe what Guido said is that indexes (integers in the broad sense) are (or should be) a subset of things convertible to ints. I concur completely. |
|||
| msg221310 - (view) | Author: Amitava Bhattacharyya (amitava.b) | Date: 2014年06月22日 20:50 | |
I started working on this issue as part of the Bloomberg Python Sprint (https://etherpad.mozilla.org/LjZPQ55oZs). Ethan, can you confirm if the attached test case summarizes the issue correctly? I tried to hook _PyLong_FromNbInt to check nb_index but didn't make progress there. Will need to load in a debugger to see what's going on. |
|||
| msg221339 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2014年06月23日 04:14 | |
Yes, that test should pass when this issue is resolved. I can't tell from your comment what you are trying to do to resolve it, but the course of action I had in mind was to have the `type` meta-class make a final examination of the type it was creating, and if that type had __index__ but not __int__ then bind __int__ to __index__. |
|||
| msg221453 - (view) | Author: Amitava Bhattacharyya (amitava.b) | Date: 2014年06月24日 11:56 | |
Hi Ethan, I tried adding a call to `nb_index` (if that slot exists) in `_PyLong_FromNbInt`, but that didn't work. Based on your comment it seems the fix would be to patch this at object creation. I will check where that happens (bear with me while I familiarize myself with the code base :) ). |
|||
| msg221459 - (view) | Author: Ethan Furman (ethan.furman) * (Python committer) | Date: 2014年06月24日 13:48 | |
Thank you for your efforts, Amitava. Please also sign a Contributor's License Agreement so we can actually use your code. :) http://www.python.org/psf/contrib/ |
|||
| msg221474 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2014年06月24日 16:11 | |
There will be a corporate agreement from Bloomberg sometime soon (and that will be required in this case, not an individual agreement). |
|||
| msg221510 - (view) | Author: Amitava Bhattacharyya (amitava.b) | Date: 2014年06月24日 23:27 | |
I did fill in the contributor agreement form and e-signed it, maybe it takes some time for my profile to be updated? But I guess I need to wait for the corporate agreement. :) |
|||
| msg313287 - (view) | Author: Josh Rosenberg (josh.r) * (Python triager) | Date: 2018年03月05日 21:16 | |
Pingback from #33002, which is caused by the fact that parts of the CPython code base that use PyNumber_Index for type conversion still pre-check for valid types with PyNumber_Check, meaning that a type with __index__ and not __int__ gets erroneously rejected by the pre-check. |
|||
| msg341509 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2019年05月06日 14:38 | |
See also the discussion on the duplicated issue33039. Few months ago I wrote the PR that makes constructors of int, float and complex to fall back to __index__ if corresponding special methods __int__, __float__ and __complex__ are not defined. I did not exposed it to public because binding __int__ to __index__ looks better to me. But perhaps some tests from that PR can be used in an alternate PR. |
|||
| msg344206 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2019年06月01日 19:21 | |
I like the delegation of `float` and `complex` to use `__index__` that was introduced in GH-13108; it would be nice to have that regardless of which solution is decided on for `__int__` and `__index__`. |
|||
| msg344234 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) | Date: 2019年06月01日 21:05 | |
New changeset bdbad71b9def0b86433de12cecca022eee91bd9f by Serhiy Storchaka in branch 'master': bpo-20092. Use __index__ in constructors of int, float and complex. (GH-13108) https://github.com/python/cpython/commit/bdbad71b9def0b86433de12cecca022eee91bd9f |
|||
| msg406580 - (view) | Author: Patrick Yang (patrick.yang.1248) | Date: 2021年11月19日 13:14 | |
I ended up in this issue after I learnt the following from the Python Library Reference Manual. ---- float(..). For a general Python object x, float(x) delegates to x.__float__(). If __float__() is not defined then it falls back to __index__(). ---- The discussion on __int__() and __index__() was very interesting but I still didn't get the answer I wanted. If __int__() is assumed to be a possibly approximate conversion and it's possible that __int__() may exist while __index__() doesn't, shouldn't __int__() be used as a fall back before __index__()? The downside would be that the resulting float may not be "very close" to the original object because __int__() is only an approximation while __index__() guarantees exact, but loss of precision is acceptable during type conversion, isn't it? (i.e. int(3.14) -> 3). Perhaps it's not acceptable if the conversion is a widening conversion and that's why __int__() is skipped? |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:56 | admin | set | github: 64291 |
| 2021年11月19日 13:14:29 | patrick.yang.1248 | set | nosy:
+ patrick.yang.1248 messages: + msg406580 |
| 2019年06月01日 21:05:50 | serhiy.storchaka | set | messages: + msg344234 |
| 2019年06月01日 19:21:31 | mark.dickinson | set | messages: + msg344206 |
| 2019年06月01日 19:16:06 | mark.dickinson | set | nosy:
+ mark.dickinson |
| 2019年05月06日 14:38:54 | serhiy.storchaka | set | versions:
+ Python 3.8, - Python 3.5 nosy: + serhiy.storchaka messages: + msg341509 components: + Interpreter Core |
| 2019年05月06日 14:31:39 | remi.lapeyre | set | pull_requests: + pull_request13023 |
| 2019年05月06日 14:30:46 | serhiy.storchaka | set | keywords:
+ patch stage: test needed -> patch review pull_requests: + pull_request13022 |
| 2019年05月06日 14:29:29 | serhiy.storchaka | link | issue33039 superseder |
| 2018年03月05日 21:16:06 | josh.r | set | nosy:
+ josh.r messages: + msg313287 |
| 2015年07月21日 07:58:21 | ethan.furman | set | nosy:
- ethan.furman |
| 2014年06月24日 23:27:35 | amitava.b | set | messages: + msg221510 |
| 2014年06月24日 16:11:56 | r.david.murray | set | messages: + msg221474 |
| 2014年06月24日 13:48:42 | ethan.furman | set | messages: + msg221459 |
| 2014年06月24日 11:56:52 | amitava.b | set | messages: + msg221453 |
| 2014年06月23日 04:14:50 | ethan.furman | set | messages: + msg221339 |
| 2014年06月22日 20:50:11 | amitava.b | set | files:
+ test_index_not_int.py nosy: + trent, amitava.b messages: + msg221310 |
| 2014年01月04日 00:33:51 | terry.reedy | set | stage: test needed |
| 2014年01月04日 00:33:35 | terry.reedy | set | nosy:
+ terry.reedy messages: + msg207263 |
| 2013年12月29日 20:30:07 | ethan.furman | set | messages: + msg207085 |
| 2013年12月29日 20:06:52 | r.david.murray | set | messages: + msg207084 |
| 2013年12月29日 14:57:18 | ethan.furman | set | messages: + msg207075 |
| 2013年12月29日 13:44:05 | r.david.murray | set | messages: + msg207072 |
| 2013年12月29日 08:11:38 | ethan.furman | set | messages: + msg207068 |
| 2013年12月29日 02:19:26 | r.david.murray | set | nosy:
+ r.david.murray messages: + msg207065 |
| 2013年12月28日 20:41:45 | Arfrever | set | nosy:
+ Arfrever |
| 2013年12月28日 20:23:56 | ethan.furman | set | messages: + msg207051 |
| 2013年12月28日 20:08:52 | benjamin.peterson | set | nosy:
+ benjamin.peterson messages: + msg207050 |
| 2013年12月28日 19:56:32 | ethan.furman | create | |