concepts.qbk 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. [chapter Concepts
  2. [quickbook 1.7]
  3. ]
  4. [section CallPolicies]
  5. [section Introduction]
  6. Models of the CallPolicies concept are used to specialize the behavior of Python callable objects
  7. generated by Boost.Python to wrapped C++ objects like function and member function pointers,
  8. providing three behaviors:
  9. # `precall` - Python argument tuple management before the wrapped object is invoked
  10. # `result_converter` - C++ return value handling
  11. # `postcall` - Python argument tuple and result management after the wrapped object is invoked
  12. # `extract_return_type` - metafunction for extracting the return type from a given signature type sequence
  13. [endsect]
  14. [section CallPolicies Composition]
  15. In order to allow the use of multiple models of CallPolicies in the same callable object,
  16. Boost.Python's CallPolicies class templates provide a chaining interface which allows them to be
  17. recursively composed. This interface takes the form of an optional template parameter, `Base`, which
  18. defaults to `default_call_policies`. By convention, the `precall` function of the `Base` is invoked after
  19. the `precall` function supplied by the `outer` template, and the `postcall` function of the `Base` is invoked
  20. before the `postcall` function of the `outer` template. If a `result_converter` is supplied by the `outer`
  21. template, it replaces any `result_converter` supplied by the `Base`. For an example, see
  22. `return_internal_reference`.
  23. [endsect]
  24. [section Concept Requirements]
  25. [table
  26. [[Expression][Type][Result/Semantics]]
  27. [[`x.precall(a)`][convertible to `bool`]
  28. [returns `false` and `PyErr_Occurred() != 0` upon failure, `true` otherwise.]]
  29. [[`P::result_converter`][A model of `ResultConverterGenerator`.]
  30. [An MPL unary Metafunction Class used produce the "preliminary" result object.]]
  31. [[`x.postcall(a, r)`][convertible to `PyObject*`]
  32. [`0` and `PyErr_Occurred() != 0` upon failure. Must "conserve references" even in the event of an exception. In other words, if `r` is not returned, its reference count must be decremented; if another existing object is returned, its reference count must be incremented.]]
  33. [[`P::extract_return_type`][A model of Metafunction.]
  34. [An MPL unary Metafunction used extract the return type from a given signature. By default it is derived from `mpl::front`.]]
  35. ]
  36. [endsect]
  37. [endsect]
  38. [section Dereferenceable]
  39. [section Introduction]
  40. Instances of a `Dereferenceable` type can be used like a pointer to access an lvalue.
  41. [endsect]
  42. [section Concept Requirements]
  43. In the table below, `T` is a model of Dereferenceable, and `x` denotes an object of type `T`. In addition, all pointers are `Dereferenceable`.
  44. [table
  45. [[Expression][Result][Operational Semantics]]
  46. [[`get_pointer(x)`][convertible to `pointee<T>::type*`]
  47. [`&*x`, or a null pointer ]]
  48. ]
  49. [endsect]
  50. [endsect]
  51. [section Extractor]
  52. [section Introduction]
  53. An Extractor is a class which Boost.Python can use to extract C++ objects from Python objects, and is typically used by facilities that define `from_python` conversions for "traditional" Python extension types.
  54. [endsect]
  55. [section Concept Requirements]
  56. In the table below, `X` denotes a model of `Extractor` and `a` denotes an instance of a Python object type.
  57. [table
  58. [[Expression][Type][Semantics]]
  59. [[`X::execute(a)`][non-void]
  60. [Returns the C++ object being extracted. The execute function must not be overloaded.]]
  61. [[`&a.ob_type`][`PyTypeObject**`]
  62. [Points to the `ob_type` field of an object which is layout-compatible with `PyObject`]]
  63. ]
  64. [endsect]
  65. [section Notes]
  66. Informally, an Extractor's execute member must be a non-overloaded static function whose single argument is a Python object type. Acceptable Python object types include those publicly (and unambiguously) derived from PyObject, and POD types which are layout-compatible with PyObject.
  67. [endsect]
  68. [endsect]
  69. [section HolderGenerator]
  70. [section Introduction]
  71. A HolderGenerator is a unary metafunction class which returns types suitable for holding instances of its argument in a wrapped C++ class instance.
  72. [endsect]
  73. [section Concept Requirements]
  74. In the table below, `G` denotes an type which models `HolderGenerator`, and `X` denotes a class type.
  75. [table
  76. [[Expression][Requirements]]
  77. [[`G::apply<X>::type`][A concrete subclass of `instance_holder` which can hold objects of type `X`. ]]
  78. ]
  79. [endsect]
  80. [endsect]
  81. [section ResultConverter]
  82. [section Introduction]
  83. A ResultConverter for a type `T` is a type whose instances can be used to convert C++ return values of type `T` `to_python`. A ResultConverterGenerator is an MPL unary metafunction class which, given the return type of a C++ function, returns a ResultConverter for that type. ResultConverters in Boost.Python generally inspect library's registry of converters to find a suitable converter, but converters which don't use the registry are also possible.
  84. [endsect]
  85. [section ResultConverter Concept Requirements]
  86. In the table below, `C` denotes a ResultConverter type for a type `R`, `c` denotes an object of type `C`, and `r` denotes an object of type `R`.
  87. [table
  88. [[Expression][Type][Semantics]]
  89. [[`C c`][]
  90. [Constructs a `c` object.]]
  91. [[`c.convertible()`][convertible to `bool`]
  92. [`false` iff no conversion from any `R` value to a Python object is possible.]]
  93. [[`c(r)`][convertible to `PyObject*`]
  94. [A pointer to a Python object corresponding to `r`, or `0` iff `r` could not be converted `to_python`, in which case `PyErr_Occurred` should return non-zero.]]
  95. [[`c.get_pytype()`][`PyTypeObject const *`]
  96. [A pointer to a Python Type object corresponding to result of the conversion, or `0`. Used for documentation generation. If `0` is returned the generated type in the documentation will be object.]]
  97. ]
  98. [endsect]
  99. [section ResultConverterGenerator Concept Requirements]
  100. In the table below, `G` denotes a ResultConverterGenerator type and `R` denotes a possible C++ function return type.
  101. [table
  102. [[Expression][Requirements]]
  103. [[`G::apply<R>::type`][A ResultConverter type for `R`.]]
  104. ]
  105. [endsect]
  106. [endsect]
  107. [section ObjectWrapper]
  108. [section Introduction]
  109. This page defines two concepts used to describe classes which manage a Python objects, and which are intended to support usage with a Python-like syntax.
  110. [endsect]
  111. [section ObjectWrapper Concept Requirements]
  112. Models of the ObjectWrapper concept have [link object_wrappers.boost_python_object_hpp.class_object object] as a publicly-accessible base class, and are used to supply special construction behavior and/or additional convenient functionality through (often templated) member functions. Except when the return type R is itself an [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper], a member function invocation of the form ``x.some_function(a1, a2,...an)`` always has semantics equivalent to:
  113. ``extract<R>(x.attr("some_function")(object(a1), object(a2),...object(an)))()`` (see [link concepts.objectwrapper.caveat caveat] below).
  114. [endsect]
  115. [section TypeWrapper Concept Requirements]
  116. TypeWrapper is a refinement of [link concepts.objectwrapper.objectwrapper_concept_requiremen ObjectWrapper] which is associated with a particular Python type `X`. For a given TypeWrapper `T`, a valid constructor expression ``T(a1, a2,...an)`` builds a new T object managing the result of invoking X with arguments corresponding to ``object(a1), object(a2),...object(an)``.
  117. When used as arguments to wrapped C++ functions, or as the template parameter to [link to_from_python_type_conversion.boost_python_extract_hpp.class_template_extract extract<>], only instances of the associated Python type will be considered a match.
  118. [endsect]
  119. [section Caveat]
  120. The upshot of the special member function invocation rules when the return type is a TypeWrapper is that it is possible for the returned object to manage a Python object of an inappropriate type. This is not usually a serious problem; the worst-case result is that errors will be detected at runtime a little later than they might otherwise be. For an example of how this can occur, note that the [link object_wrappers.boost_python_dict_hpp.class_dict dict] member function `items` returns an object of type [link object_wrappers.boost_python_list_hpp.class_list list]. Now suppose the user defines this `dict` subclass in Python:
  121. ``
  122. >>> class mydict(dict):
  123. ... def items(self):
  124. ... return tuple(dict.items(self)) # return a tuple
  125. ``
  126. Since an instance of `mydict` is also an instance of `dict`, when used as an argument to a wrapped C++ function, [link object_wrappers.boost_python_dict_hpp.class_dict boost::python::dict] can accept objects of Python type `mydict`. Invoking `items()` on this object can result in an instance of [link object_wrappers.boost_python_list_hpp.class_list boost::python::list] which actually holds a Python `tuple`. Subsequent attempts to use `list` methods (e.g. `append`, or any other mutating operation) on this object will raise the same exception that would occur if you tried to do it from Python.
  127. [endsect]
  128. [endsect]