mirror of
https://github.com/boostorg/python.git
synced 2026-01-23 05:42:30 +00:00
Allow duplicate enum values. Fixes #2744
Thanks to hugo.lima@openbossa.org [SVN r53660]
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#include <boost/python/object_protocol.hpp>
|
||||
#include <structmember.h>
|
||||
|
||||
namespace boost { namespace python { namespace objects {
|
||||
namespace boost { namespace python { namespace objects {
|
||||
|
||||
struct enum_object
|
||||
{
|
||||
@@ -43,7 +43,7 @@ extern "C"
|
||||
char* name = PyString_AsString(self->name);
|
||||
if (name == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
|
||||
}
|
||||
}
|
||||
@@ -139,15 +139,16 @@ namespace
|
||||
dict d;
|
||||
d["__slots__"] = tuple();
|
||||
d["values"] = dict();
|
||||
d["names"] = dict();
|
||||
|
||||
object module_name = module_prefix();
|
||||
if (module_name)
|
||||
d["__module__"] = module_name;
|
||||
if (doc)
|
||||
d["__doc__"] = doc;
|
||||
|
||||
|
||||
object result = (object(metatype))(name, make_tuple(base), d);
|
||||
|
||||
|
||||
scope().attr(name) = result;
|
||||
|
||||
return result;
|
||||
@@ -167,7 +168,7 @@ enum_base::enum_base(
|
||||
converter::registration& converters
|
||||
= const_cast<converter::registration&>(
|
||||
converter::registry::lookup(id));
|
||||
|
||||
|
||||
converters.m_class_object = downcast<PyTypeObject>(this->ptr());
|
||||
converter::registry::insert(to_python, id);
|
||||
converter::registry::insert(convertible, construct, id);
|
||||
@@ -186,23 +187,24 @@ void enum_base::add_value(char const* name_, long value)
|
||||
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
d[value] = x;
|
||||
|
||||
|
||||
// Set the name field in the new enum instanec
|
||||
enum_object* p = downcast<enum_object>(x.ptr());
|
||||
Py_XDECREF(p->name);
|
||||
p->name = incref(name.ptr());
|
||||
|
||||
dict names_dict = extract<dict>(this->attr("names"))();
|
||||
names_dict[x.attr("name")] = x;
|
||||
}
|
||||
|
||||
void enum_base::export_values()
|
||||
{
|
||||
dict d = extract<dict>(this->attr("values"))();
|
||||
list values = d.values();
|
||||
dict d = extract<dict>(this->attr("names"))();
|
||||
list items = d.items();
|
||||
scope current;
|
||||
|
||||
for (unsigned i = 0, max = len(values); i < max; ++i)
|
||||
{
|
||||
api::setattr(current, object(values[i].attr("name")), values[i]);
|
||||
}
|
||||
|
||||
for (unsigned i = 0, max = len(items); i < max; ++i)
|
||||
api::setattr(current, items[i][0], items[i][1]);
|
||||
}
|
||||
|
||||
PyObject* enum_base::to_python(PyTypeObject* type_, long x)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#endif
|
||||
using namespace boost::python;
|
||||
|
||||
enum color { red = 1, green = 2, blue = 4 };
|
||||
enum color { red = 1, green = 2, blue = 4, blood = 1 };
|
||||
|
||||
#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
namespace boost // Pro7 has a hard time detecting enums
|
||||
@@ -34,6 +34,7 @@ BOOST_PYTHON_MODULE(enum_ext)
|
||||
.value("red", red)
|
||||
.value("green", green)
|
||||
.value("blue", blue)
|
||||
.value("blood", blood)
|
||||
.export_values()
|
||||
;
|
||||
|
||||
|
||||
20
test/enum.py
20
test/enum.py
@@ -4,8 +4,8 @@
|
||||
'''
|
||||
>>> from enum_ext import *
|
||||
|
||||
>>> identity(color.red)
|
||||
enum_ext.color.red
|
||||
>>> identity(color.red) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(color.green)
|
||||
enum_ext.color.green
|
||||
@@ -13,8 +13,8 @@ enum_ext.color.green
|
||||
>>> identity(color.blue)
|
||||
enum_ext.color.blue
|
||||
|
||||
>>> identity(color(1))
|
||||
enum_ext.color.red
|
||||
>>> identity(color(1)) # in case of duplicated enums it always take the last enum
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(color(2))
|
||||
enum_ext.color.green
|
||||
@@ -28,7 +28,7 @@ enum_ext.color.blue
|
||||
--- check export to scope ---
|
||||
|
||||
>>> identity(red)
|
||||
enum_ext.color.red
|
||||
enum_ext.color.blood
|
||||
|
||||
>>> identity(green)
|
||||
enum_ext.color.green
|
||||
@@ -42,10 +42,18 @@ enum_ext.color.blue
|
||||
|
||||
>>> c = colorized()
|
||||
>>> c.x
|
||||
enum_ext.color.red
|
||||
enum_ext.color.blood
|
||||
>>> c.x = green
|
||||
>>> c.x
|
||||
enum_ext.color.green
|
||||
>>> red == blood
|
||||
True
|
||||
>>> red == green
|
||||
False
|
||||
>>> hash(red) == hash(blood)
|
||||
True
|
||||
>>> hash(red) == hash(green)
|
||||
False
|
||||
'''
|
||||
|
||||
# pickling of enums only works with Python 2.3 or higher
|
||||
|
||||
Reference in New Issue
Block a user