|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r53660 - in trunk/libs/python: src/object test
From: dave_at_[hidden]
Date: 2009-06-05 17:18:15
Author: dave
Date: 2009-06-05 17:18:14 EDT (Fri, 05 Jun 2009)
New Revision: 53660
URL: http://svn.boost.org/trac/boost/changeset/53660
Log:
Allow duplicate enum values. Fixes #2744
Thanks to hugo.lima_at_[hidden]
Text files modified:
trunk/libs/python/src/object/enum.cpp | 28 +++++++++++++++-------------
trunk/libs/python/test/enum.cpp | 3 ++-
trunk/libs/python/test/enum.py | 20 ++++++++++++++------
3 files changed, 31 insertions(+), 20 deletions(-)
Modified: trunk/libs/python/src/object/enum.cpp
==============================================================================
--- trunk/libs/python/src/object/enum.cpp (original)
+++ trunk/libs/python/src/object/enum.cpp 2009-06-05 17:18:14 EDT (Fri, 05 Jun 2009)
@@ -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 @@
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 @@
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 @@
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 @@
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)
Modified: trunk/libs/python/test/enum.cpp
==============================================================================
--- trunk/libs/python/test/enum.cpp (original)
+++ trunk/libs/python/test/enum.cpp 2009-06-05 17:18:14 EDT (Fri, 05 Jun 2009)
@@ -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 @@
.value("red", red)
.value("green", green)
.value("blue", blue)
+ .value("blood", blood)
.export_values()
;
Modified: trunk/libs/python/test/enum.py
==============================================================================
--- trunk/libs/python/test/enum.py (original)
+++ trunk/libs/python/test/enum.py 2009-06-05 17:18:14 EDT (Fri, 05 Jun 2009)
@@ -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 @@
>>> 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 @@
--- check export to scope ---
>>> identity(red)
-enum_ext.color.red
+enum_ext.color.blood
>>> identity(green)
enum_ext.color.green
@@ -42,10 +42,18 @@
>>> 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
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk