boost::python, returning new PyObject references

David Abrahams david.abrahams at rcn.com
Mon Jan 7 17:19:57 CET 2002


----- Original Message -----
From: "Arnaldur Gylfason" <arnaldur at decode.is>

> I am in favor of #3 as well.
> It has been interesting to follow the discussion between you and Guido.
> I think we should work carefully on defining a set of concepts for Python
> objects.
> We´ll just have to accept that there can be objects that don't fit (e.g.
> not defining >= 1 of the sequence methods).
> Users of such objects would have to be aware of that. (They could use them
> as a sequence but be aware that if a
> function/method needs a sequence method the object does not define an
> error/exception would occur).

I disagree. Based on my conversations with Guido, it looks like the Sequence
concept is quite minimal - it probably only implies that __getitem__ is
implemented. Why not make Sequence include everything in the sequence
protocol? Here's why:

Once users have constructed an object wrapping a concept in C++, they should
be able to rely on the operations of that concept being supported by the
object. I want the wrapper to do the concept introspection when it is
constructed/assigned, and throw an exception if there is a violation. At
that point, I want the entire public interface to be available; it should
only throw an exception if they python implementation of the underlying
functionality throws.

I think I am beginning to see why Guido says that an inheritance hierarchy
gets us in trouble: there are too many combinations to create classes for
all of them. Instead, we want some way to combine concepts "on-the-fly". In
other words, you want to be able to write a function that takes a callable
sliceable sequence without first having to create a class which inherits
from all three of these. The only way I can think of to represent that is:

void f(python::object<callable,sliceable,sequence> x)
{
  ...
}


> In view of the discussion I've been wondering about inheritance (e.g. list
> inheriting from sequence).

I /do/ think inheritance is appropriate for dealing with the concrete Python
types like List. So for example we might have

class list : public object<sliceable,mutable,sequence...>
{
    ...
};

We'd have to decide what the default properties for object<> are. Probably
everything.

This is a bigger programming challenge than what we've been considering, but
worth it I think.


> How about defining a python::SequenceConcept and use template parameters:
> Instead of
>      namespace python = boost::python;
>
>      void f( python::sequence & s)
>      {
>           ...
>      }
>
>      ...
>
>      python::sequence s(obj);
>      python::list l;
>
>      ...
>
>      f(s);
>      f(l);
>
> we could have
>
>      namespace python = boost::python;
>
>      template<class SequenceType>
>      void f(SequenceType & s)
>      {
>           boost::function_requires< python::SequenceConcept<SequenceType>
>
> ();
>           ...
>      }
>
>      ...
>
>      python::sequence s(obj);
>      python::list l;
>
>      ...
>
>      f(s);
>      f(l);
>

I don't think there's any reason that C++ functions which are generic over
python types need to be templated. I'd like to help people avoid templates
whenever its appropriate.

Regards,
Dave





More information about the Cplusplus-sig mailing list