Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix detail::obj_class_name() to work correctly for meta classes. #4436

Merged
merged 2 commits into from Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/pybind11/pytypes.h
Expand Up @@ -463,7 +463,7 @@ PYBIND11_NAMESPACE_BEGIN(detail)

// Equivalent to obj.__class__.__name__ (or obj.__name__ if obj is a class).
inline const char *obj_class_name(PyObject *obj) {
if (Py_TYPE(obj) == &PyType_Type) {
if (PyType_Check(obj)) {
return reinterpret_cast<PyTypeObject *>(obj)->tp_name;
}
return Py_TYPE(obj)->tp_name;
Expand Down
2 changes: 2 additions & 0 deletions tests/test_class.cpp
Expand Up @@ -55,6 +55,8 @@ void bind_empty0(py::module_ &m) {
} // namespace test_class

TEST_SUBMODULE(class_, m) {
m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); });

// test_instance
struct NoConstructor {
NoConstructor() = default;
Expand Down
11 changes: 10 additions & 1 deletion tests/test_class.py
@@ -1,10 +1,19 @@
import pytest

import env # noqa: F401
import env
from pybind11_tests import ConstructorStats, UserType
from pybind11_tests import class_ as m


def test_obj_class_name():
if env.PYPY:
expected_name = "UserType"
else:
expected_name = "pybind11_tests.UserType"
assert m.obj_class_name(UserType(1)) == expected_name
assert m.obj_class_name(UserType) == expected_name


def test_repr():
assert "pybind11_type" in repr(type(UserType))
assert "UserType" in repr(UserType)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_pytypes.cpp
Expand Up @@ -99,6 +99,8 @@ void m_defs(py::module_ &m) {
} // namespace handle_from_move_only_type_with_operator_PyObject

TEST_SUBMODULE(pytypes, m) {
m.def("obj_class_name", [](py::handle obj) { return py::detail::obj_class_name(obj.ptr()); });

handle_from_move_only_type_with_operator_PyObject::m_defs(m);

// test_bool
Expand Down
6 changes: 6 additions & 0 deletions tests/test_pytypes.py
Expand Up @@ -9,6 +9,12 @@
from pybind11_tests import pytypes as m


def test_obj_class_name():
assert m.obj_class_name(None) == "NoneType"
assert m.obj_class_name(list) == "list"
assert m.obj_class_name([]) == "list"


def test_handle_from_move_only_type_with_operator_PyObject(): # noqa: N802
assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()
assert m.handle_from_move_only_type_with_operator_PyObject_const()
Expand Down