I would like to return an instance of the following python class, which mimics boost::tribool for three state logic, from my C++ extension module:
class Tribool(object):
def __init__(self, value = None):
if any(value is v for v in (False, True, None)):
self.value = value
else:
raise ValueError("Tribool must be False, True or None")
def __nonzero__(self):
raise TypeError("Tribool may not be used as an implicit bool")
def __eq__(self, other):
if isinstance(other, Tribool):
return self.value is other.value
if any(other is v for v in (False, True, None)):
return self.value is other
raise TypeError("Tribool can only be compared to another Tribool or False, True, or None")
def __ne__(self, other):
return not (self == other)
def __invert__(self):
if self.value is False:
return Tribool(True)
elif self.value is True:
return Tribool(False)
elif self.value is None:
return Tribool(None)
raise ValueError("Tribool must be False, True or None")
def __and__(self, other):
if (self.value is False) or (other.value is False):
return Tribool(False)
if (self.value is None) or (other.value is None):
return Tribool(None)
return Tribool(True)
def __or__(self, other):
if (self.value is True) or (other.value is True):
return Tribool(True)
if (self.value is None) or (other.value is None):
return Tribool(None)
return Tribool(False)
def __xor__(self, other):
if (self.value is None) or (other.value is None):
return Tribool(None)
if self == other:
return Tribool(False)
return Tribool(True)
def __str__(self):
if any(self.value is v for v in (False, True, None)):
return str(self.value)
raise ValueError("Tribool must be False_, True_ or Maybe_")
def __repr__(self):
return "Tribool(%s)" % str(self)
I believe I need to write a to_python_converter, but I cannot figure out how to write a converter for a user defined python type. I have read the Boost Python documentation and searched with Google without finding a good example from which to draw. Any help is appreciated.
Update:
The following C++ code will convert a tribool into the Python values True, False and None which is a partial solution:
struct tribool_to_Tribool
{
static PyObject *convert(tribool const& value)
{
if (value == true) return boost::python::incref(boost::python::object(true).ptr());
else if (value == false) return boost::python::incref(boost::python::object(false).ptr());
else return boost::python::incref(boost::python::object().ptr());
}
};
to_python_converter<tribool,tribool_to_Tribool>();
The part I cannot figure out is how to return an instance of the purely Python Tribool class instead of the values True, False and None from the conversion routine.