From f7d17d4b852a1c4ec0197fc32894313da944a53b Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Fri, 28 Aug 2026 18:02:35 +0200 Subject: [PATCH] [interop] Filter deleted functions from Python-visible overload sets A deleted function is not callable, yet it still entered the overload set and contributed a spurious conversion error to every failed-call report. That defeats SetDetailedException's rule that failures which are all C++ exceptions of one type are re-raised as that type. Un-xfails test34_no_ctors_in_base in test_crossinheritance.py, which expects TypeError for a class whose only constructors are deleted. --- src/interop/interop_wrapper.cxx | 17 ++++++++++++++++- test/test_crossinheritance.py | 1 - 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/interop/interop_wrapper.cxx b/src/interop/interop_wrapper.cxx index 1b5b0eb..3b6d8d4 100644 --- a/src/interop/interop_wrapper.cxx +++ b/src/interop/interop_wrapper.cxx @@ -1173,16 +1173,31 @@ ptrdiff_t interop::GetBaseOffset(TCppScope_t derived, TCppScope_t base, } // method/function reflection information ------------------------------------ +// A deleted overload is not callable, and leaving it in the set adds a +// spurious conversion error to every failed-call report. +static void +remove_deleted_methods(std::vector& methods) { + methods.erase(std::remove_if(methods.begin(), methods.end(), + [](interop::TCppMethod_t m) { + return Cpp::IsFunctionDeleted(m); + }), + methods.end()); +} + void interop::GetClassMethods(TCppScope_t scope, std::vector& methods) { std::lock_guard Lock(InterOpMutex); Cpp::GetClassMethods(scope, methods); + remove_deleted_methods(methods); } std::vector interop::GetMethodsFromName(TCppScope_t scope, const std::string& name) { std::lock_guard Lock(InterOpMutex); - return Cpp::GetFunctionsUsingName(scope, name); + std::vector methods = + Cpp::GetFunctionsUsingName(scope, name); + remove_deleted_methods(methods); + return methods; } std::string interop::GetName(TCppScope_t method) { diff --git a/test/test_crossinheritance.py b/test/test_crossinheritance.py index 7923749..5f38393 100644 --- a/test/test_crossinheritance.py +++ b/test/test_crossinheritance.py @@ -1675,7 +1675,6 @@ def func(self): c = C() assert c.func() == 3 - @mark.xfail(reason="deriving from a ctor-less base does not raise TypeError") def test34_no_ctors_in_base(self): """Base classes with no constructors"""