@@ -286,7 +286,10 @@ def __int__(self):
286286
287287 convert , noconvert = m .int_passthrough , m .int_passthrough_noconvert
288288
289- assert doc (convert ) == "int_passthrough(arg0: typing.SupportsInt) -> int"
289+ assert (
290+ doc (convert )
291+ == "int_passthrough(arg0: typing.SupportsInt | typing.SupportsIndex) -> int"
292+ )
290293 assert doc (noconvert ) == "int_passthrough_noconvert(arg0: int) -> int"
291294
292295 def requires_conversion (v ):
@@ -301,7 +304,7 @@ def cant_convert(v):
301304 # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
302305 # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
303306 if sys .version_info < (3 , 10 ) and env .CPYTHON :
304- with env .deprecated_call ():
307+ with pytest .deprecated_call ():
305308 assert convert (Int ()) == 42
306309 else :
307310 assert convert (Int ()) == 42
@@ -322,19 +325,39 @@ def cant_convert(v):
322325
323326
324327def test_float_convert (doc ):
328+ class Int :
329+ def __int__ (self ):
330+ return - 5
331+
332+ class Index :
333+ def __index__ (self ) -> int :
334+ return - 7
335+
325336 class Float :
326337 def __float__ (self ):
327338 return 41.45
328339
329340 convert , noconvert = m .float_passthrough , m .float_passthrough_noconvert
330- assert doc (convert ) == "float_passthrough(arg0: typing.SupportsFloat) -> float"
341+ assert (
342+ doc (convert )
343+ == "float_passthrough(arg0: typing.SupportsFloat | typing.SupportsIndex) -> float"
344+ )
331345 assert doc (noconvert ) == "float_passthrough_noconvert(arg0: float) -> float"
332346
333347 def requires_conversion (v ):
334348 pytest .raises (TypeError , noconvert , v )
335349
350+ def cant_convert (v ):
351+ pytest .raises (TypeError , convert , v )
352+
336353 requires_conversion (Float ())
354+ requires_conversion (Index ())
337355 assert pytest .approx (convert (Float ())) == 41.45
356+ assert pytest .approx (convert (Index ())) == - 7.0
357+ assert isinstance (convert (Float ()), float )
358+ assert pytest .approx (convert (3 )) == 3.0
359+ requires_conversion (3 )
360+ cant_convert (Int ())
338361
339362
340363def test_numpy_int_convert ():
@@ -354,7 +377,7 @@ def require_implicit(v):
354377 # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
355378 # https://github.com/pybind/pybind11/issues/3408
356379 if (3 , 8 ) <= sys .version_info < (3 , 10 ) and env .CPYTHON :
357- with env .deprecated_call ():
380+ with pytest .deprecated_call ():
358381 assert convert (np .float32 (3.14159 )) == 3
359382 else :
360383 assert convert (np .float32 (3.14159 )) == 3
@@ -381,7 +404,7 @@ def test_tuple(doc):
381404 assert (
382405 doc (m .tuple_passthrough )
383406 == """
384- tuple_passthrough(arg0: tuple[bool, str, typing.SupportsInt]) -> tuple[int, str, bool]
407+ tuple_passthrough(arg0: tuple[bool, str, typing.SupportsInt | typing.SupportsIndex ]) -> tuple[int, str, bool]
385408
386409 Return a triple in reversed order
387410 """
@@ -458,11 +481,61 @@ def test_reference_wrapper():
458481 assert m .refwrap_call_iiw (IncType (10 ), m .refwrap_iiw ) == [10 , 10 , 10 , 10 ]
459482
460483
461- def test_complex_cast ():
484+ def test_complex_cast (doc ):
462485 """std::complex casts"""
486+
487+ class Complex :
488+ def __complex__ (self ) -> complex :
489+ return complex (5 , 4 )
490+
491+ class Float :
492+ def __float__ (self ) -> float :
493+ return 5.0
494+
495+ class Int :
496+ def __int__ (self ) -> int :
497+ return 3
498+
499+ class Index :
500+ def __index__ (self ) -> int :
501+ return 1
502+
463503 assert m .complex_cast (1 ) == "1.0"
504+ assert m .complex_cast (1.0 ) == "1.0"
505+ assert m .complex_cast (Complex ()) == "(5.0, 4.0)"
464506 assert m .complex_cast (2j ) == "(0.0, 2.0)"
465507
508+ convert , noconvert = m .complex_convert , m .complex_noconvert
509+
510+ def requires_conversion (v ):
511+ pytest .raises (TypeError , noconvert , v )
512+
513+ def cant_convert (v ):
514+ pytest .raises (TypeError , convert , v )
515+
516+ assert (
517+ doc (convert )
518+ == "complex_convert(arg0: typing.SupportsComplex | typing.SupportsFloat | typing.SupportsIndex) -> complex"
519+ )
520+ assert doc (noconvert ) == "complex_noconvert(arg0: complex) -> complex"
521+
522+ assert convert (1 ) == 1.0
523+ assert convert (2.0 ) == 2.0
524+ assert convert (1 + 5j ) == 1.0 + 5.0j
525+ assert convert (Complex ()) == 5.0 + 4j
526+ assert convert (Float ()) == 5.0
527+ assert isinstance (convert (Float ()), complex )
528+ cant_convert (Int ())
529+ assert convert (Index ()) == 1
530+ assert isinstance (convert (Index ()), complex )
531+
532+ requires_conversion (1 )
533+ requires_conversion (2.0 )
534+ assert noconvert (1 + 5j ) == 1.0 + 5.0j
535+ requires_conversion (Complex ())
536+ requires_conversion (Float ())
537+ requires_conversion (Index ())
538+
466539
467540def test_bool_caster ():
468541 """Test bool caster implicit conversions."""
0 commit comments