Ticket #2744: enum_with_duplicated_values_v2.3.patch

File enum_with_duplicated_values_v2.3.patch, 4.2 KB (added by hugo.lima@…, 14 years ago)

Patch to enum.cpp and their unit tests

  • libs/python/test/enum.py

     
    44'''
    55>>> from enum_ext import *
    66
    7 >>> identity(color.red)
    8 enum_ext.color.red
     7>>> identity(color.red) # in case of duplicated enums it always take the last enum
     8enum_ext.color.blood
    99
    1010>>> identity(color.green)
    1111enum_ext.color.green
     
    1313>>> identity(color.blue)
    1414enum_ext.color.blue
    1515
    16 >>> identity(color(1))
    17 enum_ext.color.red
     16>>> identity(color(1)) # in case of duplicated enums it always take the last enum
     17enum_ext.color.blood
    1818
    1919>>> identity(color(2))
    2020enum_ext.color.green
     
    2828  --- check export to scope ---
    2929
    3030>>> identity(red)
    31 enum_ext.color.red
     31enum_ext.color.blood
    3232
    3333>>> identity(green)
    3434enum_ext.color.green
     
    4242
    4343>>> c = colorized()
    4444>>> c.x
    45 enum_ext.color.red
     45enum_ext.color.blood
    4646>>> c.x = green
    4747>>> c.x
    4848enum_ext.color.green
     49>>> red == blood
     50True
     51>>> red == green
     52False
     53>>> hash(red) == hash(blood)
     54True
     55>>> hash(red) == hash(green)
     56False
    4957'''
    5058
    5159# pickling of enums only works with Python 2.3 or higher
  • libs/python/test/enum.cpp

     
    1212#endif
    1313using namespace boost::python;
    1414
    15 enum color { red = 1, green = 2, blue = 4 };
     15enum color { red = 1, green = 2, blue = 4, blood = 1 };
    1616
    1717#if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
    1818namespace boost  // Pro7 has a hard time detecting enums
     
    3434        .value("red", red)
    3535        .value("green", green)
    3636        .value("blue", blue)
     37        .value("blood", blood)
    3738        .export_values()
    3839        ;
    3940   
  • libs/python/src/object/enum.cpp

     
    1414#include <boost/python/object_protocol.hpp>
    1515#include <structmember.h>
    1616
    17 namespace boost { namespace python { namespace objects { 
     17namespace boost { namespace python { namespace objects {
    1818
    1919struct enum_object
    2020{
     
    4343            char* name = PyString_AsString(self->name);
    4444            if (name == 0)
    4545                return 0;
    46            
     46
    4747            return PyString_FromFormat("%s.%s.%s", mod, self_->ob_type->tp_name, name);
    4848        }
    4949    }
     
    139139      dict d;
    140140      d["__slots__"] = tuple();
    141141      d["values"] = dict();
     142      d["names"] = dict();
    142143
    143144      object module_name = module_prefix();
    144145      if (module_name)
    145146         d["__module__"] = module_name;
    146147      if (doc)
    147148         d["__doc__"] = doc;
    148      
     149
    149150      object result = (object(metatype))(name, make_tuple(base), d);
    150      
     151
    151152      scope().attr(name) = result;
    152153
    153154      return result;
     
    167168    converter::registration& converters
    168169        = const_cast<converter::registration&>(
    169170            converter::registry::lookup(id));
    170            
     171
    171172    converters.m_class_object = downcast<PyTypeObject>(this->ptr());
    172173    converter::registry::insert(to_python, id);
    173174    converter::registry::insert(convertible, construct, id);
     
    186187
    187188    dict d = extract<dict>(this->attr("values"))();
    188189    d[value] = x;
    189    
     190
    190191    // Set the name field in the new enum instanec
    191192    enum_object* p = downcast<enum_object>(x.ptr());
    192193    Py_XDECREF(p->name);
    193194    p->name = incref(name.ptr());
     195
     196    dict names_dict = extract<dict>(this->attr("names"))();
     197    names_dict[x.attr("name")] = x;
    194198}
    195199
    196200void enum_base::export_values()
    197201{
    198     dict d = extract<dict>(this->attr("values"))();
    199     list values = d.values();
     202    dict d = extract<dict>(this->attr("names"))();
     203    list items = d.items();
    200204    scope current;
    201    
    202     for (unsigned i = 0, max = len(values); i < max; ++i)
    203     {
    204         api::setattr(current, object(values[i].attr("name")), values[i]);
    205     }
     205
     206    for (unsigned i = 0, max = len(items); i < max; ++i)
     207        api::setattr(current, items[i][0], items[i][1]);
    206208 }
    207209
    208210PyObject* enum_base::to_python(PyTypeObject* type_, long x)