mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Don't allow mixed static/non-static overloads
We currently fail at runtime when trying to call a method that is overloaded with both static and non-static methods. This is something python won't allow: the object is either a function or an instance, and can't be both.
This commit is contained in:
parent
90bac96321
commit
d355f2fcca
@ -318,6 +318,15 @@ protected:
|
||||
m_ptr = rec->sibling.ptr();
|
||||
inc_ref();
|
||||
chain_start = chain;
|
||||
if (chain->is_method != rec->is_method)
|
||||
pybind11_fail("overloading a method with both static and instance methods is not supported; "
|
||||
#if defined(NDEBUG)
|
||||
"compile in debug mode for more details"
|
||||
#else
|
||||
"error while attempting to bind " + std::string(rec->is_method ? "instance" : "static") + " method " +
|
||||
std::string(pybind11::str(rec->scope.attr("__name__"))) + "." + std::string(rec->name) + signature
|
||||
#endif
|
||||
);
|
||||
while (chain->next)
|
||||
chain = chain->next;
|
||||
chain->next = rec;
|
||||
|
@ -59,6 +59,8 @@ public:
|
||||
py::str overloaded(int, int) const { return "(int, int) const"; }
|
||||
py::str overloaded(float, float) const { return "(float, float) const"; }
|
||||
|
||||
static py::str overloaded() { return "static"; }
|
||||
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
@ -206,6 +208,17 @@ test_initializer methods_and_attributes([](py::module &m) {
|
||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(int, int) const>(&ExampleMandA::overloaded))
|
||||
.def("overloaded_const", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))
|
||||
#endif
|
||||
// Raise error if trying to mix static/non-static overloads on the same name:
|
||||
.def_static("add_mixed_overloads1", []() {
|
||||
auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests").attr("ExampleMandA"));
|
||||
emna.def ("overload_mixed1", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded))
|
||||
.def_static("overload_mixed1", static_cast<py::str ( *)( )>(&ExampleMandA::overloaded));
|
||||
})
|
||||
.def_static("add_mixed_overloads2", []() {
|
||||
auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(py::module::import("pybind11_tests").attr("ExampleMandA"));
|
||||
emna.def_static("overload_mixed2", static_cast<py::str ( *)( )>(&ExampleMandA::overloaded))
|
||||
.def ("overload_mixed2", static_cast<py::str (ExampleMandA::*)(int, int)>(&ExampleMandA::overloaded));
|
||||
})
|
||||
.def("__str__", &ExampleMandA::toString)
|
||||
.def_readwrite("value", &ExampleMandA::value);
|
||||
|
||||
|
@ -148,6 +148,28 @@ def test_metaclass_override():
|
||||
assert isinstance(MetaclassOverride.__dict__["readonly"], int)
|
||||
|
||||
|
||||
def test_no_mixed_overloads():
|
||||
from pybind11_tests import debug_enabled
|
||||
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
ExampleMandA.add_mixed_overloads1()
|
||||
assert (str(excinfo.value) ==
|
||||
"overloading a method with both static and instance methods is not supported; " +
|
||||
("compile in debug mode for more details" if not debug_enabled else
|
||||
"error while attempting to bind static method ExampleMandA.overload_mixed1"
|
||||
"() -> str")
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError) as excinfo:
|
||||
ExampleMandA.add_mixed_overloads2()
|
||||
assert (str(excinfo.value) ==
|
||||
"overloading a method with both static and instance methods is not supported; " +
|
||||
("compile in debug mode for more details" if not debug_enabled else
|
||||
"error while attempting to bind instance method ExampleMandA.overload_mixed2"
|
||||
"(self: pybind11_tests.ExampleMandA, arg0: int, arg1: int) -> str")
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
|
||||
def test_property_return_value_policies(access):
|
||||
from pybind11_tests import TestPropRVP
|
||||
|
Loading…
Reference in New Issue
Block a user