mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
Automate generation of reference docs with doxygen and breathe (#598)
* Make 'any' the default markup role for Sphinx docs * Automate generation of reference docs with doxygen and breathe * Improve reference docs coverage
This commit is contained in:
parent
cc88aaecc8
commit
57a9bbc6c7
2
.readthedocs.yml
Normal file
2
.readthedocs.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
conda:
|
||||||
|
file: docs/environment.yml
|
@ -51,7 +51,10 @@ matrix:
|
|||||||
env: DOCS STYLE LINT
|
env: DOCS STYLE LINT
|
||||||
install:
|
install:
|
||||||
- pip install --upgrade sphinx sphinx_rtd_theme flake8 pep8-naming
|
- pip install --upgrade sphinx sphinx_rtd_theme flake8 pep8-naming
|
||||||
- pip install docutils==0.12
|
- |
|
||||||
|
curl -fsSL ftp://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.12.linux.bin.tar.gz | tar xz
|
||||||
|
export PATH="$PWD/doxygen-1.8.12/bin:$PATH"
|
||||||
|
pip install https://github.com/michaeljones/breathe/archive/master.zip
|
||||||
script:
|
script:
|
||||||
- make -C docs html SPHINX_OPTIONS=-W
|
- make -C docs html SPHINX_OPTIONS=-W
|
||||||
- tools/check-style.sh
|
- tools/check-style.sh
|
||||||
|
19
docs/Doxyfile
Normal file
19
docs/Doxyfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
PROJECT_NAME = pybind11
|
||||||
|
INPUT = ../include/pybind11/
|
||||||
|
|
||||||
|
GENERATE_HTML = NO
|
||||||
|
GENERATE_LATEX = NO
|
||||||
|
GENERATE_XML = YES
|
||||||
|
XML_OUTPUT = .build/doxygenxml
|
||||||
|
XML_PROGRAMLISTING = YES
|
||||||
|
|
||||||
|
MACRO_EXPANSION = YES
|
||||||
|
EXPAND_ONLY_PREDEF = YES
|
||||||
|
EXPAND_AS_DEFINED = PYBIND11_RUNTIME_EXCEPTION
|
||||||
|
|
||||||
|
ALIASES = "rst=\verbatim embed:rst"
|
||||||
|
ALIASES += "endrst=\endverbatim"
|
||||||
|
|
||||||
|
QUIET = YES
|
||||||
|
WARNINGS = YES
|
||||||
|
WARN_IF_UNDOCUMENTED = NO
|
@ -4,8 +4,8 @@ Chrono
|
|||||||
When including the additional header file :file:`pybind11/chrono.h` conversions
|
When including the additional header file :file:`pybind11/chrono.h` conversions
|
||||||
from C++11 chrono datatypes to python datetime objects are automatically enabled.
|
from C++11 chrono datatypes to python datetime objects are automatically enabled.
|
||||||
This header also enables conversions of python floats (often from sources such
|
This header also enables conversions of python floats (often from sources such
|
||||||
as `time.monotonic()`, `time.perf_counter()` and `time.process_time()`) into
|
as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
|
||||||
durations.
|
into durations.
|
||||||
|
|
||||||
An overview of clocks in C++11
|
An overview of clocks in C++11
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -14,7 +14,7 @@ lifetime of objects managed by them. This can lead to issues when creating
|
|||||||
bindings for functions that return a non-trivial type. Just by looking at the
|
bindings for functions that return a non-trivial type. Just by looking at the
|
||||||
type information, it is not clear whether Python should take charge of the
|
type information, it is not clear whether Python should take charge of the
|
||||||
returned value and eventually free its resources, or if this is handled on the
|
returned value and eventually free its resources, or if this is handled on the
|
||||||
C++ side. For this reason, pybind11 provides a several `return value policy`
|
C++ side. For this reason, pybind11 provides a several *return value policy*
|
||||||
annotations that can be passed to the :func:`module::def` and
|
annotations that can be passed to the :func:`module::def` and
|
||||||
:func:`class_::def` functions. The default policy is
|
:func:`class_::def` functions. The default policy is
|
||||||
:enum:`return_value_policy::automatic`.
|
:enum:`return_value_policy::automatic`.
|
||||||
@ -24,11 +24,11 @@ Just to illustrate what can go wrong, consider the following simple example:
|
|||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
/* Function declaration */
|
/* Function declaration */
|
||||||
Data *get_data() { return _data; /* (pointer to a static data structure) */ }
|
Data *get_data() { return _data; /* (pointer to a static data structure) */ }
|
||||||
...
|
...
|
||||||
|
|
||||||
/* Binding code */
|
/* Binding code */
|
||||||
m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python
|
m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python
|
||||||
|
|
||||||
What's going on here? When ``get_data()`` is called from Python, the return
|
What's going on here? When ``get_data()`` is called from Python, the return
|
||||||
@ -44,7 +44,7 @@ silent data corruption.
|
|||||||
|
|
||||||
In the above example, the policy :enum:`return_value_policy::reference` should have
|
In the above example, the policy :enum:`return_value_policy::reference` should have
|
||||||
been specified so that the global data instance is only *referenced* without any
|
been specified so that the global data instance is only *referenced* without any
|
||||||
implied transfer of ownership, i.e.:
|
implied transfer of ownership, i.e.:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
@ -158,9 +158,9 @@ targeted arguments can be passed through the :class:`cpp_function` constructor:
|
|||||||
Additional call policies
|
Additional call policies
|
||||||
========================
|
========================
|
||||||
|
|
||||||
In addition to the above return value policies, further `call policies` can be
|
In addition to the above return value policies, further *call policies* can be
|
||||||
specified to indicate dependencies between parameters. In general, call policies
|
specified to indicate dependencies between parameters. In general, call policies
|
||||||
are required when the C++ object is any kind of container and another object is being
|
are required when the C++ object is any kind of container and another object is being
|
||||||
added to the container.
|
added to the container.
|
||||||
|
|
||||||
There is currently just
|
There is currently just
|
||||||
|
@ -33,6 +33,8 @@ The reverse direction uses the following syntax:
|
|||||||
|
|
||||||
When conversion fails, both directions throw the exception :class:`cast_error`.
|
When conversion fails, both directions throw the exception :class:`cast_error`.
|
||||||
|
|
||||||
|
.. _calling_python_functions:
|
||||||
|
|
||||||
Calling Python functions
|
Calling Python functions
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ The binding code for ``Pet`` looks as follows:
|
|||||||
return m.ptr();
|
return m.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
:class:`class_` creates bindings for a C++ `class` or `struct`-style data
|
:class:`class_` creates bindings for a C++ *class* or *struct*-style data
|
||||||
structure. :func:`init` is a convenience function that takes the types of a
|
structure. :func:`init` is a convenience function that takes the types of a
|
||||||
constructor's parameters as template arguments and wraps the corresponding
|
constructor's parameters as template arguments and wraps the corresponding
|
||||||
constructor (see the :ref:`custom_constructors` section for details). An
|
constructor (see the :ref:`custom_constructors` section for details). An
|
||||||
|
28
docs/conf.py
28
docs/conf.py
@ -16,6 +16,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
@ -30,7 +31,11 @@ import shlex
|
|||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
# ones.
|
# ones.
|
||||||
extensions = []
|
extensions = ['breathe']
|
||||||
|
|
||||||
|
breathe_projects = {'pybind11': '.build/doxygenxml/'}
|
||||||
|
breathe_default_project = 'pybind11'
|
||||||
|
breathe_domain_by_extension = {'h': 'cpp'}
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['.templates']
|
templates_path = ['.templates']
|
||||||
@ -79,7 +84,7 @@ exclude_patterns = ['.build', 'release.rst']
|
|||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
# documents.
|
# documents.
|
||||||
#default_role = None
|
default_role = 'any'
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||||
#add_function_parentheses = True
|
#add_function_parentheses = True
|
||||||
@ -306,3 +311,22 @@ texinfo_documents = [
|
|||||||
|
|
||||||
primary_domain = 'cpp'
|
primary_domain = 'cpp'
|
||||||
highlight_language = 'cpp'
|
highlight_language = 'cpp'
|
||||||
|
|
||||||
|
|
||||||
|
def generate_doxygen_xml(app):
|
||||||
|
build_dir = '.build'
|
||||||
|
if not os.path.exists(build_dir):
|
||||||
|
os.mkdir(build_dir)
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.call(['doxygen', '--version'])
|
||||||
|
retcode = subprocess.call(['doxygen'])
|
||||||
|
if retcode < 0:
|
||||||
|
sys.stderr.write("doxygen error code: {}\n".format(-retcode))
|
||||||
|
except OSError as e:
|
||||||
|
sys.stderr.write("doxygen execution failed: {}\n".format(e))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
"""Add hook for building doxygen xml when needed"""
|
||||||
|
app.connect("builder-inited", generate_doxygen_xml)
|
||||||
|
9
docs/environment.yml
Normal file
9
docs/environment.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name: rtd
|
||||||
|
channels:
|
||||||
|
- dean0x7d
|
||||||
|
- defaults
|
||||||
|
dependencies:
|
||||||
|
- doxygen
|
||||||
|
- pip
|
||||||
|
- pip:
|
||||||
|
- https://github.com/michaeljones/breathe/archive/master.zip
|
@ -12,236 +12,69 @@ Reference
|
|||||||
Macros
|
Macros
|
||||||
======
|
======
|
||||||
|
|
||||||
.. function:: PYBIND11_PLUGIN(const char *name)
|
.. doxygendefine:: PYBIND11_PLUGIN
|
||||||
|
|
||||||
This macro creates the entry point that will be invoked when the Python
|
|
||||||
interpreter imports a plugin library. Please create a
|
|
||||||
:class:`module` in the function body and return the pointer to its
|
|
||||||
underlying Python object at the end.
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
PYBIND11_PLUGIN(example) {
|
|
||||||
pybind11::module m("example", "pybind11 example plugin");
|
|
||||||
/// Set up bindings here
|
|
||||||
return m.ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
.. _core_types:
|
.. _core_types:
|
||||||
|
|
||||||
Convenience classes for arbitrary Python types
|
Convenience classes for arbitrary Python types
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
|
Common member functions
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
.. doxygenclass:: object_api
|
||||||
|
:members:
|
||||||
|
|
||||||
Without reference counting
|
Without reference counting
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
.. class:: handle
|
.. doxygenclass:: handle
|
||||||
|
:members:
|
||||||
The :class:`handle` class is a thin wrapper around an arbitrary Python
|
|
||||||
object (i.e. a ``PyObject *`` in Python's C API). It does not perform any
|
|
||||||
automatic reference counting and merely provides a basic C++ interface to
|
|
||||||
various Python API functions.
|
|
||||||
|
|
||||||
.. seealso::
|
|
||||||
|
|
||||||
The :class:`object` class inherits from :class:`handle` and adds automatic
|
|
||||||
reference counting features.
|
|
||||||
|
|
||||||
.. function:: handle::handle()
|
|
||||||
|
|
||||||
The default constructor creates a handle with a ``nullptr``-valued pointer.
|
|
||||||
|
|
||||||
.. function:: handle::handle(const handle&)
|
|
||||||
|
|
||||||
Copy constructor
|
|
||||||
|
|
||||||
.. function:: handle::handle(PyObject *)
|
|
||||||
|
|
||||||
Creates a :class:`handle` from the given raw Python object pointer.
|
|
||||||
|
|
||||||
.. function:: PyObject * handle::ptr() const
|
|
||||||
|
|
||||||
Return the ``PyObject *`` underlying a :class:`handle`.
|
|
||||||
|
|
||||||
.. function:: const handle& handle::inc_ref() const
|
|
||||||
|
|
||||||
Manually increase the reference count of the Python object. Usually, it is
|
|
||||||
preferable to use the :class:`object` class which derives from
|
|
||||||
:class:`handle` and calls this function automatically. Returns a reference
|
|
||||||
to itself.
|
|
||||||
|
|
||||||
.. function:: const handle& handle::dec_ref() const
|
|
||||||
|
|
||||||
Manually decrease the reference count of the Python object. Usually, it is
|
|
||||||
preferable to use the :class:`object` class which derives from
|
|
||||||
:class:`handle` and calls this function automatically. Returns a reference
|
|
||||||
to itself.
|
|
||||||
|
|
||||||
.. function:: void handle::ref_count() const
|
|
||||||
|
|
||||||
Return the object's current reference count
|
|
||||||
|
|
||||||
.. function:: handle handle::get_type() const
|
|
||||||
|
|
||||||
Return a handle to the Python type object underlying the instance
|
|
||||||
|
|
||||||
.. function detail::accessor handle::operator[](handle key) const
|
|
||||||
|
|
||||||
Return an internal functor to invoke the object's sequence protocol.
|
|
||||||
Casting the returned ``detail::accessor`` instance to a :class:`handle` or
|
|
||||||
:class:`object` subclass causes a corresponding call to ``__getitem__``.
|
|
||||||
Assigning a :class:`handle` or :class:`object` subclass causes a call to
|
|
||||||
``__setitem__``.
|
|
||||||
|
|
||||||
.. function detail::accessor handle::operator[](const char *key) const
|
|
||||||
|
|
||||||
See the above function (the only difference is that they key is provided as
|
|
||||||
a string literal).
|
|
||||||
|
|
||||||
.. function detail::accessor handle::attr(handle key) const
|
|
||||||
|
|
||||||
Return an internal functor to access the object's attributes.
|
|
||||||
Casting the returned ``detail::accessor`` instance to a :class:`handle` or
|
|
||||||
:class:`object` subclass causes a corresponding call to ``__getattr``.
|
|
||||||
Assigning a :class:`handle` or :class:`object` subclass causes a call to
|
|
||||||
``__setattr``.
|
|
||||||
|
|
||||||
.. function detail::accessor handle::attr(const char *key) const
|
|
||||||
|
|
||||||
See the above function (the only difference is that they key is provided as
|
|
||||||
a string literal).
|
|
||||||
|
|
||||||
.. function operator handle::bool() const
|
|
||||||
|
|
||||||
Return ``true`` when the :class:`handle` wraps a valid Python object.
|
|
||||||
|
|
||||||
.. function str handle::str() const
|
|
||||||
|
|
||||||
Return a string representation of the object. This is analogous to
|
|
||||||
the ``str()`` function in Python.
|
|
||||||
|
|
||||||
.. function:: template <typename T> T handle::cast() const
|
|
||||||
|
|
||||||
Attempt to cast the Python object into the given C++ type. A
|
|
||||||
:class:`cast_error` will be throw upon failure.
|
|
||||||
|
|
||||||
.. function:: template <typename ... Args> object handle::call(Args&&... args) const
|
|
||||||
|
|
||||||
Assuming the Python object is a function or implements the ``__call__``
|
|
||||||
protocol, ``call()`` invokes the underlying function, passing an arbitrary
|
|
||||||
set of parameters. The result is returned as a :class:`object` and may need
|
|
||||||
to be converted back into a Python object using :func:`handle::cast`.
|
|
||||||
|
|
||||||
When some of the arguments cannot be converted to Python objects, the
|
|
||||||
function will throw a :class:`cast_error` exception. When the Python
|
|
||||||
function call fails, a :class:`error_already_set` exception is thrown.
|
|
||||||
|
|
||||||
With reference counting
|
With reference counting
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
.. class:: object : public handle
|
.. doxygenclass:: object
|
||||||
|
:members:
|
||||||
|
|
||||||
Like :class:`handle`, the object class is a thin wrapper around an
|
.. doxygenfunction:: reinterpret_borrow
|
||||||
arbitrary Python object (i.e. a ``PyObject *`` in Python's C API). In
|
|
||||||
contrast to :class:`handle`, it optionally increases the object's reference
|
|
||||||
count upon construction, and it *always* decreases the reference count when
|
|
||||||
the :class:`object` instance goes out of scope and is destructed. When
|
|
||||||
using :class:`object` instances consistently, it is much easier to get
|
|
||||||
reference counting right at the first attempt.
|
|
||||||
|
|
||||||
.. function:: object::object(const object &o)
|
.. doxygenfunction:: reinterpret_steal
|
||||||
|
|
||||||
Copy constructor; always increases the reference count
|
|
||||||
|
|
||||||
.. function:: object::object(const handle &h, bool borrowed)
|
|
||||||
|
|
||||||
Creates a :class:`object` from the given :class:`handle`. The reference
|
|
||||||
count is only increased if the ``borrowed`` parameter is set to ``true``.
|
|
||||||
|
|
||||||
.. function:: object::object(PyObject *ptr, bool borrowed)
|
|
||||||
|
|
||||||
Creates a :class:`object` from the given raw Python object pointer. The
|
|
||||||
reference count is only increased if the ``borrowed`` parameter is set to
|
|
||||||
``true``.
|
|
||||||
|
|
||||||
.. function:: object::object(object &&other)
|
|
||||||
|
|
||||||
Move constructor; steals the object from ``other`` and preserves its
|
|
||||||
reference count.
|
|
||||||
|
|
||||||
.. function:: handle object::release()
|
|
||||||
|
|
||||||
Resets the internal pointer to ``nullptr`` without without decreasing the
|
|
||||||
object's reference count. The function returns a raw handle to the original
|
|
||||||
Python object.
|
|
||||||
|
|
||||||
.. function:: object::~object()
|
|
||||||
|
|
||||||
Destructor, which automatically calls :func:`handle::dec_ref()`.
|
|
||||||
|
|
||||||
Convenience classes for specific Python types
|
Convenience classes for specific Python types
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
|
.. doxygenclass:: module
|
||||||
|
:members:
|
||||||
|
|
||||||
.. class:: module : public object
|
.. doxygengroup:: pytypes
|
||||||
|
:members:
|
||||||
.. function:: module::module(const char *name, const char *doc = nullptr)
|
|
||||||
|
|
||||||
Create a new top-level Python module with the given name and docstring
|
|
||||||
|
|
||||||
.. function:: module module::def_submodule(const char *name, const char *doc = nullptr)
|
|
||||||
|
|
||||||
Create and return a new Python submodule with the given name and docstring.
|
|
||||||
This also works recursively, i.e.
|
|
||||||
|
|
||||||
.. code-block:: cpp
|
|
||||||
|
|
||||||
pybind11::module m("example", "pybind11 example plugin");
|
|
||||||
pybind11::module m2 = m.def_submodule("sub", "A submodule of 'example'");
|
|
||||||
pybind11::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
|
|
||||||
|
|
||||||
.. cpp:function:: template <typename Func, typename ... Extra> module& module::def(const char *name, Func && f, Extra && ... extra)
|
|
||||||
|
|
||||||
Create Python binding for a new function within the module scope. ``Func``
|
|
||||||
can be a plain C++ function, a function pointer, or a lambda function. For
|
|
||||||
details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.
|
|
||||||
|
|
||||||
.. _extras:
|
.. _extras:
|
||||||
|
|
||||||
Passing extra arguments to the def function
|
Passing extra arguments to ``def`` or ``class_``
|
||||||
===========================================
|
================================================
|
||||||
|
|
||||||
.. class:: arg
|
.. doxygengroup:: annotations
|
||||||
|
:members:
|
||||||
|
|
||||||
.. function:: arg::arg(const char *name)
|
Python build-in functions
|
||||||
|
=========================
|
||||||
|
|
||||||
.. function:: template <typename T> arg_v arg::operator=(T &&value)
|
.. doxygengroup:: python_builtins
|
||||||
|
:members:
|
||||||
|
|
||||||
.. class:: arg_v : public arg
|
Exceptions
|
||||||
|
==========
|
||||||
|
|
||||||
Represents a named argument with a default value
|
.. doxygenclass:: error_already_set
|
||||||
|
:members:
|
||||||
|
|
||||||
.. class:: sibling
|
.. doxygenclass:: builtin_exception
|
||||||
|
:members:
|
||||||
|
|
||||||
Used to specify a handle to an existing sibling function; used internally
|
|
||||||
to implement function overloading in :func:`module::def` and
|
|
||||||
:func:`class_::def`.
|
|
||||||
|
|
||||||
.. function:: sibling::sibling(handle handle)
|
Literals
|
||||||
|
========
|
||||||
.. class doc
|
|
||||||
|
|
||||||
This is class is internally used by pybind11.
|
|
||||||
|
|
||||||
.. function:: doc::doc(const char *value)
|
|
||||||
|
|
||||||
Create a new docstring with the specified value
|
|
||||||
|
|
||||||
.. class name
|
|
||||||
|
|
||||||
This is class is internally used by pybind11.
|
|
||||||
|
|
||||||
.. function:: name::name(const char *value)
|
|
||||||
|
|
||||||
Used to specify the function name
|
|
||||||
|
|
||||||
|
.. doxygennamespace:: literals
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
|
|
||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
|
|
||||||
|
/// \addtogroup annotations
|
||||||
|
/// @{
|
||||||
|
|
||||||
/// Annotation for methods
|
/// Annotation for methods
|
||||||
struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
|
struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
|
||||||
|
|
||||||
@ -56,6 +59,8 @@ struct metaclass { };
|
|||||||
/// Annotation to mark enums as an arithmetic type
|
/// Annotation to mark enums as an arithmetic type
|
||||||
struct arithmetic { };
|
struct arithmetic { };
|
||||||
|
|
||||||
|
/// @} annotations
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
/* Forward declarations */
|
/* Forward declarations */
|
||||||
enum op_id : int;
|
enum op_id : int;
|
||||||
|
@ -1177,14 +1177,18 @@ template <return_value_policy policy = return_value_policy::automatic_reference,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \ingroup annotations
|
||||||
/// Annotation for keyword arguments
|
/// Annotation for keyword arguments
|
||||||
struct arg {
|
struct arg {
|
||||||
|
/// Set the name of the argument
|
||||||
constexpr explicit arg(const char *name) : name(name) { }
|
constexpr explicit arg(const char *name) : name(name) { }
|
||||||
|
/// Assign a value to this argument
|
||||||
template <typename T> arg_v operator=(T &&value) const;
|
template <typename T> arg_v operator=(T &&value) const;
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \ingroup annotations
|
||||||
/// Annotation for keyword arguments with values
|
/// Annotation for keyword arguments with values
|
||||||
struct arg_v : arg {
|
struct arg_v : arg {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1213,7 +1217,9 @@ arg_v arg::operator=(T &&value) const { return {name, std::forward<T>(value)}; }
|
|||||||
template <typename /*unused*/> using arg_t = arg_v;
|
template <typename /*unused*/> using arg_t = arg_v;
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
/// String literal version of arg
|
/** \rst
|
||||||
|
String literal version of `arg`
|
||||||
|
\endrst */
|
||||||
constexpr arg operator"" _a(const char *name, size_t) { return arg(name); }
|
constexpr arg operator"" _a(const char *name, size_t) { return arg(name); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,6 +159,19 @@ extern "C" {
|
|||||||
#define PYBIND11_INTERNALS_ID "__pybind11_" \
|
#define PYBIND11_INTERNALS_ID "__pybind11_" \
|
||||||
PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
|
PYBIND11_TOSTRING(PYBIND11_VERSION_MAJOR) "_" PYBIND11_TOSTRING(PYBIND11_VERSION_MINOR) "__"
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
This macro creates the entry point that will be invoked when the Python interpreter
|
||||||
|
imports a plugin library. Please create a `module` in the function body and return
|
||||||
|
the pointer to its underlying Python object at the end.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
PYBIND11_PLUGIN(example) {
|
||||||
|
pybind11::module m("example", "pybind11 example plugin");
|
||||||
|
/// Set up bindings here
|
||||||
|
return m.ptr();
|
||||||
|
}
|
||||||
|
\endrst */
|
||||||
#define PYBIND11_PLUGIN(name) \
|
#define PYBIND11_PLUGIN(name) \
|
||||||
static PyObject *pybind11_init(); \
|
static PyObject *pybind11_init(); \
|
||||||
PYBIND11_PLUGIN_IMPL(name) { \
|
PYBIND11_PLUGIN_IMPL(name) { \
|
||||||
@ -388,7 +401,7 @@ template <bool B> using bool_constant = std::integral_constant<bool, B>;
|
|||||||
template <class T> using negation = bool_constant<!T::value>;
|
template <class T> using negation = bool_constant<!T::value>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Compile-time all/any/none of that check the ::value of all template types
|
/// Compile-time all/any/none of that check the boolean value of all template types
|
||||||
#ifdef PYBIND11_CPP17
|
#ifdef PYBIND11_CPP17
|
||||||
template <class... Ts> using all_of = bool_constant<(Ts::value && ...)>;
|
template <class... Ts> using all_of = bool_constant<(Ts::value && ...)>;
|
||||||
template <class... Ts> using any_of = bool_constant<(Ts::value || ...)>;
|
template <class... Ts> using any_of = bool_constant<(Ts::value || ...)>;
|
||||||
@ -532,7 +545,8 @@ private:
|
|||||||
class builtin_exception : public std::runtime_error {
|
class builtin_exception : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
using std::runtime_error::runtime_error;
|
using std::runtime_error::runtime_error;
|
||||||
virtual void set_error() const = 0; /// Set the error using the Python C API
|
/// Set the error using the Python C API
|
||||||
|
virtual void set_error() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PYBIND11_RUNTIME_EXCEPTION(name, type) \
|
#define PYBIND11_RUNTIME_EXCEPTION(name, type) \
|
||||||
|
@ -544,6 +544,7 @@ class module : public object {
|
|||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check)
|
PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check)
|
||||||
|
|
||||||
|
/// Create a new top-level Python module with the given name and docstring
|
||||||
explicit module(const char *name, const char *doc = nullptr) {
|
explicit module(const char *name, const char *doc = nullptr) {
|
||||||
if (!options::show_user_defined_docstrings()) doc = nullptr;
|
if (!options::show_user_defined_docstrings()) doc = nullptr;
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
@ -562,6 +563,11 @@ public:
|
|||||||
inc_ref();
|
inc_ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Create Python binding for a new function within the module scope. ``Func``
|
||||||
|
can be a plain C++ function, a function pointer, or a lambda function. For
|
||||||
|
details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.
|
||||||
|
\endrst */
|
||||||
template <typename Func, typename... Extra>
|
template <typename Func, typename... Extra>
|
||||||
module &def(const char *name_, Func &&f, const Extra& ... extra) {
|
module &def(const char *name_, Func &&f, const Extra& ... extra) {
|
||||||
cpp_function func(std::forward<Func>(f), name(name_), scope(*this),
|
cpp_function func(std::forward<Func>(f), name(name_), scope(*this),
|
||||||
@ -572,6 +578,16 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Create and return a new Python submodule with the given name and docstring.
|
||||||
|
This also works recursively, i.e.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
py::module m("example", "pybind11 example plugin");
|
||||||
|
py::module m2 = m.def_submodule("sub", "A submodule of 'example'");
|
||||||
|
py::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
|
||||||
|
\endrst */
|
||||||
module def_submodule(const char *name, const char *doc = nullptr) {
|
module def_submodule(const char *name, const char *doc = nullptr) {
|
||||||
std::string full_name = std::string(PyModule_GetName(m_ptr))
|
std::string full_name = std::string(PyModule_GetName(m_ptr))
|
||||||
+ std::string(".") + std::string(name);
|
+ std::string(".") + std::string(name);
|
||||||
@ -582,6 +598,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Import and return a module or throws `error_already_set`.
|
||||||
static module import(const char *name) {
|
static module import(const char *name) {
|
||||||
PyObject *obj = PyImport_ImportModule(name);
|
PyObject *obj = PyImport_ImportModule(name);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
|
@ -45,51 +45,130 @@ using tuple_accessor = accessor<accessor_policies::tuple_item>;
|
|||||||
class pyobject_tag { };
|
class pyobject_tag { };
|
||||||
template <typename T> using is_pyobject = std::is_base_of<pyobject_tag, typename std::remove_reference<T>::type>;
|
template <typename T> using is_pyobject = std::is_base_of<pyobject_tag, typename std::remove_reference<T>::type>;
|
||||||
|
|
||||||
/// Mixin which adds common functions to handle, object and various accessors.
|
/** \rst
|
||||||
/// The only requirement for `Derived` is to implement `PyObject *Derived::ptr() const`.
|
A mixin class which adds common functions to `handle`, `object` and various accessors.
|
||||||
|
The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``.
|
||||||
|
\endrst */
|
||||||
template <typename Derived>
|
template <typename Derived>
|
||||||
class object_api : public pyobject_tag {
|
class object_api : public pyobject_tag {
|
||||||
const Derived &derived() const { return static_cast<const Derived &>(*this); }
|
const Derived &derived() const { return static_cast<const Derived &>(*this); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** \rst
|
||||||
|
Return an iterator equivalent to calling ``iter()`` in Python. The object
|
||||||
|
must be a collection which supports the iteration protocol.
|
||||||
|
\endrst */
|
||||||
iterator begin() const;
|
iterator begin() const;
|
||||||
|
/// Return a sentinel which ends iteration.
|
||||||
iterator end() const;
|
iterator end() const;
|
||||||
item_accessor operator[](handle key) const;
|
|
||||||
item_accessor operator[](const char *key) const;
|
|
||||||
obj_attr_accessor attr(handle key) const;
|
|
||||||
str_attr_accessor attr(const char *key) const;
|
|
||||||
args_proxy operator*() const;
|
|
||||||
template <typename T> bool contains(T &&key) const;
|
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Return an internal functor to invoke the object's sequence protocol. Casting
|
||||||
|
the returned ``detail::item_accessor`` instance to a `handle` or `object`
|
||||||
|
subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`
|
||||||
|
or `object` subclass causes a call to ``__setitem__``.
|
||||||
|
\endrst */
|
||||||
|
item_accessor operator[](handle key) const;
|
||||||
|
/// See above (the only difference is that they key is provided as a string literal)
|
||||||
|
item_accessor operator[](const char *key) const;
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Return an internal functor to access the object's attributes. Casting the
|
||||||
|
returned ``detail::obj_attr_accessor`` instance to a `handle` or `object`
|
||||||
|
subclass causes a corresponding call to ``getattr``. Assigning a `handle`
|
||||||
|
or `object` subclass causes a call to ``setattr``.
|
||||||
|
\endrst */
|
||||||
|
obj_attr_accessor attr(handle key) const;
|
||||||
|
/// See above (the only difference is that they key is provided as a string literal)
|
||||||
|
str_attr_accessor attr(const char *key) const;
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple``
|
||||||
|
or ``list`` for a function call. Applying another * to the result yields
|
||||||
|
** unpacking, e.g. to unpack a dict as function keyword arguments.
|
||||||
|
See :ref:`calling_python_functions`.
|
||||||
|
\endrst */
|
||||||
|
args_proxy operator*() const;
|
||||||
|
|
||||||
|
/// Check if the given item is contained within this object, i.e. ``item in obj``.
|
||||||
|
template <typename T> bool contains(T &&item) const;
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Assuming the Python object is a function or implements the ``__call__``
|
||||||
|
protocol, ``operator()`` invokes the underlying function, passing an
|
||||||
|
arbitrary set of parameters. The result is returned as a `object` and
|
||||||
|
may need to be converted back into a Python object using `handle::cast()`.
|
||||||
|
|
||||||
|
When some of the arguments cannot be converted to Python objects, the
|
||||||
|
function will throw a `cast_error` exception. When the Python function
|
||||||
|
call fails, a `error_already_set` exception is thrown.
|
||||||
|
\endrst */
|
||||||
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
|
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
|
||||||
object operator()(Args &&...args) const;
|
object operator()(Args &&...args) const;
|
||||||
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
|
template <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>
|
||||||
PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)")
|
PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)")
|
||||||
object call(Args&&... args) const;
|
object call(Args&&... args) const;
|
||||||
|
|
||||||
|
/// Equivalent to ``obj is None`` in Python.
|
||||||
bool is_none() const { return derived().ptr() == Py_None; }
|
bool is_none() const { return derived().ptr() == Py_None; }
|
||||||
PYBIND11_DEPRECATED("Instead of obj.str(), use py::str(obj)")
|
PYBIND11_DEPRECATED("Use py::str(obj) instead")
|
||||||
pybind11::str str() const;
|
pybind11::str str() const;
|
||||||
|
|
||||||
|
/// Return the object's current reference count
|
||||||
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
|
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
|
||||||
|
/// Return a handle to the Python type object underlying the instance
|
||||||
handle get_type() const;
|
handle get_type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NAMESPACE_END(detail)
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
/// Holds a reference to a Python object (no reference counting)
|
/** \rst
|
||||||
|
Holds a reference to a Python object (no reference counting)
|
||||||
|
|
||||||
|
The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a
|
||||||
|
``PyObject *`` in Python's C API). It does not perform any automatic reference
|
||||||
|
counting and merely provides a basic C++ interface to various Python API functions.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
The `object` class inherits from `handle` and adds automatic reference
|
||||||
|
counting features.
|
||||||
|
\endrst */
|
||||||
class handle : public detail::object_api<handle> {
|
class handle : public detail::object_api<handle> {
|
||||||
public:
|
public:
|
||||||
|
/// The default constructor creates a handle with a ``nullptr``-valued pointer
|
||||||
handle() = default;
|
handle() = default;
|
||||||
|
/// Creates a ``handle`` from the given raw Python object pointer
|
||||||
handle(PyObject *ptr) : m_ptr(ptr) { } // Allow implicit conversion from PyObject*
|
handle(PyObject *ptr) : m_ptr(ptr) { } // Allow implicit conversion from PyObject*
|
||||||
|
|
||||||
|
/// Return the underlying ``PyObject *`` pointer
|
||||||
PyObject *ptr() const { return m_ptr; }
|
PyObject *ptr() const { return m_ptr; }
|
||||||
PyObject *&ptr() { return m_ptr; }
|
PyObject *&ptr() { return m_ptr; }
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Manually increase the reference count of the Python object. Usually, it is
|
||||||
|
preferable to use the `object` class which derives from `handle` and calls
|
||||||
|
this function automatically. Returns a reference to itself.
|
||||||
|
\endrst */
|
||||||
const handle& inc_ref() const { Py_XINCREF(m_ptr); return *this; }
|
const handle& inc_ref() const { Py_XINCREF(m_ptr); return *this; }
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Manually decrease the reference count of the Python object. Usually, it is
|
||||||
|
preferable to use the `object` class which derives from `handle` and calls
|
||||||
|
this function automatically. Returns a reference to itself.
|
||||||
|
\endrst */
|
||||||
const handle& dec_ref() const { Py_XDECREF(m_ptr); return *this; }
|
const handle& dec_ref() const { Py_XDECREF(m_ptr); return *this; }
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Attempt to cast the Python object into the given C++ type. A `cast_error`
|
||||||
|
will be throw upon failure.
|
||||||
|
\endrst */
|
||||||
template <typename T> T cast() const;
|
template <typename T> T cast() const;
|
||||||
|
/// Return ``true`` when the `handle` wraps a valid Python object
|
||||||
explicit operator bool() const { return m_ptr != nullptr; }
|
explicit operator bool() const { return m_ptr != nullptr; }
|
||||||
|
/** \rst
|
||||||
|
Check that the underlying pointers are the same.
|
||||||
|
Equivalent to ``obj1 is obj2`` in Python.
|
||||||
|
\endrst */
|
||||||
bool operator==(const handle &h) const { return m_ptr == h.m_ptr; }
|
bool operator==(const handle &h) const { return m_ptr == h.m_ptr; }
|
||||||
bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; }
|
bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; }
|
||||||
PYBIND11_DEPRECATED("Use handle::operator bool() instead")
|
PYBIND11_DEPRECATED("Use handle::operator bool() instead")
|
||||||
@ -98,16 +177,33 @@ protected:
|
|||||||
PyObject *m_ptr = nullptr;
|
PyObject *m_ptr = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Holds a reference to a Python object (with reference counting)
|
/** \rst
|
||||||
|
Holds a reference to a Python object (with reference counting)
|
||||||
|
|
||||||
|
Like `handle`, the `object` class is a thin wrapper around an arbitrary Python
|
||||||
|
object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it
|
||||||
|
optionally increases the object's reference count upon construction, and it
|
||||||
|
*always* decreases the reference count when the `object` instance goes out of
|
||||||
|
scope and is destructed. When using `object` instances consistently, it is much
|
||||||
|
easier to get reference counting right at the first attempt.
|
||||||
|
\endrst */
|
||||||
class object : public handle {
|
class object : public handle {
|
||||||
public:
|
public:
|
||||||
object() = default;
|
object() = default;
|
||||||
PYBIND11_DEPRECATED("Use reinterpret_borrow<object>() or reinterpret_steal<object>()")
|
PYBIND11_DEPRECATED("Use reinterpret_borrow<object>() or reinterpret_steal<object>()")
|
||||||
object(handle h, bool is_borrowed) : handle(h) { if (is_borrowed) inc_ref(); }
|
object(handle h, bool is_borrowed) : handle(h) { if (is_borrowed) inc_ref(); }
|
||||||
|
/// Copy constructor; always increases the reference count
|
||||||
object(const object &o) : handle(o) { inc_ref(); }
|
object(const object &o) : handle(o) { inc_ref(); }
|
||||||
|
/// Move constructor; steals the object from ``other`` and preserves its reference count
|
||||||
object(object &&other) noexcept { m_ptr = other.m_ptr; other.m_ptr = nullptr; }
|
object(object &&other) noexcept { m_ptr = other.m_ptr; other.m_ptr = nullptr; }
|
||||||
|
/// Destructor; automatically calls `handle::dec_ref()`
|
||||||
~object() { dec_ref(); }
|
~object() { dec_ref(); }
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Resets the internal pointer to ``nullptr`` without without decreasing the
|
||||||
|
object's reference count. The function returns a raw handle to the original
|
||||||
|
Python object.
|
||||||
|
\endrst */
|
||||||
handle release() {
|
handle release() {
|
||||||
PyObject *tmp = m_ptr;
|
PyObject *tmp = m_ptr;
|
||||||
m_ptr = nullptr;
|
m_ptr = nullptr;
|
||||||
@ -150,12 +246,41 @@ public:
|
|||||||
object(handle h, stolen_t) : handle(h) { }
|
object(handle h, stolen_t) : handle(h) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The following functions don't do any kind of conversion, they simply declare
|
/** \rst
|
||||||
that a PyObject is a certain type and borrow or steal the reference. */
|
Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference.
|
||||||
|
The target type ``T`` must be `object` or one of its derived classes. The function
|
||||||
|
doesn't do any conversions or checks. It's up to the user to make sure that the
|
||||||
|
target type is correct.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
PyObject *result = PySequence_GetItem(obj, index);
|
||||||
|
py::object o = reinterpret_borrow<py::object>(p);
|
||||||
|
// or
|
||||||
|
py::tuple t = reinterpret_borrow<py::tuple>(p); // <-- `p` must be already be a `tuple`
|
||||||
|
\endrst */
|
||||||
template <typename T> T reinterpret_borrow(handle h) { return {h, object::borrowed}; }
|
template <typename T> T reinterpret_borrow(handle h) { return {h, object::borrowed}; }
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Like `reinterpret_borrow`, but steals the reference.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
PyObject *p = PyObject_Str(obj);
|
||||||
|
py::str s = reinterpret_steal<py::str>(p); // <-- `p` must be already be a `str`
|
||||||
|
\endrst */
|
||||||
template <typename T> T reinterpret_steal(handle h) { return {h, object::stolen}; }
|
template <typename T> T reinterpret_steal(handle h) { return {h, object::stolen}; }
|
||||||
|
|
||||||
/// Check if `obj` is an instance of type `T`
|
/** \defgroup python_builtins _
|
||||||
|
Unless stated otherwise, the following C++ functions behave the same
|
||||||
|
as their Python counterparts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \ingroup python_builtins
|
||||||
|
\rst
|
||||||
|
Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of
|
||||||
|
`object` or a class which was exposed to Python as ``py::class_<T>``.
|
||||||
|
\endrst */
|
||||||
template <typename T, detail::enable_if_t<std::is_base_of<object, T>::value, int> = 0>
|
template <typename T, detail::enable_if_t<std::is_base_of<object, T>::value, int> = 0>
|
||||||
bool isinstance(handle obj) { return T::_check(obj); }
|
bool isinstance(handle obj) { return T::_check(obj); }
|
||||||
|
|
||||||
@ -165,6 +290,8 @@ bool isinstance(handle obj) { return detail::isinstance_generic(obj, typeid(T));
|
|||||||
template <> inline bool isinstance<handle>(handle obj) = delete;
|
template <> inline bool isinstance<handle>(handle obj) = delete;
|
||||||
template <> inline bool isinstance<object>(handle obj) { return obj.ptr() != nullptr; }
|
template <> inline bool isinstance<object>(handle obj) { return obj.ptr() != nullptr; }
|
||||||
|
|
||||||
|
/// \ingroup python_builtins
|
||||||
|
/// Return true if ``obj`` is an instance of the ``type``.
|
||||||
inline bool isinstance(handle obj, handle type) {
|
inline bool isinstance(handle obj, handle type) {
|
||||||
const auto result = PyObject_IsInstance(obj.ptr(), type.ptr());
|
const auto result = PyObject_IsInstance(obj.ptr(), type.ptr());
|
||||||
if (result == -1)
|
if (result == -1)
|
||||||
@ -172,6 +299,8 @@ inline bool isinstance(handle obj, handle type) {
|
|||||||
return result != 0;
|
return result != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \addtogroup python_builtins
|
||||||
|
/// @{
|
||||||
inline bool hasattr(handle obj, handle name) {
|
inline bool hasattr(handle obj, handle name) {
|
||||||
return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;
|
return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;
|
||||||
}
|
}
|
||||||
@ -217,6 +346,7 @@ inline void setattr(handle obj, handle name, handle value) {
|
|||||||
inline void setattr(handle obj, const char *name, handle value) {
|
inline void setattr(handle obj, const char *name, handle value) {
|
||||||
if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); }
|
if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); }
|
||||||
}
|
}
|
||||||
|
/// @} python_builtins
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
inline handle get_function(handle value) {
|
inline handle get_function(handle value) {
|
||||||
@ -459,6 +589,8 @@ NAMESPACE_END(detail)
|
|||||||
PYBIND11_OBJECT(Name, Parent, CheckFun) \
|
PYBIND11_OBJECT(Name, Parent, CheckFun) \
|
||||||
Name() : Parent() { }
|
Name() : Parent() { }
|
||||||
|
|
||||||
|
/// \addtogroup pytypes
|
||||||
|
/// @{
|
||||||
class iterator : public object {
|
class iterator : public object {
|
||||||
public:
|
public:
|
||||||
/** Caveat: copying an iterator does not (and cannot) clone the internal
|
/** Caveat: copying an iterator does not (and cannot) clone the internal
|
||||||
@ -528,6 +660,10 @@ public:
|
|||||||
|
|
||||||
explicit str(const bytes &b);
|
explicit str(const bytes &b);
|
||||||
|
|
||||||
|
/** \rst
|
||||||
|
Return a string representation of the object. This is analogous to
|
||||||
|
the ``str()`` function in Python.
|
||||||
|
\endrst */
|
||||||
explicit str(handle h) : object(raw_str(h.ptr()), stolen) { }
|
explicit str(handle h) : object(raw_str(h.ptr()), stolen) { }
|
||||||
|
|
||||||
operator std::string() const {
|
operator std::string() const {
|
||||||
@ -561,12 +697,17 @@ private:
|
|||||||
return str_value;
|
return str_value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/// @} pytypes
|
||||||
|
|
||||||
inline namespace literals {
|
inline namespace literals {
|
||||||
/// String literal version of str
|
/** \rst
|
||||||
|
String literal version of `str`
|
||||||
|
\endrst */
|
||||||
inline str operator"" _s(const char *s, size_t size) { return {s, size}; }
|
inline str operator"" _s(const char *s, size_t size) { return {s, size}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \addtogroup pytypes
|
||||||
|
/// @{
|
||||||
class bytes : public object {
|
class bytes : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK)
|
PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK)
|
||||||
@ -870,7 +1011,10 @@ public:
|
|||||||
|
|
||||||
PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject)
|
PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject)
|
||||||
};
|
};
|
||||||
|
/// @} pytypes
|
||||||
|
|
||||||
|
/// \addtogroup python_builtins
|
||||||
|
/// @{
|
||||||
inline size_t len(handle h) {
|
inline size_t len(handle h) {
|
||||||
ssize_t result = PyObject_Length(h.ptr());
|
ssize_t result = PyObject_Length(h.ptr());
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
@ -888,6 +1032,7 @@ inline str repr(handle h) {
|
|||||||
#endif
|
#endif
|
||||||
return reinterpret_steal<str>(str_value);
|
return reinterpret_steal<str>(str_value);
|
||||||
}
|
}
|
||||||
|
/// @} python_builtins
|
||||||
|
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
template <typename D> iterator object_api<D>::begin() const {
|
template <typename D> iterator object_api<D>::begin() const {
|
||||||
@ -911,8 +1056,8 @@ template <typename D> str_attr_accessor object_api<D>::attr(const char *key) con
|
|||||||
template <typename D> args_proxy object_api<D>::operator*() const {
|
template <typename D> args_proxy object_api<D>::operator*() const {
|
||||||
return args_proxy(derived().ptr());
|
return args_proxy(derived().ptr());
|
||||||
}
|
}
|
||||||
template <typename D> template <typename T> bool object_api<D>::contains(T &&key) const {
|
template <typename D> template <typename T> bool object_api<D>::contains(T &&item) const {
|
||||||
return attr("__contains__")(std::forward<T>(key)).template cast<bool>();
|
return attr("__contains__")(std::forward<T>(item)).template cast<bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename D>
|
template <typename D>
|
||||||
|
Loading…
Reference in New Issue
Block a user