For more detailed information, search for "rich comparison" here.
Boost.Python supports both automatic overloading and manual overloading of the Rich Comparison operators. The compile-time support is independent of the Python version that is used when compiling Boost.Python extension modules. That is, op_lt for example can always be used, and the C++ operator< will always be bound to the Python method __lt__. However, the run-time behavior will depend on the Python version.
With Python versions before 2.1, the Rich Comparison operators will not be called by Python when any of the six comparison operators (<, <=, ==, !=, >, >=) is used in an expression. The only way to access the corresponding methods is to call them explicitly, e.g. a.__lt__(b). Only with Python versions 2.1 or higher will expressions like a < b work as expected.
To support Rich Comparisions, the Python C API was modified between Python versions 2.0 and 2.1. A new slot was introduced in the PyTypeObject structure: tp_richcompare. For backwards compatibility, a flag (Py_TPFLAGS_HAVE_RICHCOMPARE) has to be set to signal to the Python interpreter that Rich Comparisions are supported by a particular type. There is only one flag for all the six comparison operators. When any of the six operators is wrapped automatically or manually, Boost.Python will set this flag. Attempts to use comparison operators at the Python level that are not defined at the C++ level will then lead to an AttributeError when the Python 2.1 (or higher) interpreter tries, e.g., a.__lt__(b). That is, in general all six operators should be supplied. Automatically wrapped operators and manually wrapped operators can be mixed. For example:
boost::python::class_builder<code> py_code(this_module, "code"); py_code.def(boost::python::constructor<>()); py_code.def(boost::python::constructor<int>()); py_code.def(boost::python::operators<( boost::python::op_eq | boost::python::op_ne)>()); py_code.def(NotImplemented, "__lt__"); py_code.def(NotImplemented, "__le__"); py_code.def(NotImplemented, "__gt__"); py_code.def(NotImplemented, "__ge__");NotImplemented is a simple free function that (currently) has to be provided by the user. For example:
boost::python::ref NotImplemented(const code&, const code&) { return boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count); }See also:
Updated: July 2001