__qualname__ and nested class naming fixes (#1171)
A few fixes related to how we set `__qualname__` and how we show the
type name in function signatures:
- `__qualname__` isn't supposed to have the module name at the
beginning, but we've been putting it there. This removes it, while
keeping the `Nested.Class` name chaining.
- print `__module__.__qualname__` rather than `type->tp_name`; the
latter doesn't work properly for nested classes, so we would get
`module.B` rather than `module.A.B` for a class `B` with parent `A`.
This also unifies the Python 3 and PyPy code. Fixes #1166.
- This now sets a `__qualname__` attribute on the type (as would happen
in Python 3.3+) for Python <3.3, including PyPy. While not particularly
important to have in earlier Python versions, it's useful for us to be
able to extracted the nested name, which is why `__qualname__` was
invented in the first place.
- Added tests for the above.
diff --git a/tests/test_class.cpp b/tests/test_class.cpp
index 2221906..927adf3 100644
--- a/tests/test_class.cpp
+++ b/tests/test_class.cpp
@@ -302,6 +302,21 @@
.def(py::init<const BogusImplicitConversion &>());
py::implicitly_convertible<int, BogusImplicitConversion>();
+
+ // test_qualname
+ // #1166: nested class docstring doesn't show nested name
+ // Also related: tests that __qualname__ is set properly
+ struct NestBase {};
+ struct Nested {};
+ py::class_<NestBase> base(m, "NestBase");
+ base.def(py::init<>());
+ py::class_<Nested>(base, "Nested")
+ .def(py::init<>())
+ .def("fn", [](Nested &, int, NestBase &, Nested &) {})
+ .def("fa", [](Nested &, int, NestBase &, Nested &) {},
+ "a"_a, "b"_a, "c"_a);
+ base.def("g", [](NestBase &, Nested &) {});
+ base.def("h", []() { return NestBase(); });
}
template <int N> class BreaksBase { public: virtual ~BreaksBase() = default; };