Skip to content

Commit 111423b

Browse files
committed
Implement an enum_ property "name"
The property returns the enum_ value as a string. For example: >>> import module >>> module.enum.VALUE enum.VALUE >>> str(module.enum.VALUE) 'enum.VALUE' >>> module.enum.VALUE.name 'VALUE' This is actually the equivalent of Boost.Python "name" property.
1 parent 6d0b470 commit 111423b

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

docs/classes.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,24 @@ The entries defined by the enumeration type are exposed in the ``__members__`` p
488488
>>> Pet.Kind.__members__
489489
{'Dog': Kind.Dog, 'Cat': Kind.Cat}
490490
491+
The ``name`` property returns the name of the enum value as a unicode string.
492+
493+
.. note::
494+
495+
It is also possible to use ``str(enum)``, however these accomplish different
496+
goals. The following shows how these two approaches differ.
497+
498+
.. code-block:: pycon
499+
500+
>>> p = Pet( "Lucy", Pet.Cat )
501+
>>> pet_type = p.type
502+
>>> pet_type
503+
Pet.Cat
504+
>>> str(pet_type)
505+
'Pet.Cat'
506+
>>> pet_type.name
507+
'Cat'
508+
491509
.. note::
492510

493511
When the special tag ``py::arithmetic()`` is specified to the ``enum_``

include/pybind11/pybind11.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,7 @@ detail::initimpl::pickle_factory<GetState, SetState> pickle(GetState &&g, SetSta
13641364
template <typename Type> class enum_ : public class_<Type> {
13651365
public:
13661366
using class_<Type>::def;
1367+
using class_<Type>::def_property_readonly;
13671368
using class_<Type>::def_property_readonly_static;
13681369
using Scalar = typename std::underlying_type<Type>::type;
13691370

@@ -1381,6 +1382,13 @@ template <typename Type> class enum_ : public class_<Type> {
13811382
}
13821383
return pybind11::str("{}.???").format(name);
13831384
});
1385+
def_property_readonly("name", [m_entries_ptr](Type value) -> pybind11::str {
1386+
for (const auto &kv : reinterpret_borrow<dict>(m_entries_ptr)) {
1387+
if (pybind11::cast<Type>(kv.second[int_(0)]) == value)
1388+
return pybind11::str(kv.first);
1389+
}
1390+
return pybind11::str("???");
1391+
});
13841392
def_property_readonly_static("__doc__", [m_entries_ptr](handle self) {
13851393
std::string docstring;
13861394
const char *tp_doc = ((PyTypeObject *) self.ptr())->tp_doc;

tests/test_enum.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ def test_unscoped_enum():
66
assert str(m.UnscopedEnum.EOne) == "UnscopedEnum.EOne"
77
assert str(m.UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
88
assert str(m.EOne) == "UnscopedEnum.EOne"
9+
10+
# name property
11+
assert m.UnscopedEnum.EOne.name == "EOne"
12+
assert m.UnscopedEnum.ETwo.name == "ETwo"
13+
assert m.EOne.name == "EOne"
14+
# name readonly
15+
with pytest.raises(AttributeError):
16+
m.UnscopedEnum.EOne.name = ""
17+
# name returns a copy
18+
foo = m.UnscopedEnum.EOne.name
19+
foo = "bar"
20+
assert m.UnscopedEnum.EOne.name == "EOne"
21+
922
# __members__ property
1023
assert m.UnscopedEnum.__members__ == \
1124
{"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo}

0 commit comments

Comments
 (0)