internals.rst 7.6 KB

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