Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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