[C++-sig] Re: accessing the python type system
David Abrahams
dave at boost-consulting.com
Thu May 29 17:35:37 CEST 2003
Stefan Seefeld <seefeld at sympatico.ca> writes:
> Hi David,
>
> David Abrahams wrote:
>
>>>which means you would be able to hold a boost::python::type
>>>describing another boost::python::type's type (i.e. the result of
>>>'type(type([]))'.
>>>
>>>What do you want to copy here ?
>> I don't want to copy anything. I have no choice; type(type(x)) calls
>> type's copy constructor. I hope that's clear by now.
>
> 'type(x)' is a python expression, right ?
The question was how to reflect that in the Boost.Python library, so
in the sentence above, no: type(x) is a C++ expression.
> The equivalent in C is
>
> PyObject *the_type = PyObject_Type(the_object);
>
> so your statement seems to imply that there already is some C++ wrapper
> code encapsulating a call to PyObject_Type, and resulting in some class'
> copy constructor to be called. Where can I find that ?
It doesn't exist. I was responding speculatively to your request:
"For example holding two python objects I'd like to test whether
one's type is derived from the other's type, whether they are
derived from a given type, i.e. things like 'type', 'isinstance',
etc."
In Python, 'type' is a type, so the most obvious way to reflect that
in C++ would be with a class called 'type', just as we have a class
called tuple in C++ whose constructor performs conversion to a tuple:
x = tuple(some_list);
when I wrote the following, I was pointing out that it doesn't work:
"In principle, there's no reason we shouldn't have something like
you propose, only it should be a wrapper around Python's 'type'
just the same way that boost::python::dict is a wrapper around
Python's 'dict'... but once you start go go down that road you
get in trouble."
> I was assuming that the C++ API would provide a function somewhat
> similar to
>
> object type(const object &o)
> {
> return object(borrowed(PyObject_Type(o.ptr())));
> }
I've been trying to say that I think the right answer is to provide a
boost::python::object called 'type', something like:
object const type = extract<object>(PyTypeObject*);
so you could do:
object y = type(x);
> or, with a suitable 'type' class defined,
>
> type get_type(const object &o)
> {
> return type(borrowed(PyObject_Type(o.ptr())));
> }
>
> in which case there is no copy constructor anywhere.
The latter doesn't work, for all the reasons I've been listing. Users
will expect to be able to do:
object y = type(x);
which leads directly to the copy constructor problem.
Your statement that there's no copy ctor above is also not true; the
type object is copied when it is returned (though that copy may be
elided). That is not just an irrelevant nitpick - if type(type(x)) is
not equivalent to type(x) you will get some very strange results.
>>>Or in diagram form:
>>>
>>> py_object -> py_type
>>> ^ ^
>>> | |
>>>python::object python::type
>> What are those things on the first line of the diagram?
>
> the actual python objects (of type 'PyObject').
I see no reason not to use boost::python::object for both roles.
>> print 'class:',type(x)
>> print 'metaclass:',type(type(x))
>> print 'metametaclass:',type(type(type(x)))
>
> fine, the last line tells me that the 'metametaclass' is a 'type'.
> Applying the 'type' operator to that still returns 'type'. It's just
> one level higher up than what I described. So what ?
So I can make it as many levels higher as I like; you said that type
applied to a metaclass is idempotent. It just isn't true.
> All I was trying to get at is that a way to look at this is as a
> single rooted tree, where each parent node is the 'metaclass' of its
> respective child nodes.
OK, I think I understand how the Python type system is
organized... again, I'm not sure what your point is.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list