• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1===================================
2 Boost.Python_ Internals |(logo)|__
3===================================
4
5.. |(logo)| image:: ../../../boost.png
6   :alt: Boost
7   :class: boost-logo
8
9__ ../../../index.htm
10
11.. _`Boost.Python`: index.html
12
13.. _license: ../../../LICENSE_1_0.txt
14
15
16-------------------------------------------------------
17A conversation between Brett Calcott and David Abrahams
18-------------------------------------------------------
19
20:copyright: Copyright David Abrahams and Brett Calcott 2003. See
21            accompanying license_ for terms of use.
22
23In both of these cases, I'm quite capable of reading code - but the
24thing I don't get from scanning the source is a sense of the
25architecture, both structurally, and temporally (er, I mean in what
26order things go on).
27
281) What happens when you do the following::
29
30     struct boring {};
31     ...etc...
32     class_<boring>("boring")
33         ;
34
35There seems to be a fair bit going on.
36
37 - Python needs a new ClassType to be registered.
38 - We need to construct a new type that can hold our boring struct.
39 - Inward and outward converters need to be registered for the type.
40
41Can you gesture in the general direction where these things are done?
42
43  I only have time for a "off-the-top-of-my-head" answer at the moment;
44  I suggest you step through the code with a debugger after reading this
45  to see how it works, fill in details, and make sure I didn't forget
46  anything.
47
48          A new (Python) subclass of Boost.Python.Instance (see
49          libs/python/src/object/class.cpp) is created by invoking
50          Boost.Python.class, the metatype::
51
52                >>> boring = Boost.Python.class(
53                ...     'boring'
54                ...   , bases_tuple       # in this case, just ()
55                ...   , {
56                ...         '__module__' : module_name
57                ...       , '__doc__' : doc_string # optional
58                ...     }
59                ... )
60
61          A handle to this object is stuck in the m_class_object field
62          of the registration associated with ``typeid(boring)``.  The
63          registry will keep that object alive forever, even if you
64          wipe out the 'boring' attribute of the extension module
65          (probably not a good thing).
66
67          Because you didn't specify ``class<boring, non_copyable,
68          ...>``, a to-python converter for boring is registered which
69          copies its argument into a value_holder held by the the
70          Python boring object.
71
72          Because you didn't specify ``class<boring ...>(no_init)``,
73          an ``__init__`` function object is added to the class
74          dictionary which default-constructs a boring in a
75          value_holder (because you didn't specify some smart pointer
76          or derived wrapper class as a holder) held by the Python
77          boring object.
78
79          ``register_class_from_python`` is used to register a
80          from-python converter for ``shared_ptr<boring>``.
81          ``boost::shared_ptr``\ s are special among smart pointers
82          because their Deleter argument can be made to manage the
83          whole Python object, not just the C++ object it contains, no
84          matter how the C++ object is held.
85
86          If there were any ``bases<>``, we'd also be registering the
87          relationship between these base classes and boring in the
88          up/down cast graph (``inheritance.[hpp/cpp]``).
89
90          In earlier versions of the code, we'd be registering lvalue
91          from-python converters for the class here, but now
92          from-python conversion for wrapped classes is handled as a
93          special case, before consulting the registry, if the source
94          Python object's metaclass is the Boost.Python metaclass.
95
96          Hmm, that from-python converter probably ought to be handled
97          the way class converters are, with no explicit conversions
98          registered.
99
1002) Can you give a brief overview of the data structures that are
101   present in the registry
102
103        The registry is simple: it's just a map from typeid ->
104        registration (see boost/python/converter/registrations.hpp).
105        ``lvalue_chain`` and ``rvalue_chain`` are simple endogenous
106        linked lists.
107
108        If you want to know more, just ask.
109
110        If you want to know about the cast graph, ask me something specific in
111        a separate message.
112
113   and an overview of the process that happens as a type makes its
114   way from c++ to python and back again.
115
116  Big subject.  I suggest some background reading: look for relevant
117  info in the LLNL progress reports and the messages they link to.
118  Also,
119
120        http://mail.python.org/pipermail/c++-sig/2002-May/001023.html
121
122        http://mail.python.org/pipermail/c++-sig/2002-December/003115.html
123
124        http://aspn.activestate.com/ASPN/Mail/Message/1280898
125
126        http://mail.python.org/pipermail/c++-sig/2002-July/001755.html
127
128  from c++ to python:
129
130       It depends on the type and the call policies in use or, for
131       ``call<>(...)``, ``call_method<>(...)``, or ``object(...)``, if
132       ``ref`` or ``ptr`` is used.  There are also two basic
133       categories to to-python conversion, "return value" conversion
134       (for Python->C++ calls) and "argument" conversion (for
135       C++->Python calls and explicit ``object()`` conversions).  The
136       behavior of these two categories differs subtly in various ways
137       whose details I forget at the moment.  You can probably find
138       the answers in the above references, and certainly in the code.
139
140       The "default" case is by-value (copying) conversion, which uses
141       to_python_value as a to-python converter.
142
143           Since there can sensibly be only one way to convert any type
144           to python (disregarding the idea of scoped registries for the
145           moment), it makes sense that to-python conversions can be
146           handled by specializing a template.  If the type is one of
147           the types handled by a built-in conversion
148           (builtin_converters.hpp), the corresponding template
149           specialization of to_python_value gets used.
150
151           Otherwise, to_python_value uses the ``m_to_python``
152           function in the registration for the C++ type.
153
154       Other conversions, like by-reference conversions, are only
155       available for wrapped classes, and are requested explicitly by
156       using ``ref(...)``, ``ptr(...)``, or by specifying different
157       CallPolicies for a call, which can cause a different to-python
158       converter to be used.  These conversions are never registered
159       anywhere, though they do need to use the registration to find
160       the Python class corresponding to the C++ type being referred
161       to.  They just build a new Python instance and stick the
162       appropriate Holder instance in it.
163
164
165  from python to C++:
166
167       Once again I think there is a distinction between "return value"
168       and "argument" conversions, and I forget exactly what that is.
169
170       What happens depends on whether an lvalue conversion is needed
171       (see http://mail.python.org/pipermail/c++-sig/2002-May/001023.html)
172       All lvalue conversions are also registered in a type's rvalue
173       conversion chain, since when an rvalue will do, an lvalue is
174       certainly good enough.
175
176       An lvalue conversion can be done in one step (just get me the
177       pointer to the object - it can be ``NULL`` if no conversion is
178       possible) while an rvalue conversion requires two steps to
179       support wrapped function overloading and multiple converters for
180       a given C++ target type: first tell me if a conversion is
181       possible, then construct the converted object as a second step.
182
183