-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Always call PyNumber_Index when casting from Python to a C++ integral type, also pre-3.8 #2801
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
2231d9c
2eb35ac
064d671
caa5382
cffc586
8356073
2092295
7fd2db5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -256,6 +256,13 @@ class DeepThought(object): | |
| def __int__(self): | ||
| return 42 | ||
|
|
||
| class DoubleThought(object): | ||
|
||
| def __int__(self): | ||
| return 42 | ||
|
|
||
| def __index__(self): | ||
| return 0 | ||
|
|
||
| class ShallowThought(object): | ||
| pass | ||
|
|
||
|
|
@@ -267,6 +274,13 @@ class IndexedThought(object): | |
| def __index__(self): | ||
| return 42 | ||
|
|
||
| class TypeErrorThought(object): | ||
| def __index__(self): | ||
| raise TypeError | ||
|
|
||
| def __int__(self): | ||
| return 42 | ||
|
|
||
| class RaisingThought(object): | ||
| def __index__(self): | ||
| raise ValueError | ||
|
|
@@ -276,7 +290,7 @@ def __int__(self): | |
|
|
||
| convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert | ||
|
|
||
| def require_implicit(v): | ||
| def requires_conversion(v): | ||
| pytest.raises(TypeError, noconvert, v) | ||
|
|
||
| def cant_convert(v): | ||
|
|
@@ -286,14 +300,20 @@ def cant_convert(v): | |
| assert noconvert(7) == 7 | ||
| cant_convert(3.14159) | ||
| assert convert(DeepThought()) == 42 | ||
| require_implicit(DeepThought()) | ||
| requires_conversion(DeepThought()) | ||
| assert convert(DoubleThought()) == 0 # Fishy; `int(DoubleThought)` == 42 | ||
|
||
| assert noconvert(DoubleThought()) == 0 | ||
| cant_convert(ShallowThought()) | ||
| cant_convert(FuzzyThought()) | ||
| if env.PY >= (3, 8): | ||
| # Before Python 3.8, `int(obj)` does not pick up on `obj.__index__` | ||
| assert convert(IndexedThought()) == 42 | ||
| assert noconvert(IndexedThought()) == 42 | ||
| cant_convert(RaisingThought()) # no fall-back to `__int__`if `__index__` raises | ||
|
|
||
| # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`, | ||
| # but pybind11 "backports" this behavior. | ||
| assert convert(IndexedThought()) == 42 | ||
| assert noconvert(IndexedThought()) == 42 | ||
| assert convert(TypeErrorThought()) == 42 | ||
| requires_conversion(TypeErrorThought()) | ||
| assert convert(RaisingThought()) == 42 | ||
| requires_conversion(RaisingThought()) | ||
|
|
||
|
|
||
| def test_numpy_int_convert(): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, another note: this results in warnings, and I think that's correct. Because it's not just getting out the
longfrom thePyLongobject, but it's also trying to do the conversion.Yes, the C API is quite messy here. And it's only made worse by the structure of this caster.