mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Add typing.SupportsIndex to int/float/complex type hints (#5891)
* Add typing.SupportsIndex to int/float/complex type hints
This corrects a mistake where these types were supported but the type
hint was not updated to reflect that SupportsIndex objects are accepted.
To track the resulting test failures:
The output of
"$(cat PYROOT)"/bin/python3 $HOME/clone/pybind11_scons/run_tests.py $HOME/forked/pybind11 -v
is in
~/logs/pybind11_pr5879_scons_run_tests_v_log_2025-11-10+122217.txt
* Cursor auto-fixes (partial) plus pre-commit cleanup. 7 test failures left to do.
* Fix remaining test failures, partially done by cursor, partially manually.
* Cursor-generated commit: Added the Index() tests from PR 5879.
Summary:
Changes Made
1. **C++ Bindings** (`tests/test_builtin_casters.cpp`)
• Added complex_convert and complex_noconvert functions needed for the tests
2. **Python Tests** (`tests/test_builtin_casters.py`)
`test_float_convert`:
• Added Index class with __index__ returning -7
• Added Int class with __int__ returning -5
• Added test showing Index() works with convert mode: assert pytest.approx(convert(Index())) == -7.0
• Added test showing Index() doesn't work with noconvert mode: requires_conversion(Index())
• Added additional assertions for int literals and Int() class
`test_complex_cast`:
• Expanded the test to include convert and noconvert functionality
• Added Index, Complex, Float, and Int classes
• Added test showing Index() works with convert mode: assert convert(Index()) == 1 and assert isinstance(convert(Index()), complex)
• Added test showing Index() doesn't work with noconvert mode: requires_conversion(Index())
• Added type hint assertions matching the SupportsIndex additions
These tests demonstrate that custom __index__ objects work with float and complex in convert mode, matching the typing.SupportsIndex type hint added in PR
5891.
* Reflect behavior changes going back from PR 5879 to master. This diff will have to be reapplied under PR 5879.
* Add PyPy-specific __index__ handling for complex caster
Extract PyPy-specific __index__ backporting from PR 5879 to fix PyPy 3.10
test failures in PR 5891. This adds:
1. PYBIND11_INDEX_CHECK macro in detail/common.h:
- Uses PyIndex_Check on CPython
- Uses hasattr check on PyPy (workaround for PyPy 7.3.3 behavior)
2. PyPy-specific __index__ handling in complex.h:
- Handles __index__ objects on PyPy 7.3.7's 3.8 which doesn't
implement PyLong_*'s __index__ calls
- Mirrors the logic used in numeric_caster for ints and floats
This backports __index__ handling for PyPy, matching the approach
used in PR 5879's expand-float-strict branch.
This commit is contained in:
committed by
GitHub
parent
73da78c3e4
commit
9f1187f97c
@@ -347,9 +347,12 @@ public:
|
||||
return PyLong_FromUnsignedLongLong((unsigned long long) src);
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(T,
|
||||
io_name<std::is_integral<T>::value>(
|
||||
"typing.SupportsInt", "int", "typing.SupportsFloat", "float"));
|
||||
PYBIND11_TYPE_CASTER(
|
||||
T,
|
||||
io_name<std::is_integral<T>::value>("typing.SupportsInt | typing.SupportsIndex",
|
||||
"int",
|
||||
"typing.SupportsFloat | typing.SupportsIndex",
|
||||
"float"));
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -54,7 +54,23 @@ public:
|
||||
if (!convert && !PyComplex_Check(src.ptr())) {
|
||||
return false;
|
||||
}
|
||||
Py_complex result = PyComplex_AsCComplex(src.ptr());
|
||||
handle src_or_index = src;
|
||||
// PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
|
||||
// The same logic is used in numeric_caster for ints and floats
|
||||
#if defined(PYPY_VERSION)
|
||||
object index;
|
||||
if (PYBIND11_INDEX_CHECK(src.ptr())) {
|
||||
index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));
|
||||
if (!index) {
|
||||
PyErr_Clear();
|
||||
if (!convert)
|
||||
return false;
|
||||
} else {
|
||||
src_or_index = index;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Py_complex result = PyComplex_AsCComplex(src_or_index.ptr());
|
||||
if (result.real == -1.0 && PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
@@ -68,7 +84,10 @@ public:
|
||||
return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
|
||||
PYBIND11_TYPE_CASTER(
|
||||
std::complex<T>,
|
||||
io_name("typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex",
|
||||
"complex"));
|
||||
};
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
|
||||
@@ -322,6 +322,13 @@
|
||||
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString
|
||||
#define PYBIND11_BYTES_SIZE PyBytes_Size
|
||||
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
|
||||
// In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,
|
||||
// while CPython only considers the existence of `nb_index`/`__index__`.
|
||||
#if !defined(PYPY_VERSION)
|
||||
# define PYBIND11_INDEX_CHECK(o) PyIndex_Check(o)
|
||||
#else
|
||||
# define PYBIND11_INDEX_CHECK(o) hasattr(o, "__index__")
|
||||
#endif
|
||||
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
|
||||
#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))
|
||||
#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))
|
||||
|
||||
@@ -363,6 +363,8 @@ TEST_SUBMODULE(builtin_casters, m) {
|
||||
m.def("complex_cast", [](float x) { return "{}"_s.format(x); });
|
||||
m.def("complex_cast",
|
||||
[](std::complex<float> x) { return "({}, {})"_s.format(x.real(), x.imag()); });
|
||||
m.def("complex_convert", [](std::complex<float> x) { return x; });
|
||||
m.def("complex_noconvert", [](std::complex<float> x) { return x; }, py::arg{}.noconvert());
|
||||
|
||||
// test int vs. long (Python 2)
|
||||
m.def("int_cast", []() { return (int) 42; });
|
||||
|
||||
@@ -286,7 +286,10 @@ def test_int_convert(doc):
|
||||
|
||||
convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert
|
||||
|
||||
assert doc(convert) == "int_passthrough(arg0: typing.SupportsInt) -> int"
|
||||
assert (
|
||||
doc(convert)
|
||||
== "int_passthrough(arg0: typing.SupportsInt | typing.SupportsIndex) -> int"
|
||||
)
|
||||
assert doc(noconvert) == "int_passthrough_noconvert(arg0: int) -> int"
|
||||
|
||||
def requires_conversion(v):
|
||||
@@ -322,19 +325,39 @@ def test_int_convert(doc):
|
||||
|
||||
|
||||
def test_float_convert(doc):
|
||||
class Int:
|
||||
def __int__(self):
|
||||
return -5
|
||||
|
||||
class Index:
|
||||
def __index__(self) -> int:
|
||||
return -7
|
||||
|
||||
class Float:
|
||||
def __float__(self):
|
||||
return 41.45
|
||||
|
||||
convert, noconvert = m.float_passthrough, m.float_passthrough_noconvert
|
||||
assert doc(convert) == "float_passthrough(arg0: typing.SupportsFloat) -> float"
|
||||
assert (
|
||||
doc(convert)
|
||||
== "float_passthrough(arg0: typing.SupportsFloat | typing.SupportsIndex) -> float"
|
||||
)
|
||||
assert doc(noconvert) == "float_passthrough_noconvert(arg0: float) -> float"
|
||||
|
||||
def requires_conversion(v):
|
||||
pytest.raises(TypeError, noconvert, v)
|
||||
|
||||
def cant_convert(v):
|
||||
pytest.raises(TypeError, convert, v)
|
||||
|
||||
requires_conversion(Float())
|
||||
requires_conversion(Index())
|
||||
assert pytest.approx(convert(Float())) == 41.45
|
||||
assert pytest.approx(convert(Index())) == -7.0
|
||||
assert isinstance(convert(Float()), float)
|
||||
assert pytest.approx(convert(3)) == 3.0
|
||||
requires_conversion(3)
|
||||
cant_convert(Int())
|
||||
|
||||
|
||||
def test_numpy_int_convert():
|
||||
@@ -381,7 +404,7 @@ def test_tuple(doc):
|
||||
assert (
|
||||
doc(m.tuple_passthrough)
|
||||
== """
|
||||
tuple_passthrough(arg0: tuple[bool, str, typing.SupportsInt]) -> tuple[int, str, bool]
|
||||
tuple_passthrough(arg0: tuple[bool, str, typing.SupportsInt | typing.SupportsIndex]) -> tuple[int, str, bool]
|
||||
|
||||
Return a triple in reversed order
|
||||
"""
|
||||
@@ -458,11 +481,61 @@ def test_reference_wrapper():
|
||||
assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
|
||||
|
||||
|
||||
def test_complex_cast():
|
||||
def test_complex_cast(doc):
|
||||
"""std::complex casts"""
|
||||
|
||||
class Complex:
|
||||
def __complex__(self) -> complex:
|
||||
return complex(5, 4)
|
||||
|
||||
class Float:
|
||||
def __float__(self) -> float:
|
||||
return 5.0
|
||||
|
||||
class Int:
|
||||
def __int__(self) -> int:
|
||||
return 3
|
||||
|
||||
class Index:
|
||||
def __index__(self) -> int:
|
||||
return 1
|
||||
|
||||
assert m.complex_cast(1) == "1.0"
|
||||
assert m.complex_cast(1.0) == "1.0"
|
||||
assert m.complex_cast(Complex()) == "(5.0, 4.0)"
|
||||
assert m.complex_cast(2j) == "(0.0, 2.0)"
|
||||
|
||||
convert, noconvert = m.complex_convert, m.complex_noconvert
|
||||
|
||||
def requires_conversion(v):
|
||||
pytest.raises(TypeError, noconvert, v)
|
||||
|
||||
def cant_convert(v):
|
||||
pytest.raises(TypeError, convert, v)
|
||||
|
||||
assert (
|
||||
doc(convert)
|
||||
== "complex_convert(arg0: typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex) -> complex"
|
||||
)
|
||||
assert doc(noconvert) == "complex_noconvert(arg0: complex) -> complex"
|
||||
|
||||
assert convert(1) == 1.0
|
||||
assert convert(2.0) == 2.0
|
||||
assert convert(1 + 5j) == 1.0 + 5.0j
|
||||
assert convert(Complex()) == 5.0 + 4j
|
||||
assert convert(Float()) == 5.0
|
||||
assert isinstance(convert(Float()), complex)
|
||||
cant_convert(Int())
|
||||
assert convert(Index()) == 1
|
||||
assert isinstance(convert(Index()), complex)
|
||||
|
||||
requires_conversion(1)
|
||||
requires_conversion(2.0)
|
||||
assert noconvert(1 + 5j) == 1.0 + 5.0j
|
||||
requires_conversion(Complex())
|
||||
requires_conversion(Float())
|
||||
requires_conversion(Index())
|
||||
|
||||
|
||||
def test_bool_caster():
|
||||
"""Test bool caster implicit conversions."""
|
||||
|
||||
@@ -140,11 +140,11 @@ def test_cpp_function_roundtrip():
|
||||
def test_function_signatures(doc):
|
||||
assert (
|
||||
doc(m.test_callback3)
|
||||
== "test_callback3(arg0: collections.abc.Callable[[typing.SupportsInt], int]) -> str"
|
||||
== "test_callback3(arg0: collections.abc.Callable[[typing.SupportsInt | typing.SupportsIndex], int]) -> str"
|
||||
)
|
||||
assert (
|
||||
doc(m.test_callback4)
|
||||
== "test_callback4() -> collections.abc.Callable[[typing.SupportsInt], int]"
|
||||
== "test_callback4() -> collections.abc.Callable[[typing.SupportsInt | typing.SupportsIndex], int]"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -163,13 +163,13 @@ def test_qualname(doc):
|
||||
assert (
|
||||
doc(m.NestBase.Nested.fn)
|
||||
== """
|
||||
fn(self: m.class_.NestBase.Nested, arg0: typing.SupportsInt, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
|
||||
fn(self: m.class_.NestBase.Nested, arg0: typing.SupportsInt | typing.SupportsIndex, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
|
||||
"""
|
||||
)
|
||||
assert (
|
||||
doc(m.NestBase.Nested.fa)
|
||||
== """
|
||||
fa(self: m.class_.NestBase.Nested, a: typing.SupportsInt, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
|
||||
fa(self: m.class_.NestBase.Nested, a: typing.SupportsInt | typing.SupportsIndex, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
|
||||
"""
|
||||
)
|
||||
assert m.NestBase.__module__ == "pybind11_tests.class_"
|
||||
|
||||
@@ -75,7 +75,7 @@ def test_noconvert_args(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
ints_preferred(): incompatible function arguments. The following argument types are supported:
|
||||
1. (i: typing.SupportsInt) -> int
|
||||
1. (i: typing.SupportsInt | typing.SupportsIndex) -> int
|
||||
|
||||
Invoked with: 4.0
|
||||
"""
|
||||
|
||||
@@ -20,11 +20,11 @@ def test_docstring_options():
|
||||
|
||||
# options.enable_function_signatures()
|
||||
assert m.test_function3.__doc__.startswith(
|
||||
"test_function3(a: typing.SupportsInt, b: typing.SupportsInt) -> None"
|
||||
"test_function3(a: typing.SupportsInt | typing.SupportsIndex, b: typing.SupportsInt | typing.SupportsIndex) -> None"
|
||||
)
|
||||
|
||||
assert m.test_function4.__doc__.startswith(
|
||||
"test_function4(a: typing.SupportsInt, b: typing.SupportsInt) -> None"
|
||||
"test_function4(a: typing.SupportsInt | typing.SupportsIndex, b: typing.SupportsInt | typing.SupportsIndex) -> None"
|
||||
)
|
||||
assert m.test_function4.__doc__.endswith("A custom docstring\n")
|
||||
|
||||
@@ -37,7 +37,7 @@ def test_docstring_options():
|
||||
|
||||
# RAII destructor
|
||||
assert m.test_function7.__doc__.startswith(
|
||||
"test_function7(a: typing.SupportsInt, b: typing.SupportsInt) -> None"
|
||||
"test_function7(a: typing.SupportsInt | typing.SupportsIndex, b: typing.SupportsInt | typing.SupportsIndex) -> None"
|
||||
)
|
||||
assert m.test_function7.__doc__.endswith("A custom docstring\n")
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ def test_generated_dunder_methods_pos_only():
|
||||
)
|
||||
assert (
|
||||
re.match(
|
||||
r"^__setstate__\(self: [\w\.]+, state: [\w\.]+, /\)",
|
||||
r"^__setstate__\(self: [\w\.]+, state: [\w\. \|]+, /\)",
|
||||
enum_type.__setstate__.__doc__,
|
||||
)
|
||||
is not None
|
||||
|
||||
@@ -78,10 +78,10 @@ def test_init_factory_signature(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
__init__(): incompatible constructor arguments. The following argument types are supported:
|
||||
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: typing.SupportsInt)
|
||||
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: typing.SupportsInt | typing.SupportsIndex)
|
||||
2. m.factory_constructors.TestFactory1(arg0: str)
|
||||
3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)
|
||||
4. m.factory_constructors.TestFactory1(arg0: object, arg1: typing.SupportsInt, arg2: object)
|
||||
4. m.factory_constructors.TestFactory1(arg0: object, arg1: typing.SupportsInt | typing.SupportsIndex, arg2: object)
|
||||
|
||||
Invoked with: 'invalid', 'constructor', 'arguments'
|
||||
"""
|
||||
@@ -93,13 +93,13 @@ def test_init_factory_signature(msg):
|
||||
__init__(*args, **kwargs)
|
||||
Overloaded function.
|
||||
|
||||
1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: typing.SupportsInt) -> None
|
||||
1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: typing.SupportsInt | typing.SupportsIndex) -> None
|
||||
|
||||
2. __init__(self: m.factory_constructors.TestFactory1, arg0: str) -> None
|
||||
|
||||
3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
|
||||
|
||||
4. __init__(self: m.factory_constructors.TestFactory1, arg0: object, arg1: typing.SupportsInt, arg2: object) -> None
|
||||
4. __init__(self: m.factory_constructors.TestFactory1, arg0: object, arg1: typing.SupportsInt | typing.SupportsIndex, arg2: object) -> None
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@@ -9,28 +9,28 @@ from pybind11_tests import kwargs_and_defaults as m
|
||||
def test_function_signatures(doc):
|
||||
assert (
|
||||
doc(m.kw_func0)
|
||||
== "kw_func0(arg0: typing.SupportsInt, arg1: typing.SupportsInt) -> str"
|
||||
== "kw_func0(arg0: typing.SupportsInt | typing.SupportsIndex, arg1: typing.SupportsInt | typing.SupportsIndex) -> str"
|
||||
)
|
||||
assert (
|
||||
doc(m.kw_func1)
|
||||
== "kw_func1(x: typing.SupportsInt, y: typing.SupportsInt) -> str"
|
||||
== "kw_func1(x: typing.SupportsInt | typing.SupportsIndex, y: typing.SupportsInt | typing.SupportsIndex) -> str"
|
||||
)
|
||||
assert (
|
||||
doc(m.kw_func2)
|
||||
== "kw_func2(x: typing.SupportsInt = 100, y: typing.SupportsInt = 200) -> str"
|
||||
== "kw_func2(x: typing.SupportsInt | typing.SupportsIndex = 100, y: typing.SupportsInt | typing.SupportsIndex = 200) -> str"
|
||||
)
|
||||
assert doc(m.kw_func3) == "kw_func3(data: str = 'Hello world!') -> None"
|
||||
assert (
|
||||
doc(m.kw_func4)
|
||||
== "kw_func4(myList: collections.abc.Sequence[typing.SupportsInt] = [13, 17]) -> str"
|
||||
== "kw_func4(myList: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex] = [13, 17]) -> str"
|
||||
)
|
||||
assert (
|
||||
doc(m.kw_func_udl)
|
||||
== "kw_func_udl(x: typing.SupportsInt, y: typing.SupportsInt = 300) -> str"
|
||||
== "kw_func_udl(x: typing.SupportsInt | typing.SupportsIndex, y: typing.SupportsInt | typing.SupportsIndex = 300) -> str"
|
||||
)
|
||||
assert (
|
||||
doc(m.kw_func_udl_z)
|
||||
== "kw_func_udl_z(x: typing.SupportsInt, y: typing.SupportsInt = 0) -> str"
|
||||
== "kw_func_udl_z(x: typing.SupportsInt | typing.SupportsIndex, y: typing.SupportsInt | typing.SupportsIndex = 0) -> str"
|
||||
)
|
||||
assert doc(m.args_function) == "args_function(*args) -> tuple"
|
||||
assert (
|
||||
@@ -42,11 +42,11 @@ def test_function_signatures(doc):
|
||||
)
|
||||
assert (
|
||||
doc(m.KWClass.foo0)
|
||||
== "foo0(self: m.kwargs_and_defaults.KWClass, arg0: typing.SupportsInt, arg1: typing.SupportsFloat) -> None"
|
||||
== "foo0(self: m.kwargs_and_defaults.KWClass, arg0: typing.SupportsInt | typing.SupportsIndex, arg1: typing.SupportsFloat | typing.SupportsIndex) -> None"
|
||||
)
|
||||
assert (
|
||||
doc(m.KWClass.foo1)
|
||||
== "foo1(self: m.kwargs_and_defaults.KWClass, x: typing.SupportsInt, y: typing.SupportsFloat) -> None"
|
||||
== "foo1(self: m.kwargs_and_defaults.KWClass, x: typing.SupportsInt | typing.SupportsIndex, y: typing.SupportsFloat | typing.SupportsIndex) -> None"
|
||||
)
|
||||
assert (
|
||||
doc(m.kw_lb_func0)
|
||||
@@ -138,7 +138,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
|
||||
1. (arg0: typing.SupportsInt, arg1: typing.SupportsFloat, *args) -> tuple
|
||||
1. (arg0: typing.SupportsInt | typing.SupportsIndex, arg1: typing.SupportsFloat | typing.SupportsIndex, *args) -> tuple
|
||||
|
||||
Invoked with: 1
|
||||
"""
|
||||
@@ -149,7 +149,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
|
||||
1. (arg0: typing.SupportsInt, arg1: typing.SupportsFloat, *args) -> tuple
|
||||
1. (arg0: typing.SupportsInt | typing.SupportsIndex, arg1: typing.SupportsFloat | typing.SupportsIndex, *args) -> tuple
|
||||
|
||||
Invoked with:
|
||||
"""
|
||||
@@ -183,7 +183,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
|
||||
1. (i: typing.SupportsInt = 1, j: typing.SupportsFloat = 3.14159, *args, **kwargs) -> tuple
|
||||
1. (i: typing.SupportsInt | typing.SupportsIndex = 1, j: typing.SupportsFloat | typing.SupportsIndex = 3.14159, *args, **kwargs) -> tuple
|
||||
|
||||
Invoked with: 1; kwargs: i=1
|
||||
"""
|
||||
@@ -194,7 +194,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
|
||||
1. (i: typing.SupportsInt = 1, j: typing.SupportsFloat = 3.14159, *args, **kwargs) -> tuple
|
||||
1. (i: typing.SupportsInt | typing.SupportsIndex = 1, j: typing.SupportsFloat | typing.SupportsIndex = 3.14159, *args, **kwargs) -> tuple
|
||||
|
||||
Invoked with: 1, 2; kwargs: j=1
|
||||
"""
|
||||
@@ -211,7 +211,7 @@ def test_mixed_args_and_kwargs(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
args_kwonly(): incompatible function arguments. The following argument types are supported:
|
||||
1. (i: typing.SupportsInt, j: typing.SupportsFloat, *args, z: typing.SupportsInt) -> tuple
|
||||
1. (i: typing.SupportsInt | typing.SupportsIndex, j: typing.SupportsFloat | typing.SupportsIndex, *args, z: typing.SupportsInt | typing.SupportsIndex) -> tuple
|
||||
|
||||
Invoked with: 2, 2.5, 22
|
||||
"""
|
||||
@@ -233,12 +233,12 @@ def test_mixed_args_and_kwargs(msg):
|
||||
)
|
||||
assert (
|
||||
m.args_kwonly_kwargs.__doc__
|
||||
== "args_kwonly_kwargs(i: typing.SupportsInt, j: typing.SupportsFloat, *args, z: typing.SupportsInt, **kwargs) -> tuple\n"
|
||||
== "args_kwonly_kwargs(i: typing.SupportsInt | typing.SupportsIndex, j: typing.SupportsFloat | typing.SupportsIndex, *args, z: typing.SupportsInt | typing.SupportsIndex, **kwargs) -> tuple\n"
|
||||
)
|
||||
|
||||
assert (
|
||||
m.args_kwonly_kwargs_defaults.__doc__
|
||||
== "args_kwonly_kwargs_defaults(i: typing.SupportsInt = 1, j: typing.SupportsFloat = 3.14159, *args, z: typing.SupportsInt = 42, **kwargs) -> tuple\n"
|
||||
== "args_kwonly_kwargs_defaults(i: typing.SupportsInt | typing.SupportsIndex = 1, j: typing.SupportsFloat | typing.SupportsIndex = 3.14159, *args, z: typing.SupportsInt | typing.SupportsIndex = 42, **kwargs) -> tuple\n"
|
||||
)
|
||||
assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})
|
||||
assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})
|
||||
@@ -294,11 +294,11 @@ def test_keyword_only_args(msg):
|
||||
x.method(i=1, j=2)
|
||||
assert (
|
||||
m.first_arg_kw_only.__init__.__doc__
|
||||
== "__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: typing.SupportsInt = 0) -> None\n"
|
||||
== "__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: typing.SupportsInt | typing.SupportsIndex = 0) -> None\n"
|
||||
)
|
||||
assert (
|
||||
m.first_arg_kw_only.method.__doc__
|
||||
== "method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: typing.SupportsInt = 1, j: typing.SupportsInt = 2) -> None\n"
|
||||
== "method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: typing.SupportsInt | typing.SupportsIndex = 1, j: typing.SupportsInt | typing.SupportsIndex = 2) -> None\n"
|
||||
)
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ def test_positional_only_args():
|
||||
# Mix it with args and kwargs:
|
||||
assert (
|
||||
m.args_kwonly_full_monty.__doc__
|
||||
== "args_kwonly_full_monty(arg0: typing.SupportsInt = 1, arg1: typing.SupportsInt = 2, /, j: typing.SupportsFloat = 3.14159, *args, z: typing.SupportsInt = 42, **kwargs) -> tuple\n"
|
||||
== "args_kwonly_full_monty(arg0: typing.SupportsInt | typing.SupportsIndex = 1, arg1: typing.SupportsInt | typing.SupportsIndex = 2, /, j: typing.SupportsFloat | typing.SupportsIndex = 3.14159, *args, z: typing.SupportsInt | typing.SupportsIndex = 42, **kwargs) -> tuple\n"
|
||||
)
|
||||
assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})
|
||||
assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})
|
||||
@@ -387,30 +387,30 @@ def test_positional_only_args():
|
||||
# https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987
|
||||
assert (
|
||||
m.first_arg_kw_only.pos_only.__doc__
|
||||
== "pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: typing.SupportsInt, j: typing.SupportsInt) -> None\n"
|
||||
== "pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: typing.SupportsInt | typing.SupportsIndex, j: typing.SupportsInt | typing.SupportsIndex) -> None\n"
|
||||
)
|
||||
|
||||
|
||||
def test_signatures():
|
||||
assert (
|
||||
m.kw_only_all.__doc__
|
||||
== "kw_only_all(*, i: typing.SupportsInt, j: typing.SupportsInt) -> tuple\n"
|
||||
== "kw_only_all(*, i: typing.SupportsInt | typing.SupportsIndex, j: typing.SupportsInt | typing.SupportsIndex) -> tuple\n"
|
||||
)
|
||||
assert (
|
||||
m.kw_only_mixed.__doc__
|
||||
== "kw_only_mixed(i: typing.SupportsInt, *, j: typing.SupportsInt) -> tuple\n"
|
||||
== "kw_only_mixed(i: typing.SupportsInt | typing.SupportsIndex, *, j: typing.SupportsInt | typing.SupportsIndex) -> tuple\n"
|
||||
)
|
||||
assert (
|
||||
m.pos_only_all.__doc__
|
||||
== "pos_only_all(i: typing.SupportsInt, j: typing.SupportsInt, /) -> tuple\n"
|
||||
== "pos_only_all(i: typing.SupportsInt | typing.SupportsIndex, j: typing.SupportsInt | typing.SupportsIndex, /) -> tuple\n"
|
||||
)
|
||||
assert (
|
||||
m.pos_only_mix.__doc__
|
||||
== "pos_only_mix(i: typing.SupportsInt, /, j: typing.SupportsInt) -> tuple\n"
|
||||
== "pos_only_mix(i: typing.SupportsInt | typing.SupportsIndex, /, j: typing.SupportsInt | typing.SupportsIndex) -> tuple\n"
|
||||
)
|
||||
assert (
|
||||
m.pos_kw_only_mix.__doc__
|
||||
== "pos_kw_only_mix(i: typing.SupportsInt, /, j: typing.SupportsInt, *, k: typing.SupportsInt) -> tuple\n"
|
||||
== "pos_kw_only_mix(i: typing.SupportsInt | typing.SupportsIndex, /, j: typing.SupportsInt | typing.SupportsIndex, *, k: typing.SupportsInt | typing.SupportsIndex) -> tuple\n"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ def test_no_mixed_overloads():
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details"
|
||||
if not detailed_error_messages_enabled
|
||||
else "error while attempting to bind static method ExampleMandA.overload_mixed1"
|
||||
"(arg0: typing.SupportsFloat) -> str"
|
||||
"(arg0: typing.SupportsFloat | typing.SupportsIndex) -> str"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -264,7 +264,7 @@ def test_no_mixed_overloads():
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details"
|
||||
if not detailed_error_messages_enabled
|
||||
else "error while attempting to bind instance method ExampleMandA.overload_mixed2"
|
||||
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: typing.SupportsInt, arg1: typing.SupportsInt)"
|
||||
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: typing.SupportsInt | typing.SupportsIndex, arg1: typing.SupportsInt | typing.SupportsIndex)"
|
||||
" -> str"
|
||||
)
|
||||
)
|
||||
@@ -491,7 +491,7 @@ def test_str_issue(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
__init__(): incompatible constructor arguments. The following argument types are supported:
|
||||
1. m.methods_and_attributes.StrIssue(arg0: typing.SupportsInt)
|
||||
1. m.methods_and_attributes.StrIssue(arg0: typing.SupportsInt | typing.SupportsIndex)
|
||||
2. m.methods_and_attributes.StrIssue()
|
||||
|
||||
Invoked with: 'no', 'such', 'constructor'
|
||||
@@ -534,21 +534,27 @@ def test_overload_ordering():
|
||||
assert m.overload_order(0) == 4
|
||||
|
||||
assert (
|
||||
"1. overload_order(arg0: typing.SupportsInt) -> int" in m.overload_order.__doc__
|
||||
"1. overload_order(arg0: typing.SupportsInt | typing.SupportsIndex) -> int"
|
||||
in m.overload_order.__doc__
|
||||
)
|
||||
assert "2. overload_order(arg0: str) -> int" in m.overload_order.__doc__
|
||||
assert "3. overload_order(arg0: str) -> int" in m.overload_order.__doc__
|
||||
assert (
|
||||
"4. overload_order(arg0: typing.SupportsInt) -> int" in m.overload_order.__doc__
|
||||
"4. overload_order(arg0: typing.SupportsInt | typing.SupportsIndex) -> int"
|
||||
in m.overload_order.__doc__
|
||||
)
|
||||
|
||||
with pytest.raises(TypeError) as err:
|
||||
m.overload_order(1.1)
|
||||
|
||||
assert "1. (arg0: typing.SupportsInt) -> int" in str(err.value)
|
||||
assert "1. (arg0: typing.SupportsInt | typing.SupportsIndex) -> int" in str(
|
||||
err.value
|
||||
)
|
||||
assert "2. (arg0: str) -> int" in str(err.value)
|
||||
assert "3. (arg0: str) -> int" in str(err.value)
|
||||
assert "4. (arg0: typing.SupportsInt) -> int" in str(err.value)
|
||||
assert "4. (arg0: typing.SupportsInt | typing.SupportsIndex) -> int" in str(
|
||||
err.value
|
||||
)
|
||||
|
||||
|
||||
def test_rvalue_ref_param():
|
||||
|
||||
@@ -367,7 +367,7 @@ def test_complex_array():
|
||||
def test_signature(doc):
|
||||
assert (
|
||||
doc(m.create_rec_nested)
|
||||
== "create_rec_nested(arg0: typing.SupportsInt) -> numpy.typing.NDArray[NestedStruct]"
|
||||
== "create_rec_nested(arg0: typing.SupportsInt | typing.SupportsIndex) -> numpy.typing.NDArray[NestedStruct]"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -211,11 +211,11 @@ def test_passthrough_arguments(doc):
|
||||
"vec_passthrough("
|
||||
+ ", ".join(
|
||||
[
|
||||
"arg0: typing.SupportsFloat",
|
||||
"arg0: typing.SupportsFloat | typing.SupportsIndex",
|
||||
"arg1: typing.Annotated[numpy.typing.ArrayLike, numpy.float64]",
|
||||
"arg2: typing.Annotated[numpy.typing.ArrayLike, numpy.float64]",
|
||||
"arg3: typing.Annotated[numpy.typing.ArrayLike, numpy.int32]",
|
||||
"arg4: typing.SupportsInt",
|
||||
"arg4: typing.SupportsInt | typing.SupportsIndex",
|
||||
"arg5: m.numpy_vectorize.NonPODClass",
|
||||
"arg6: typing.Annotated[numpy.typing.ArrayLike, numpy.float64]",
|
||||
]
|
||||
|
||||
@@ -944,14 +944,14 @@ def test_tuple_variable_length_annotations(doc):
|
||||
def test_dict_annotations(doc):
|
||||
assert (
|
||||
doc(m.annotate_dict_str_int)
|
||||
== "annotate_dict_str_int(arg0: dict[str, typing.SupportsInt]) -> None"
|
||||
== "annotate_dict_str_int(arg0: dict[str, typing.SupportsInt | typing.SupportsIndex]) -> None"
|
||||
)
|
||||
|
||||
|
||||
def test_list_annotations(doc):
|
||||
assert (
|
||||
doc(m.annotate_list_int)
|
||||
== "annotate_list_int(arg0: list[typing.SupportsInt]) -> None"
|
||||
== "annotate_list_int(arg0: list[typing.SupportsInt | typing.SupportsIndex]) -> None"
|
||||
)
|
||||
|
||||
|
||||
@@ -969,7 +969,7 @@ def test_iterable_annotations(doc):
|
||||
def test_iterator_annotations(doc):
|
||||
assert (
|
||||
doc(m.annotate_iterator_int)
|
||||
== "annotate_iterator_int(arg0: collections.abc.Iterator[typing.SupportsInt]) -> None"
|
||||
== "annotate_iterator_int(arg0: collections.abc.Iterator[typing.SupportsInt | typing.SupportsIndex]) -> None"
|
||||
)
|
||||
|
||||
|
||||
@@ -989,7 +989,8 @@ def test_fn_return_only(doc):
|
||||
|
||||
def test_type_annotation(doc):
|
||||
assert (
|
||||
doc(m.annotate_type) == "annotate_type(arg0: type[typing.SupportsInt]) -> type"
|
||||
doc(m.annotate_type)
|
||||
== "annotate_type(arg0: type[typing.SupportsInt | typing.SupportsIndex]) -> type"
|
||||
)
|
||||
|
||||
|
||||
@@ -1007,7 +1008,7 @@ def test_union_typing_only(doc):
|
||||
def test_union_object_annotations(doc):
|
||||
assert (
|
||||
doc(m.annotate_union_to_object)
|
||||
== "annotate_union_to_object(arg0: typing.SupportsInt | str) -> object"
|
||||
== "annotate_union_to_object(arg0: typing.SupportsInt | typing.SupportsIndex | str) -> object"
|
||||
)
|
||||
|
||||
|
||||
@@ -1044,7 +1045,7 @@ def test_never_annotation(doc, backport_typehints):
|
||||
def test_optional_object_annotations(doc):
|
||||
assert (
|
||||
doc(m.annotate_optional_to_object)
|
||||
== "annotate_optional_to_object(arg0: typing.SupportsInt | None) -> object"
|
||||
== "annotate_optional_to_object(arg0: typing.SupportsInt | typing.SupportsIndex | None) -> object"
|
||||
)
|
||||
|
||||
|
||||
@@ -1167,7 +1168,10 @@ def get_annotations_helper(o):
|
||||
def test_module_attribute_types() -> None:
|
||||
module_annotations = get_annotations_helper(m)
|
||||
|
||||
assert module_annotations["list_int"] == "list[typing.SupportsInt]"
|
||||
assert (
|
||||
module_annotations["list_int"]
|
||||
== "list[typing.SupportsInt | typing.SupportsIndex]"
|
||||
)
|
||||
assert module_annotations["set_str"] == "set[str]"
|
||||
assert module_annotations["foo"] == "pybind11_tests.pytypes.foo"
|
||||
|
||||
@@ -1190,7 +1194,10 @@ def test_get_annotations_compliance() -> None:
|
||||
|
||||
module_annotations = get_annotations(m)
|
||||
|
||||
assert module_annotations["list_int"] == "list[typing.SupportsInt]"
|
||||
assert (
|
||||
module_annotations["list_int"]
|
||||
== "list[typing.SupportsInt | typing.SupportsIndex]"
|
||||
)
|
||||
assert module_annotations["set_str"] == "set[str]"
|
||||
|
||||
|
||||
@@ -1204,10 +1211,13 @@ def test_class_attribute_types() -> None:
|
||||
instance_annotations = get_annotations_helper(m.Instance)
|
||||
|
||||
assert empty_annotations is None
|
||||
assert static_annotations["x"] == "typing.ClassVar[typing.SupportsFloat]"
|
||||
assert (
|
||||
static_annotations["x"]
|
||||
== "typing.ClassVar[typing.SupportsFloat | typing.SupportsIndex]"
|
||||
)
|
||||
assert (
|
||||
static_annotations["dict_str_int"]
|
||||
== "typing.ClassVar[dict[str, typing.SupportsInt]]"
|
||||
== "typing.ClassVar[dict[str, typing.SupportsInt | typing.SupportsIndex]]"
|
||||
)
|
||||
|
||||
assert m.Static.x == 1.0
|
||||
@@ -1219,7 +1229,7 @@ def test_class_attribute_types() -> None:
|
||||
static.dict_str_int["hi"] = 3
|
||||
assert m.Static().dict_str_int == {"hi": 3}
|
||||
|
||||
assert instance_annotations["y"] == "typing.SupportsFloat"
|
||||
assert instance_annotations["y"] == "typing.SupportsFloat | typing.SupportsIndex"
|
||||
instance1 = m.Instance()
|
||||
instance1.y = 4.0
|
||||
|
||||
@@ -1236,7 +1246,10 @@ def test_class_attribute_types() -> None:
|
||||
def test_redeclaration_attr_with_type_hint() -> None:
|
||||
obj = m.Instance()
|
||||
m.attr_with_type_hint_float_x(obj)
|
||||
assert get_annotations_helper(obj)["x"] == "typing.SupportsFloat"
|
||||
assert (
|
||||
get_annotations_helper(obj)["x"]
|
||||
== "typing.SupportsFloat | typing.SupportsIndex"
|
||||
)
|
||||
with pytest.raises(
|
||||
RuntimeError, match=r'^__annotations__\["x"\] was set already\.$'
|
||||
):
|
||||
|
||||
@@ -22,7 +22,7 @@ def test_vector(doc):
|
||||
assert doc(m.cast_vector) == "cast_vector() -> list[int]"
|
||||
assert (
|
||||
doc(m.load_vector)
|
||||
== "load_vector(arg0: collections.abc.Sequence[typing.SupportsInt]) -> bool"
|
||||
== "load_vector(arg0: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex]) -> bool"
|
||||
)
|
||||
|
||||
# Test regression caused by 936: pointers to stl containers weren't castable
|
||||
@@ -51,7 +51,7 @@ def test_array(doc):
|
||||
)
|
||||
assert (
|
||||
doc(m.load_array)
|
||||
== 'load_array(arg0: typing.Annotated[collections.abc.Sequence[typing.SupportsInt], "FixedSize(2)"]) -> bool'
|
||||
== 'load_array(arg0: typing.Annotated[collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex], "FixedSize(2)"]) -> bool'
|
||||
)
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ def test_valarray(doc):
|
||||
assert doc(m.cast_valarray) == "cast_valarray() -> list[int]"
|
||||
assert (
|
||||
doc(m.load_valarray)
|
||||
== "load_valarray(arg0: collections.abc.Sequence[typing.SupportsInt]) -> bool"
|
||||
== "load_valarray(arg0: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex]) -> bool"
|
||||
)
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ def test_reference_sensitive_optional(doc):
|
||||
|
||||
assert (
|
||||
doc(m.double_or_zero_refsensitive)
|
||||
== "double_or_zero_refsensitive(arg0: typing.SupportsInt | None) -> int"
|
||||
== "double_or_zero_refsensitive(arg0: typing.SupportsInt | typing.SupportsIndex | None) -> int"
|
||||
)
|
||||
|
||||
assert m.half_or_none_refsensitive(0) is None
|
||||
@@ -352,7 +352,7 @@ def test_variant(doc):
|
||||
|
||||
assert (
|
||||
doc(m.load_variant)
|
||||
== "load_variant(arg0: typing.SupportsInt | str | typing.SupportsFloat | None) -> str"
|
||||
== "load_variant(arg0: typing.SupportsInt | typing.SupportsIndex | str | typing.SupportsFloat | typing.SupportsIndex | None) -> str"
|
||||
)
|
||||
|
||||
|
||||
@@ -368,7 +368,7 @@ def test_variant_monostate(doc):
|
||||
|
||||
assert (
|
||||
doc(m.load_monostate_variant)
|
||||
== "load_monostate_variant(arg0: None | typing.SupportsInt | str) -> str"
|
||||
== "load_monostate_variant(arg0: None | typing.SupportsInt | typing.SupportsIndex | str) -> str"
|
||||
)
|
||||
|
||||
|
||||
@@ -388,7 +388,7 @@ def test_stl_pass_by_pointer(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
||||
1. (v: collections.abc.Sequence[typing.SupportsInt] = None) -> list[int]
|
||||
1. (v: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex] = None) -> list[int]
|
||||
|
||||
Invoked with:
|
||||
"""
|
||||
@@ -400,7 +400,7 @@ def test_stl_pass_by_pointer(msg):
|
||||
msg(excinfo.value)
|
||||
== """
|
||||
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
||||
1. (v: collections.abc.Sequence[typing.SupportsInt] = None) -> list[int]
|
||||
1. (v: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex] = None) -> list[int]
|
||||
|
||||
Invoked with: None
|
||||
"""
|
||||
@@ -615,7 +615,7 @@ def test_sequence_caster_protocol(doc):
|
||||
# convert mode
|
||||
assert (
|
||||
doc(m.roundtrip_std_vector_int)
|
||||
== "roundtrip_std_vector_int(arg0: collections.abc.Sequence[typing.SupportsInt]) -> list[int]"
|
||||
== "roundtrip_std_vector_int(arg0: collections.abc.Sequence[typing.SupportsInt | typing.SupportsIndex]) -> list[int]"
|
||||
)
|
||||
assert m.roundtrip_std_vector_int([1, 2, 3]) == [1, 2, 3]
|
||||
assert m.roundtrip_std_vector_int((1, 2, 3)) == [1, 2, 3]
|
||||
@@ -668,7 +668,7 @@ def test_mapping_caster_protocol(doc):
|
||||
# convert mode
|
||||
assert (
|
||||
doc(m.roundtrip_std_map_str_int)
|
||||
== "roundtrip_std_map_str_int(arg0: collections.abc.Mapping[str, typing.SupportsInt]) -> dict[str, int]"
|
||||
== "roundtrip_std_map_str_int(arg0: collections.abc.Mapping[str, typing.SupportsInt | typing.SupportsIndex]) -> dict[str, int]"
|
||||
)
|
||||
assert m.roundtrip_std_map_str_int(a1b2c3) == a1b2c3
|
||||
assert m.roundtrip_std_map_str_int(FormalMappingLike(**a1b2c3)) == a1b2c3
|
||||
@@ -714,7 +714,7 @@ def test_set_caster_protocol(doc):
|
||||
# convert mode
|
||||
assert (
|
||||
doc(m.roundtrip_std_set_int)
|
||||
== "roundtrip_std_set_int(arg0: collections.abc.Set[typing.SupportsInt]) -> set[int]"
|
||||
== "roundtrip_std_set_int(arg0: collections.abc.Set[typing.SupportsInt | typing.SupportsIndex]) -> set[int]"
|
||||
)
|
||||
assert m.roundtrip_std_set_int({1, 2, 3}) == {1, 2, 3}
|
||||
assert m.roundtrip_std_set_int(FormalSetLike(1, 2, 3)) == {1, 2, 3}
|
||||
|
||||
@@ -103,7 +103,8 @@ def test_return_list_pyobject_ptr_reference():
|
||||
|
||||
def test_type_caster_name_via_incompatible_function_arguments_type_error():
|
||||
with pytest.raises(
|
||||
TypeError, match=r"1\. \(arg0: object, arg1: typing.SupportsInt\) -> None"
|
||||
TypeError,
|
||||
match=r"1\. \(arg0: object, arg1: typing.SupportsInt \| typing.SupportsIndex\) -> None",
|
||||
):
|
||||
m.pass_pyobject_ptr_and_int(ValueHolder(101), ValueHolder(202))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user