Spaces:
Sleeping
Sleeping
3fcbe24c16a686a483fb3546c8297933aea8e317fa2507a6c436d82627d50293
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +1 -0
- third-party/DPVO/DPRetrieval/CMakeLists.txt +17 -0
- third-party/DPVO/DPRetrieval/pybind11/.appveyor.yml +37 -0
- third-party/DPVO/DPRetrieval/pybind11/.clang-format +38 -0
- third-party/DPVO/DPRetrieval/pybind11/.clang-tidy +72 -0
- third-party/DPVO/DPRetrieval/pybind11/.cmake-format.yaml +73 -0
- third-party/DPVO/DPRetrieval/pybind11/.pre-commit-config.yaml +147 -0
- third-party/DPVO/DPRetrieval/pybind11/.readthedocs.yml +3 -0
- third-party/DPVO/DPRetrieval/pybind11/CMakeLists.txt +299 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/_static/theme_overrides.css +11 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/chrono.rst +81 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/custom.rst +93 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/eigen.rst +310 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/functional.rst +109 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/index.rst +43 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/overview.rst +171 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/stl.rst +251 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/strings.rst +305 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/classes.rst +1349 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/embedding.rst +262 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/exceptions.rst +398 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/functions.rst +615 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/misc.rst +337 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/index.rst +13 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/numpy.rst +463 -0
- third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/object.rst +286 -0
- third-party/DPVO/calib/barn.txt +1 -0
- third-party/DPVO/calib/eth.txt +1 -0
- third-party/DPVO/calib/euroc.txt +1 -0
- third-party/DPVO/calib/iphone.txt +1 -0
- third-party/DPVO/calib/kitti.txt +1 -0
- third-party/DPVO/calib/monovo.txt +1 -0
- third-party/DPVO/calib/tartan.txt +1 -0
- third-party/DPVO/calib/tum3.txt +1 -0
- third-party/DPVO/calib/viper.txt +1 -0
- third-party/DPVO/config/default.yaml +19 -0
- third-party/DPVO/config/fast.yaml +20 -0
- third-party/DPVO/datasets/euroc_groundtruth/MH_01_easy.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/MH_02_easy.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/MH_03_medium.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/MH_04_difficult.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/MH_05_difficult.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V1_01_easy.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V1_02_medium.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V1_03_difficult.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V2_01_easy.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V2_02_medium.txt +0 -0
- third-party/DPVO/datasets/euroc_groundtruth/V2_03_difficult.txt +0 -0
- third-party/DPVO/demo.py +103 -0
- third-party/DPVO/dist/dpvo-0.0.0-py3.9-win-amd64.egg +3 -0
.gitattributes
CHANGED
@@ -49,3 +49,4 @@ third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/fastba/ba_cuda.obj filter
|
|
49 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch.obj filter=lfs diff=lfs merge=lfs -text
|
50 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch_cpu.obj filter=lfs diff=lfs merge=lfs -text
|
51 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch_gpu.obj filter=lfs diff=lfs merge=lfs -text
|
|
|
|
49 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch.obj filter=lfs diff=lfs merge=lfs -text
|
50 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch_cpu.obj filter=lfs diff=lfs merge=lfs -text
|
51 |
third-party/DPVO/build/temp.win-amd64-3.9/Release/dpvo/lietorch/src/lietorch_gpu.obj filter=lfs diff=lfs merge=lfs -text
|
52 |
+
third-party/DPVO/dist/dpvo-0.0.0-py3.9-win-amd64.egg filter=lfs diff=lfs merge=lfs -text
|
third-party/DPVO/DPRetrieval/CMakeLists.txt
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
cmake_minimum_required(VERSION 3.4...3.18)
|
2 |
+
project(dpretrieval)
|
3 |
+
find_package(OpenCV REQUIRED)
|
4 |
+
include_directories(${OpenCV_INCLUDE_DIRS})
|
5 |
+
|
6 |
+
find_package(DBoW2 REQUIRED)
|
7 |
+
include_directories(${DBoW2_INCLUDE_DIRS})
|
8 |
+
|
9 |
+
|
10 |
+
add_subdirectory(pybind11)
|
11 |
+
pybind11_add_module(dpretrieval src/main.cpp)
|
12 |
+
target_link_libraries(dpretrieval PRIVATE ${OpenCV_LIBS} ${DBoW2_LIBS} )
|
13 |
+
|
14 |
+
# EXAMPLE_VERSION_INFO is defined by setup.py and passed into the C++ code as a
|
15 |
+
# define (VERSION_INFO) here.
|
16 |
+
target_compile_definitions(dpretrieval
|
17 |
+
PRIVATE VERSION_INFO=${EXAMPLE_VERSION_INFO})
|
third-party/DPVO/DPRetrieval/pybind11/.appveyor.yml
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
version: 1.0.{build}
|
2 |
+
image:
|
3 |
+
- Visual Studio 2015
|
4 |
+
test: off
|
5 |
+
skip_branch_with_pr: true
|
6 |
+
build:
|
7 |
+
parallel: true
|
8 |
+
platform:
|
9 |
+
- x86
|
10 |
+
environment:
|
11 |
+
matrix:
|
12 |
+
- PYTHON: 36
|
13 |
+
CONFIG: Debug
|
14 |
+
- PYTHON: 27
|
15 |
+
CONFIG: Debug
|
16 |
+
install:
|
17 |
+
- ps: |
|
18 |
+
$env:CMAKE_GENERATOR = "Visual Studio 14 2015"
|
19 |
+
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
|
20 |
+
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
|
21 |
+
python -W ignore -m pip install --upgrade pip wheel
|
22 |
+
python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout
|
23 |
+
- ps: |
|
24 |
+
Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'
|
25 |
+
7z x eigen-3.3.7.zip -y > $null
|
26 |
+
$env:CMAKE_INCLUDE_PATH = "eigen-3.3.7;$env:CMAKE_INCLUDE_PATH"
|
27 |
+
build_script:
|
28 |
+
- cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%"
|
29 |
+
-DCMAKE_CXX_STANDARD=14
|
30 |
+
-DPYBIND11_WERROR=ON
|
31 |
+
-DDOWNLOAD_CATCH=ON
|
32 |
+
-DCMAKE_SUPPRESS_REGENERATION=1
|
33 |
+
.
|
34 |
+
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
35 |
+
- cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%
|
36 |
+
- cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%
|
37 |
+
on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log*
|
third-party/DPVO/DPRetrieval/pybind11/.clang-format
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
# See all possible options and defaults with:
|
3 |
+
# clang-format --style=llvm --dump-config
|
4 |
+
BasedOnStyle: LLVM
|
5 |
+
AccessModifierOffset: -4
|
6 |
+
AllowShortLambdasOnASingleLine: true
|
7 |
+
AlwaysBreakTemplateDeclarations: Yes
|
8 |
+
BinPackArguments: false
|
9 |
+
BinPackParameters: false
|
10 |
+
BreakBeforeBinaryOperators: All
|
11 |
+
BreakConstructorInitializers: BeforeColon
|
12 |
+
ColumnLimit: 99
|
13 |
+
CommentPragmas: 'NOLINT:.*|^ IWYU pragma:'
|
14 |
+
IncludeBlocks: Regroup
|
15 |
+
IndentCaseLabels: true
|
16 |
+
IndentPPDirectives: AfterHash
|
17 |
+
IndentWidth: 4
|
18 |
+
Language: Cpp
|
19 |
+
SpaceAfterCStyleCast: true
|
20 |
+
Standard: Cpp11
|
21 |
+
StatementMacros: ['PyObject_HEAD']
|
22 |
+
TabWidth: 4
|
23 |
+
IncludeCategories:
|
24 |
+
- Regex: '<pybind11/.*'
|
25 |
+
Priority: -1
|
26 |
+
- Regex: 'pybind11.h"$'
|
27 |
+
Priority: 1
|
28 |
+
- Regex: '^".*/?detail/'
|
29 |
+
Priority: 1
|
30 |
+
SortPriority: 2
|
31 |
+
- Regex: '^"'
|
32 |
+
Priority: 1
|
33 |
+
SortPriority: 3
|
34 |
+
- Regex: '<[[:alnum:]._]+>'
|
35 |
+
Priority: 4
|
36 |
+
- Regex: '.*'
|
37 |
+
Priority: 5
|
38 |
+
...
|
third-party/DPVO/DPRetrieval/pybind11/.clang-tidy
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FormatStyle: file
|
2 |
+
|
3 |
+
Checks: '
|
4 |
+
*bugprone*,
|
5 |
+
clang-analyzer-optin.performance.Padding,
|
6 |
+
clang-analyzer-optin.cplusplus.VirtualCall,
|
7 |
+
cppcoreguidelines-init-variables,
|
8 |
+
cppcoreguidelines-prefer-member-initializer,
|
9 |
+
cppcoreguidelines-pro-type-static-cast-downcast,
|
10 |
+
cppcoreguidelines-slicing,
|
11 |
+
google-explicit-constructor,
|
12 |
+
llvm-namespace-comment,
|
13 |
+
misc-misplaced-const,
|
14 |
+
misc-non-copyable-objects,
|
15 |
+
misc-static-assert,
|
16 |
+
misc-throw-by-value-catch-by-reference,
|
17 |
+
misc-uniqueptr-reset-release,
|
18 |
+
misc-unused-parameters,
|
19 |
+
modernize-avoid-bind,
|
20 |
+
modernize-make-shared,
|
21 |
+
modernize-redundant-void-arg,
|
22 |
+
modernize-replace-auto-ptr,
|
23 |
+
modernize-replace-disallow-copy-and-assign-macro,
|
24 |
+
modernize-replace-random-shuffle,
|
25 |
+
modernize-shrink-to-fit,
|
26 |
+
modernize-use-auto,
|
27 |
+
modernize-use-bool-literals,
|
28 |
+
modernize-use-equals-default,
|
29 |
+
modernize-use-equals-delete,
|
30 |
+
modernize-use-default-member-init,
|
31 |
+
modernize-use-noexcept,
|
32 |
+
modernize-use-emplace,
|
33 |
+
modernize-use-override,
|
34 |
+
modernize-use-using,
|
35 |
+
*performance*,
|
36 |
+
readability-avoid-const-params-in-decls,
|
37 |
+
readability-braces-around-statements,
|
38 |
+
readability-const-return-type,
|
39 |
+
readability-container-size-empty,
|
40 |
+
readability-delete-null-pointer,
|
41 |
+
readability-else-after-return,
|
42 |
+
readability-implicit-bool-conversion,
|
43 |
+
readability-inconsistent-declaration-parameter-name,
|
44 |
+
readability-make-member-function-const,
|
45 |
+
readability-misplaced-array-index,
|
46 |
+
readability-non-const-parameter,
|
47 |
+
readability-qualified-auto,
|
48 |
+
readability-redundant-function-ptr-dereference,
|
49 |
+
readability-redundant-smartptr-get,
|
50 |
+
readability-redundant-string-cstr,
|
51 |
+
readability-simplify-subscript-expr,
|
52 |
+
readability-static-accessed-through-instance,
|
53 |
+
readability-static-definition-in-anonymous-namespace,
|
54 |
+
readability-string-compare,
|
55 |
+
readability-suspicious-call-argument,
|
56 |
+
readability-uniqueptr-delete-release,
|
57 |
+
-bugprone-exception-escape,
|
58 |
+
-bugprone-reserved-identifier,
|
59 |
+
-bugprone-unused-raii,
|
60 |
+
'
|
61 |
+
|
62 |
+
CheckOptions:
|
63 |
+
- key: performance-for-range-copy.WarnOnAllAutoCopies
|
64 |
+
value: true
|
65 |
+
- key: performance-unnecessary-value-param.AllowedTypes
|
66 |
+
value: 'exception_ptr$;'
|
67 |
+
- key: readability-implicit-bool-conversion.AllowPointerConditions
|
68 |
+
value: true
|
69 |
+
|
70 |
+
HeaderFilterRegex: 'pybind11/.*h'
|
71 |
+
|
72 |
+
WarningsAsErrors: '*'
|
third-party/DPVO/DPRetrieval/pybind11/.cmake-format.yaml
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
parse:
|
2 |
+
additional_commands:
|
3 |
+
pybind11_add_module:
|
4 |
+
flags:
|
5 |
+
- THIN_LTO
|
6 |
+
- MODULE
|
7 |
+
- SHARED
|
8 |
+
- NO_EXTRAS
|
9 |
+
- EXCLUDE_FROM_ALL
|
10 |
+
- SYSTEM
|
11 |
+
|
12 |
+
format:
|
13 |
+
line_width: 99
|
14 |
+
tab_size: 2
|
15 |
+
|
16 |
+
# If an argument group contains more than this many sub-groups
|
17 |
+
# (parg or kwarg groups) then force it to a vertical layout.
|
18 |
+
max_subgroups_hwrap: 2
|
19 |
+
|
20 |
+
# If a positional argument group contains more than this many
|
21 |
+
# arguments, then force it to a vertical layout.
|
22 |
+
max_pargs_hwrap: 6
|
23 |
+
|
24 |
+
# If a cmdline positional group consumes more than this many
|
25 |
+
# lines without nesting, then invalidate the layout (and nest)
|
26 |
+
max_rows_cmdline: 2
|
27 |
+
separate_ctrl_name_with_space: false
|
28 |
+
separate_fn_name_with_space: false
|
29 |
+
dangle_parens: false
|
30 |
+
|
31 |
+
# If the trailing parenthesis must be 'dangled' on its on
|
32 |
+
# 'line, then align it to this reference: `prefix`: the start'
|
33 |
+
# 'of the statement, `prefix-indent`: the start of the'
|
34 |
+
# 'statement, plus one indentation level, `child`: align to'
|
35 |
+
# the column of the arguments
|
36 |
+
dangle_align: prefix
|
37 |
+
# If the statement spelling length (including space and
|
38 |
+
# parenthesis) is smaller than this amount, then force reject
|
39 |
+
# nested layouts.
|
40 |
+
min_prefix_chars: 4
|
41 |
+
|
42 |
+
# If the statement spelling length (including space and
|
43 |
+
# parenthesis) is larger than the tab width by more than this
|
44 |
+
# amount, then force reject un-nested layouts.
|
45 |
+
max_prefix_chars: 10
|
46 |
+
|
47 |
+
# If a candidate layout is wrapped horizontally but it exceeds
|
48 |
+
# this many lines, then reject the layout.
|
49 |
+
max_lines_hwrap: 2
|
50 |
+
|
51 |
+
line_ending: unix
|
52 |
+
|
53 |
+
# Format command names consistently as 'lower' or 'upper' case
|
54 |
+
command_case: canonical
|
55 |
+
|
56 |
+
# Format keywords consistently as 'lower' or 'upper' case
|
57 |
+
# unchanged is valid too
|
58 |
+
keyword_case: 'upper'
|
59 |
+
|
60 |
+
# A list of command names which should always be wrapped
|
61 |
+
always_wrap: []
|
62 |
+
|
63 |
+
# If true, the argument lists which are known to be sortable
|
64 |
+
# will be sorted lexicographically
|
65 |
+
enable_sort: true
|
66 |
+
|
67 |
+
# If true, the parsers may infer whether or not an argument
|
68 |
+
# list is sortable (without annotation).
|
69 |
+
autosort: false
|
70 |
+
|
71 |
+
# Causes a few issues - can be solved later, possibly.
|
72 |
+
markup:
|
73 |
+
enable_markup: false
|
third-party/DPVO/DPRetrieval/pybind11/.pre-commit-config.yaml
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# To use:
|
2 |
+
#
|
3 |
+
# pre-commit run -a
|
4 |
+
#
|
5 |
+
# Or:
|
6 |
+
#
|
7 |
+
# pre-commit install # (runs every time you commit in git)
|
8 |
+
#
|
9 |
+
# To update this file:
|
10 |
+
#
|
11 |
+
# pre-commit autoupdate
|
12 |
+
#
|
13 |
+
# See https://github.com/pre-commit/pre-commit
|
14 |
+
|
15 |
+
repos:
|
16 |
+
# Standard hooks
|
17 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
18 |
+
rev: v4.1.0
|
19 |
+
hooks:
|
20 |
+
- id: check-added-large-files
|
21 |
+
- id: check-case-conflict
|
22 |
+
- id: check-docstring-first
|
23 |
+
- id: check-merge-conflict
|
24 |
+
- id: check-symlinks
|
25 |
+
- id: check-toml
|
26 |
+
- id: check-yaml
|
27 |
+
- id: debug-statements
|
28 |
+
- id: end-of-file-fixer
|
29 |
+
- id: mixed-line-ending
|
30 |
+
- id: requirements-txt-fixer
|
31 |
+
- id: trailing-whitespace
|
32 |
+
- id: fix-encoding-pragma
|
33 |
+
exclude: ^noxfile.py$
|
34 |
+
|
35 |
+
- repo: https://github.com/asottile/pyupgrade
|
36 |
+
rev: v2.31.0
|
37 |
+
hooks:
|
38 |
+
- id: pyupgrade
|
39 |
+
|
40 |
+
- repo: https://github.com/PyCQA/isort
|
41 |
+
rev: 5.10.1
|
42 |
+
hooks:
|
43 |
+
- id: isort
|
44 |
+
|
45 |
+
# Black, the code formatter, natively supports pre-commit
|
46 |
+
- repo: https://github.com/psf/black
|
47 |
+
rev: 21.12b0 # Keep in sync with blacken-docs
|
48 |
+
hooks:
|
49 |
+
- id: black
|
50 |
+
|
51 |
+
- repo: https://github.com/asottile/blacken-docs
|
52 |
+
rev: v1.12.0
|
53 |
+
hooks:
|
54 |
+
- id: blacken-docs
|
55 |
+
additional_dependencies:
|
56 |
+
- black==21.12b0 # keep in sync with black hook
|
57 |
+
|
58 |
+
# Changes tabs to spaces
|
59 |
+
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
60 |
+
rev: v1.1.10
|
61 |
+
hooks:
|
62 |
+
- id: remove-tabs
|
63 |
+
|
64 |
+
# Autoremoves unused imports
|
65 |
+
- repo: https://github.com/hadialqattan/pycln
|
66 |
+
rev: v1.1.0
|
67 |
+
hooks:
|
68 |
+
- id: pycln
|
69 |
+
|
70 |
+
- repo: https://github.com/pre-commit/pygrep-hooks
|
71 |
+
rev: v1.9.0
|
72 |
+
hooks:
|
73 |
+
- id: python-check-blanket-noqa
|
74 |
+
- id: python-check-blanket-type-ignore
|
75 |
+
- id: python-no-log-warn
|
76 |
+
- id: rst-backticks
|
77 |
+
- id: rst-directive-colons
|
78 |
+
- id: rst-inline-touching-normal
|
79 |
+
|
80 |
+
# Flake8 also supports pre-commit natively (same author)
|
81 |
+
- repo: https://github.com/PyCQA/flake8
|
82 |
+
rev: 4.0.1
|
83 |
+
hooks:
|
84 |
+
- id: flake8
|
85 |
+
additional_dependencies: &flake8_dependencies
|
86 |
+
- flake8-bugbear
|
87 |
+
- pep8-naming
|
88 |
+
exclude: ^(docs/.*|tools/.*)$
|
89 |
+
|
90 |
+
- repo: https://github.com/asottile/yesqa
|
91 |
+
rev: v1.3.0
|
92 |
+
hooks:
|
93 |
+
- id: yesqa
|
94 |
+
additional_dependencies: *flake8_dependencies
|
95 |
+
|
96 |
+
# CMake formatting
|
97 |
+
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
98 |
+
rev: v0.6.13
|
99 |
+
hooks:
|
100 |
+
- id: cmake-format
|
101 |
+
additional_dependencies: [pyyaml]
|
102 |
+
types: [file]
|
103 |
+
files: (\.cmake|CMakeLists.txt)(.in)?$
|
104 |
+
|
105 |
+
# Check static types with mypy
|
106 |
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
107 |
+
rev: v0.931
|
108 |
+
hooks:
|
109 |
+
- id: mypy
|
110 |
+
# Running per-file misbehaves a bit, so just run on all files, it's fast
|
111 |
+
pass_filenames: false
|
112 |
+
additional_dependencies: [typed_ast]
|
113 |
+
|
114 |
+
# Checks the manifest for missing files (native support)
|
115 |
+
- repo: https://github.com/mgedmin/check-manifest
|
116 |
+
rev: "0.47"
|
117 |
+
hooks:
|
118 |
+
- id: check-manifest
|
119 |
+
# This is a slow hook, so only run this if --hook-stage manual is passed
|
120 |
+
stages: [manual]
|
121 |
+
additional_dependencies: [cmake, ninja]
|
122 |
+
|
123 |
+
- repo: https://github.com/codespell-project/codespell
|
124 |
+
rev: v2.1.0
|
125 |
+
hooks:
|
126 |
+
- id: codespell
|
127 |
+
exclude: ".supp$"
|
128 |
+
args: ["-L", "nd,ot,thist"]
|
129 |
+
|
130 |
+
- repo: https://github.com/shellcheck-py/shellcheck-py
|
131 |
+
rev: v0.8.0.3
|
132 |
+
hooks:
|
133 |
+
- id: shellcheck
|
134 |
+
|
135 |
+
# The original pybind11 checks for a few C++ style items
|
136 |
+
- repo: local
|
137 |
+
hooks:
|
138 |
+
- id: disallow-caps
|
139 |
+
name: Disallow improper capitalization
|
140 |
+
language: pygrep
|
141 |
+
entry: PyBind|Numpy|Cmake|CCache|PyTest
|
142 |
+
exclude: .pre-commit-config.yaml
|
143 |
+
|
144 |
+
- repo: https://github.com/pre-commit/mirrors-clang-format
|
145 |
+
rev: "v13.0.0"
|
146 |
+
hooks:
|
147 |
+
- id: clang-format
|
third-party/DPVO/DPRetrieval/pybind11/.readthedocs.yml
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
python:
|
2 |
+
version: 3
|
3 |
+
requirements_file: docs/requirements.txt
|
third-party/DPVO/DPRetrieval/pybind11/CMakeLists.txt
ADDED
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# CMakeLists.txt -- Build system for the pybind11 modules
|
2 |
+
#
|
3 |
+
# Copyright (c) 2015 Wenzel Jakob <[email protected]>
|
4 |
+
#
|
5 |
+
# All rights reserved. Use of this source code is governed by a
|
6 |
+
# BSD-style license that can be found in the LICENSE file.
|
7 |
+
|
8 |
+
cmake_minimum_required(VERSION 3.4)
|
9 |
+
|
10 |
+
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
|
11 |
+
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
12 |
+
# the behavior using the following workaround:
|
13 |
+
if(${CMAKE_VERSION} VERSION_LESS 3.22)
|
14 |
+
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
15 |
+
else()
|
16 |
+
cmake_policy(VERSION 3.22)
|
17 |
+
endif()
|
18 |
+
|
19 |
+
# Avoid infinite recursion if tests include this as a subdirectory
|
20 |
+
if(DEFINED PYBIND11_MASTER_PROJECT)
|
21 |
+
return()
|
22 |
+
endif()
|
23 |
+
|
24 |
+
# Extract project version from source
|
25 |
+
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
|
26 |
+
pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
|
27 |
+
|
28 |
+
foreach(ver ${pybind11_version_defines})
|
29 |
+
if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
|
30 |
+
set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
|
31 |
+
endif()
|
32 |
+
endforeach()
|
33 |
+
|
34 |
+
if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
|
35 |
+
set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
|
36 |
+
endif()
|
37 |
+
string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")
|
38 |
+
|
39 |
+
project(
|
40 |
+
pybind11
|
41 |
+
LANGUAGES CXX
|
42 |
+
VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")
|
43 |
+
|
44 |
+
# Standard includes
|
45 |
+
include(GNUInstallDirs)
|
46 |
+
include(CMakePackageConfigHelpers)
|
47 |
+
include(CMakeDependentOption)
|
48 |
+
|
49 |
+
if(NOT pybind11_FIND_QUIETLY)
|
50 |
+
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
51 |
+
endif()
|
52 |
+
|
53 |
+
# Check if pybind11 is being used directly or via add_subdirectory
|
54 |
+
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
55 |
+
### Warn if not an out-of-source builds
|
56 |
+
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
57 |
+
set(lines
|
58 |
+
"You are building in-place. If that is not what you intended to "
|
59 |
+
"do, you can clean the source directory with:\n"
|
60 |
+
"rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
|
61 |
+
"pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
|
62 |
+
message(AUTHOR_WARNING ${lines})
|
63 |
+
endif()
|
64 |
+
|
65 |
+
set(PYBIND11_MASTER_PROJECT ON)
|
66 |
+
|
67 |
+
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
|
68 |
+
# Bug in macOS CMake < 3.7 is unable to download catch
|
69 |
+
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
|
70 |
+
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
|
71 |
+
# Only tested with 3.8+ in CI.
|
72 |
+
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
|
73 |
+
endif()
|
74 |
+
|
75 |
+
message(STATUS "CMake ${CMAKE_VERSION}")
|
76 |
+
|
77 |
+
if(CMAKE_CXX_STANDARD)
|
78 |
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
79 |
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
80 |
+
endif()
|
81 |
+
|
82 |
+
set(pybind11_system "")
|
83 |
+
|
84 |
+
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
85 |
+
else()
|
86 |
+
set(PYBIND11_MASTER_PROJECT OFF)
|
87 |
+
set(pybind11_system SYSTEM)
|
88 |
+
endif()
|
89 |
+
|
90 |
+
# Options
|
91 |
+
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
|
92 |
+
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
|
93 |
+
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
|
94 |
+
set(PYBIND11_INTERNALS_VERSION
|
95 |
+
""
|
96 |
+
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
|
97 |
+
|
98 |
+
cmake_dependent_option(
|
99 |
+
USE_PYTHON_INCLUDE_DIR
|
100 |
+
"Install pybind11 headers in Python include directory instead of default installation prefix"
|
101 |
+
OFF "PYBIND11_INSTALL" OFF)
|
102 |
+
|
103 |
+
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
|
104 |
+
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
|
105 |
+
|
106 |
+
# NB: when adding a header don't forget to also add it to setup.py
|
107 |
+
set(PYBIND11_HEADERS
|
108 |
+
include/pybind11/detail/class.h
|
109 |
+
include/pybind11/detail/common.h
|
110 |
+
include/pybind11/detail/descr.h
|
111 |
+
include/pybind11/detail/init.h
|
112 |
+
include/pybind11/detail/internals.h
|
113 |
+
include/pybind11/detail/type_caster_base.h
|
114 |
+
include/pybind11/detail/typeid.h
|
115 |
+
include/pybind11/attr.h
|
116 |
+
include/pybind11/buffer_info.h
|
117 |
+
include/pybind11/cast.h
|
118 |
+
include/pybind11/chrono.h
|
119 |
+
include/pybind11/common.h
|
120 |
+
include/pybind11/complex.h
|
121 |
+
include/pybind11/options.h
|
122 |
+
include/pybind11/eigen.h
|
123 |
+
include/pybind11/embed.h
|
124 |
+
include/pybind11/eval.h
|
125 |
+
include/pybind11/gil.h
|
126 |
+
include/pybind11/iostream.h
|
127 |
+
include/pybind11/functional.h
|
128 |
+
include/pybind11/numpy.h
|
129 |
+
include/pybind11/operators.h
|
130 |
+
include/pybind11/pybind11.h
|
131 |
+
include/pybind11/pytypes.h
|
132 |
+
include/pybind11/stl.h
|
133 |
+
include/pybind11/stl_bind.h
|
134 |
+
include/pybind11/stl/filesystem.h)
|
135 |
+
|
136 |
+
# Compare with grep and warn if mismatched
|
137 |
+
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
|
138 |
+
file(
|
139 |
+
GLOB_RECURSE _pybind11_header_check
|
140 |
+
LIST_DIRECTORIES false
|
141 |
+
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
142 |
+
CONFIGURE_DEPENDS "include/pybind11/*.h")
|
143 |
+
set(_pybind11_here_only ${PYBIND11_HEADERS})
|
144 |
+
set(_pybind11_disk_only ${_pybind11_header_check})
|
145 |
+
list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
|
146 |
+
list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
|
147 |
+
if(_pybind11_here_only)
|
148 |
+
message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
|
149 |
+
endif()
|
150 |
+
if(_pybind11_disk_only)
|
151 |
+
message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
|
152 |
+
endif()
|
153 |
+
endif()
|
154 |
+
|
155 |
+
# CMake 3.12 added list(TRANSFORM <list> PREPEND
|
156 |
+
# But we can't use it yet
|
157 |
+
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
|
158 |
+
"${PYBIND11_HEADERS}")
|
159 |
+
|
160 |
+
# Cache variable so this can be used in parent projects
|
161 |
+
set(pybind11_INCLUDE_DIR
|
162 |
+
"${CMAKE_CURRENT_LIST_DIR}/include"
|
163 |
+
CACHE INTERNAL "Directory where pybind11 headers are located")
|
164 |
+
|
165 |
+
# Backward compatible variable for add_subdirectory mode
|
166 |
+
if(NOT PYBIND11_MASTER_PROJECT)
|
167 |
+
set(PYBIND11_INCLUDE_DIR
|
168 |
+
"${pybind11_INCLUDE_DIR}"
|
169 |
+
CACHE INTERNAL "")
|
170 |
+
endif()
|
171 |
+
|
172 |
+
# Note: when creating targets, you cannot use if statements at configure time -
|
173 |
+
# you need generator expressions, because those will be placed in the target file.
|
174 |
+
# You can also place ifs *in* the Config.in, but not here.
|
175 |
+
|
176 |
+
# This section builds targets, but does *not* touch Python
|
177 |
+
# Non-IMPORT targets cannot be defined twice
|
178 |
+
if(NOT TARGET pybind11_headers)
|
179 |
+
# Build the headers-only target (no Python included):
|
180 |
+
# (long name used here to keep this from clashing in subdirectory mode)
|
181 |
+
add_library(pybind11_headers INTERFACE)
|
182 |
+
add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
|
183 |
+
add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
|
184 |
+
|
185 |
+
target_include_directories(
|
186 |
+
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
|
187 |
+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
188 |
+
|
189 |
+
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
|
190 |
+
cxx_right_angle_brackets)
|
191 |
+
if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
|
192 |
+
target_compile_definitions(
|
193 |
+
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
|
194 |
+
endif()
|
195 |
+
else()
|
196 |
+
# It is invalid to install a target twice, too.
|
197 |
+
set(PYBIND11_INSTALL OFF)
|
198 |
+
endif()
|
199 |
+
|
200 |
+
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
|
201 |
+
|
202 |
+
# Relative directory setting
|
203 |
+
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
|
204 |
+
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
|
205 |
+
elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
|
206 |
+
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
|
207 |
+
endif()
|
208 |
+
|
209 |
+
if(PYBIND11_INSTALL)
|
210 |
+
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
211 |
+
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
|
212 |
+
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
|
213 |
+
CACHE STRING "install path for pybind11Config.cmake")
|
214 |
+
|
215 |
+
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
|
216 |
+
set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
217 |
+
else()
|
218 |
+
set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}")
|
219 |
+
endif()
|
220 |
+
|
221 |
+
configure_package_config_file(
|
222 |
+
tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
223 |
+
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
224 |
+
|
225 |
+
if(CMAKE_VERSION VERSION_LESS 3.14)
|
226 |
+
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
|
227 |
+
# not depend on architecture specific settings or libraries.
|
228 |
+
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
|
229 |
+
unset(CMAKE_SIZEOF_VOID_P)
|
230 |
+
|
231 |
+
write_basic_package_version_file(
|
232 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
233 |
+
VERSION ${PROJECT_VERSION}
|
234 |
+
COMPATIBILITY AnyNewerVersion)
|
235 |
+
|
236 |
+
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
|
237 |
+
else()
|
238 |
+
# CMake 3.14+ natively supports header-only libraries
|
239 |
+
write_basic_package_version_file(
|
240 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
241 |
+
VERSION ${PROJECT_VERSION}
|
242 |
+
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
|
243 |
+
endif()
|
244 |
+
|
245 |
+
install(
|
246 |
+
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
247 |
+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
248 |
+
tools/FindPythonLibsNew.cmake
|
249 |
+
tools/pybind11Common.cmake
|
250 |
+
tools/pybind11Tools.cmake
|
251 |
+
tools/pybind11NewTools.cmake
|
252 |
+
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
253 |
+
|
254 |
+
if(NOT PYBIND11_EXPORT_NAME)
|
255 |
+
set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
|
256 |
+
endif()
|
257 |
+
|
258 |
+
install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")
|
259 |
+
|
260 |
+
install(
|
261 |
+
EXPORT "${PYBIND11_EXPORT_NAME}"
|
262 |
+
NAMESPACE "pybind11::"
|
263 |
+
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
264 |
+
|
265 |
+
# Uninstall target
|
266 |
+
if(PYBIND11_MASTER_PROJECT)
|
267 |
+
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
|
268 |
+
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
269 |
+
|
270 |
+
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
|
271 |
+
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
272 |
+
endif()
|
273 |
+
endif()
|
274 |
+
|
275 |
+
# BUILD_TESTING takes priority, but only if this is the master project
|
276 |
+
if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
|
277 |
+
if(BUILD_TESTING)
|
278 |
+
if(_pybind11_nopython)
|
279 |
+
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
280 |
+
else()
|
281 |
+
add_subdirectory(tests)
|
282 |
+
endif()
|
283 |
+
endif()
|
284 |
+
else()
|
285 |
+
if(PYBIND11_TEST)
|
286 |
+
if(_pybind11_nopython)
|
287 |
+
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
288 |
+
else()
|
289 |
+
add_subdirectory(tests)
|
290 |
+
endif()
|
291 |
+
endif()
|
292 |
+
endif()
|
293 |
+
|
294 |
+
# Better symmetry with find_package(pybind11 CONFIG) mode.
|
295 |
+
if(NOT PYBIND11_MASTER_PROJECT)
|
296 |
+
set(pybind11_FOUND
|
297 |
+
TRUE
|
298 |
+
CACHE INTERNAL "True if pybind11 and all required components found on the system")
|
299 |
+
endif()
|
third-party/DPVO/DPRetrieval/pybind11/docs/_static/theme_overrides.css
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.wy-table-responsive table td,
|
2 |
+
.wy-table-responsive table th {
|
3 |
+
white-space: initial !important;
|
4 |
+
}
|
5 |
+
.rst-content table.docutils td {
|
6 |
+
vertical-align: top !important;
|
7 |
+
}
|
8 |
+
div[class^='highlight'] pre {
|
9 |
+
white-space: pre;
|
10 |
+
white-space: pre-wrap;
|
11 |
+
}
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/chrono.rst
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Chrono
|
2 |
+
======
|
3 |
+
|
4 |
+
When including the additional header file :file:`pybind11/chrono.h` conversions
|
5 |
+
from C++11 chrono datatypes to python datetime objects are automatically enabled.
|
6 |
+
This header also enables conversions of python floats (often from sources such
|
7 |
+
as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
|
8 |
+
into durations.
|
9 |
+
|
10 |
+
An overview of clocks in C++11
|
11 |
+
------------------------------
|
12 |
+
|
13 |
+
A point of confusion when using these conversions is the differences between
|
14 |
+
clocks provided in C++11. There are three clock types defined by the C++11
|
15 |
+
standard and users can define their own if needed. Each of these clocks have
|
16 |
+
different properties and when converting to and from python will give different
|
17 |
+
results.
|
18 |
+
|
19 |
+
The first clock defined by the standard is ``std::chrono::system_clock``. This
|
20 |
+
clock measures the current date and time. However, this clock changes with to
|
21 |
+
updates to the operating system time. For example, if your time is synchronised
|
22 |
+
with a time server this clock will change. This makes this clock a poor choice
|
23 |
+
for timing purposes but good for measuring the wall time.
|
24 |
+
|
25 |
+
The second clock defined in the standard is ``std::chrono::steady_clock``.
|
26 |
+
This clock ticks at a steady rate and is never adjusted. This makes it excellent
|
27 |
+
for timing purposes, however the value in this clock does not correspond to the
|
28 |
+
current date and time. Often this clock will be the amount of time your system
|
29 |
+
has been on, although it does not have to be. This clock will never be the same
|
30 |
+
clock as the system clock as the system clock can change but steady clocks
|
31 |
+
cannot.
|
32 |
+
|
33 |
+
The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
|
34 |
+
This clock is the clock that has the highest resolution out of the clocks in the
|
35 |
+
system. It is normally a typedef to either the system clock or the steady clock
|
36 |
+
but can be its own independent clock. This is important as when using these
|
37 |
+
conversions as the types you get in python for this clock might be different
|
38 |
+
depending on the system.
|
39 |
+
If it is a typedef of the system clock, python will get datetime objects, but if
|
40 |
+
it is a different clock they will be timedelta objects.
|
41 |
+
|
42 |
+
Provided conversions
|
43 |
+
--------------------
|
44 |
+
|
45 |
+
.. rubric:: C++ to Python
|
46 |
+
|
47 |
+
- ``std::chrono::system_clock::time_point`` → ``datetime.datetime``
|
48 |
+
System clock times are converted to python datetime instances. They are
|
49 |
+
in the local timezone, but do not have any timezone information attached
|
50 |
+
to them (they are naive datetime objects).
|
51 |
+
|
52 |
+
- ``std::chrono::duration`` → ``datetime.timedelta``
|
53 |
+
Durations are converted to timedeltas, any precision in the duration
|
54 |
+
greater than microseconds is lost by rounding towards zero.
|
55 |
+
|
56 |
+
- ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta``
|
57 |
+
Any clock time that is not the system clock is converted to a time delta.
|
58 |
+
This timedelta measures the time from the clocks epoch to now.
|
59 |
+
|
60 |
+
.. rubric:: Python to C++
|
61 |
+
|
62 |
+
- ``datetime.datetime`` or ``datetime.date`` or ``datetime.time`` → ``std::chrono::system_clock::time_point``
|
63 |
+
Date/time objects are converted into system clock timepoints. Any
|
64 |
+
timezone information is ignored and the type is treated as a naive
|
65 |
+
object.
|
66 |
+
|
67 |
+
- ``datetime.timedelta`` → ``std::chrono::duration``
|
68 |
+
Time delta are converted into durations with microsecond precision.
|
69 |
+
|
70 |
+
- ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point``
|
71 |
+
Time deltas that are converted into clock timepoints are treated as
|
72 |
+
the amount of time from the start of the clocks epoch.
|
73 |
+
|
74 |
+
- ``float`` → ``std::chrono::duration``
|
75 |
+
Floats that are passed to C++ as durations be interpreted as a number of
|
76 |
+
seconds. These will be converted to the duration using ``duration_cast``
|
77 |
+
from the float.
|
78 |
+
|
79 |
+
- ``float`` → ``std::chrono::[other_clocks]::time_point``
|
80 |
+
Floats that are passed to C++ as time points will be interpreted as the
|
81 |
+
number of seconds from the start of the clocks epoch.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/custom.rst
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Custom type casters
|
2 |
+
===================
|
3 |
+
|
4 |
+
In very rare cases, applications may require custom type casters that cannot be
|
5 |
+
expressed using the abstractions provided by pybind11, thus requiring raw
|
6 |
+
Python C API calls. This is fairly advanced usage and should only be pursued by
|
7 |
+
experts who are familiar with the intricacies of Python reference counting.
|
8 |
+
|
9 |
+
The following snippets demonstrate how this works for a very simple ``inty``
|
10 |
+
type that that should be convertible from Python types that provide a
|
11 |
+
``__int__(self)`` method.
|
12 |
+
|
13 |
+
.. code-block:: cpp
|
14 |
+
|
15 |
+
struct inty { long long_value; };
|
16 |
+
|
17 |
+
void print(inty s) {
|
18 |
+
std::cout << s.long_value << std::endl;
|
19 |
+
}
|
20 |
+
|
21 |
+
The following Python snippet demonstrates the intended usage from the Python side:
|
22 |
+
|
23 |
+
.. code-block:: python
|
24 |
+
|
25 |
+
class A:
|
26 |
+
def __int__(self):
|
27 |
+
return 123
|
28 |
+
|
29 |
+
|
30 |
+
from example import print
|
31 |
+
|
32 |
+
print(A())
|
33 |
+
|
34 |
+
To register the necessary conversion routines, it is necessary to add an
|
35 |
+
instantiation of the ``pybind11::detail::type_caster<T>`` template.
|
36 |
+
Although this is an implementation detail, adding an instantiation of this
|
37 |
+
type is explicitly allowed.
|
38 |
+
|
39 |
+
.. code-block:: cpp
|
40 |
+
|
41 |
+
namespace pybind11 { namespace detail {
|
42 |
+
template <> struct type_caster<inty> {
|
43 |
+
public:
|
44 |
+
/**
|
45 |
+
* This macro establishes the name 'inty' in
|
46 |
+
* function signatures and declares a local variable
|
47 |
+
* 'value' of type inty
|
48 |
+
*/
|
49 |
+
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Conversion part 1 (Python->C++): convert a PyObject into a inty
|
53 |
+
* instance or return false upon failure. The second argument
|
54 |
+
* indicates whether implicit conversions should be applied.
|
55 |
+
*/
|
56 |
+
bool load(handle src, bool) {
|
57 |
+
/* Extract PyObject from handle */
|
58 |
+
PyObject *source = src.ptr();
|
59 |
+
/* Try converting into a Python integer value */
|
60 |
+
PyObject *tmp = PyNumber_Long(source);
|
61 |
+
if (!tmp)
|
62 |
+
return false;
|
63 |
+
/* Now try to convert into a C++ int */
|
64 |
+
value.long_value = PyLong_AsLong(tmp);
|
65 |
+
Py_DECREF(tmp);
|
66 |
+
/* Ensure return code was OK (to avoid out-of-range errors etc) */
|
67 |
+
return !(value.long_value == -1 && !PyErr_Occurred());
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Conversion part 2 (C++ -> Python): convert an inty instance into
|
72 |
+
* a Python object. The second and third arguments are used to
|
73 |
+
* indicate the return value policy and parent object (for
|
74 |
+
* ``return_value_policy::reference_internal``) and are generally
|
75 |
+
* ignored by implicit casters.
|
76 |
+
*/
|
77 |
+
static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
|
78 |
+
return PyLong_FromLong(src.long_value);
|
79 |
+
}
|
80 |
+
};
|
81 |
+
}} // namespace pybind11::detail
|
82 |
+
|
83 |
+
.. note::
|
84 |
+
|
85 |
+
A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires
|
86 |
+
that ``T`` is default-constructible (``value`` is first default constructed
|
87 |
+
and then ``load()`` assigns to it).
|
88 |
+
|
89 |
+
.. warning::
|
90 |
+
|
91 |
+
When using custom type casters, it's important to declare them consistently
|
92 |
+
in every compilation unit of the Python extension module. Otherwise,
|
93 |
+
undefined behavior can ensue.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/eigen.rst
ADDED
@@ -0,0 +1,310 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Eigen
|
2 |
+
#####
|
3 |
+
|
4 |
+
`Eigen <http://eigen.tuxfamily.org>`_ is C++ header-based library for dense and
|
5 |
+
sparse linear algebra. Due to its popularity and widespread adoption, pybind11
|
6 |
+
provides transparent conversion and limited mapping support between Eigen and
|
7 |
+
Scientific Python linear algebra data types.
|
8 |
+
|
9 |
+
To enable the built-in Eigen support you must include the optional header file
|
10 |
+
:file:`pybind11/eigen.h`.
|
11 |
+
|
12 |
+
Pass-by-value
|
13 |
+
=============
|
14 |
+
|
15 |
+
When binding a function with ordinary Eigen dense object arguments (for
|
16 |
+
example, ``Eigen::MatrixXd``), pybind11 will accept any input value that is
|
17 |
+
already (or convertible to) a ``numpy.ndarray`` with dimensions compatible with
|
18 |
+
the Eigen type, copy its values into a temporary Eigen variable of the
|
19 |
+
appropriate type, then call the function with this temporary variable.
|
20 |
+
|
21 |
+
Sparse matrices are similarly copied to or from
|
22 |
+
``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` objects.
|
23 |
+
|
24 |
+
Pass-by-reference
|
25 |
+
=================
|
26 |
+
|
27 |
+
One major limitation of the above is that every data conversion implicitly
|
28 |
+
involves a copy, which can be both expensive (for large matrices) and disallows
|
29 |
+
binding functions that change their (Matrix) arguments. Pybind11 allows you to
|
30 |
+
work around this by using Eigen's ``Eigen::Ref<MatrixType>`` class much as you
|
31 |
+
would when writing a function taking a generic type in Eigen itself (subject to
|
32 |
+
some limitations discussed below).
|
33 |
+
|
34 |
+
When calling a bound function accepting a ``Eigen::Ref<const MatrixType>``
|
35 |
+
type, pybind11 will attempt to avoid copying by using an ``Eigen::Map`` object
|
36 |
+
that maps into the source ``numpy.ndarray`` data: this requires both that the
|
37 |
+
data types are the same (e.g. ``dtype='float64'`` and ``MatrixType::Scalar`` is
|
38 |
+
``double``); and that the storage is layout compatible. The latter limitation
|
39 |
+
is discussed in detail in the section below, and requires careful
|
40 |
+
consideration: by default, numpy matrices and Eigen matrices are *not* storage
|
41 |
+
compatible.
|
42 |
+
|
43 |
+
If the numpy matrix cannot be used as is (either because its types differ, e.g.
|
44 |
+
passing an array of integers to an Eigen parameter requiring doubles, or
|
45 |
+
because the storage is incompatible), pybind11 makes a temporary copy and
|
46 |
+
passes the copy instead.
|
47 |
+
|
48 |
+
When a bound function parameter is instead ``Eigen::Ref<MatrixType>`` (note the
|
49 |
+
lack of ``const``), pybind11 will only allow the function to be called if it
|
50 |
+
can be mapped *and* if the numpy array is writeable (that is
|
51 |
+
``a.flags.writeable`` is true). Any access (including modification) made to
|
52 |
+
the passed variable will be transparently carried out directly on the
|
53 |
+
``numpy.ndarray``.
|
54 |
+
|
55 |
+
This means you can write code such as the following and have it work as
|
56 |
+
expected:
|
57 |
+
|
58 |
+
.. code-block:: cpp
|
59 |
+
|
60 |
+
void scale_by_2(Eigen::Ref<Eigen::VectorXd> v) {
|
61 |
+
v *= 2;
|
62 |
+
}
|
63 |
+
|
64 |
+
Note, however, that you will likely run into limitations due to numpy and
|
65 |
+
Eigen's difference default storage order for data; see the below section on
|
66 |
+
:ref:`storage_orders` for details on how to bind code that won't run into such
|
67 |
+
limitations.
|
68 |
+
|
69 |
+
.. note::
|
70 |
+
|
71 |
+
Passing by reference is not supported for sparse types.
|
72 |
+
|
73 |
+
Returning values to Python
|
74 |
+
==========================
|
75 |
+
|
76 |
+
When returning an ordinary dense Eigen matrix type to numpy (e.g.
|
77 |
+
``Eigen::MatrixXd`` or ``Eigen::RowVectorXf``) pybind11 keeps the matrix and
|
78 |
+
returns a numpy array that directly references the Eigen matrix: no copy of the
|
79 |
+
data is performed. The numpy array will have ``array.flags.owndata`` set to
|
80 |
+
``False`` to indicate that it does not own the data, and the lifetime of the
|
81 |
+
stored Eigen matrix will be tied to the returned ``array``.
|
82 |
+
|
83 |
+
If you bind a function with a non-reference, ``const`` return type (e.g.
|
84 |
+
``const Eigen::MatrixXd``), the same thing happens except that pybind11 also
|
85 |
+
sets the numpy array's ``writeable`` flag to false.
|
86 |
+
|
87 |
+
If you return an lvalue reference or pointer, the usual pybind11 rules apply,
|
88 |
+
as dictated by the binding function's return value policy (see the
|
89 |
+
documentation on :ref:`return_value_policies` for full details). That means,
|
90 |
+
without an explicit return value policy, lvalue references will be copied and
|
91 |
+
pointers will be managed by pybind11. In order to avoid copying, you should
|
92 |
+
explicitly specify an appropriate return value policy, as in the following
|
93 |
+
example:
|
94 |
+
|
95 |
+
.. code-block:: cpp
|
96 |
+
|
97 |
+
class MyClass {
|
98 |
+
Eigen::MatrixXd big_mat = Eigen::MatrixXd::Zero(10000, 10000);
|
99 |
+
public:
|
100 |
+
Eigen::MatrixXd &getMatrix() { return big_mat; }
|
101 |
+
const Eigen::MatrixXd &viewMatrix() { return big_mat; }
|
102 |
+
};
|
103 |
+
|
104 |
+
// Later, in binding code:
|
105 |
+
py::class_<MyClass>(m, "MyClass")
|
106 |
+
.def(py::init<>())
|
107 |
+
.def("copy_matrix", &MyClass::getMatrix) // Makes a copy!
|
108 |
+
.def("get_matrix", &MyClass::getMatrix, py::return_value_policy::reference_internal)
|
109 |
+
.def("view_matrix", &MyClass::viewMatrix, py::return_value_policy::reference_internal)
|
110 |
+
;
|
111 |
+
|
112 |
+
.. code-block:: python
|
113 |
+
|
114 |
+
a = MyClass()
|
115 |
+
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
|
116 |
+
v = a.view_matrix() # flags.writeable = False, flags.owndata = False
|
117 |
+
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True
|
118 |
+
# m[5,6] and v[5,6] refer to the same element, c[5,6] does not.
|
119 |
+
|
120 |
+
Note in this example that ``py::return_value_policy::reference_internal`` is
|
121 |
+
used to tie the life of the MyClass object to the life of the returned arrays.
|
122 |
+
|
123 |
+
You may also return an ``Eigen::Ref``, ``Eigen::Map`` or other map-like Eigen
|
124 |
+
object (for example, the return value of ``matrix.block()`` and related
|
125 |
+
methods) that map into a dense Eigen type. When doing so, the default
|
126 |
+
behaviour of pybind11 is to simply reference the returned data: you must take
|
127 |
+
care to ensure that this data remains valid! You may ask pybind11 to
|
128 |
+
explicitly *copy* such a return value by using the
|
129 |
+
``py::return_value_policy::copy`` policy when binding the function. You may
|
130 |
+
also use ``py::return_value_policy::reference_internal`` or a
|
131 |
+
``py::keep_alive`` to ensure the data stays valid as long as the returned numpy
|
132 |
+
array does.
|
133 |
+
|
134 |
+
When returning such a reference of map, pybind11 additionally respects the
|
135 |
+
readonly-status of the returned value, marking the numpy array as non-writeable
|
136 |
+
if the reference or map was itself read-only.
|
137 |
+
|
138 |
+
.. note::
|
139 |
+
|
140 |
+
Sparse types are always copied when returned.
|
141 |
+
|
142 |
+
.. _storage_orders:
|
143 |
+
|
144 |
+
Storage orders
|
145 |
+
==============
|
146 |
+
|
147 |
+
Passing arguments via ``Eigen::Ref`` has some limitations that you must be
|
148 |
+
aware of in order to effectively pass matrices by reference. First and
|
149 |
+
foremost is that the default ``Eigen::Ref<MatrixType>`` class requires
|
150 |
+
contiguous storage along columns (for column-major types, the default in Eigen)
|
151 |
+
or rows if ``MatrixType`` is specifically an ``Eigen::RowMajor`` storage type.
|
152 |
+
The former, Eigen's default, is incompatible with ``numpy``'s default row-major
|
153 |
+
storage, and so you will not be able to pass numpy arrays to Eigen by reference
|
154 |
+
without making one of two changes.
|
155 |
+
|
156 |
+
(Note that this does not apply to vectors (or column or row matrices): for such
|
157 |
+
types the "row-major" and "column-major" distinction is meaningless).
|
158 |
+
|
159 |
+
The first approach is to change the use of ``Eigen::Ref<MatrixType>`` to the
|
160 |
+
more general ``Eigen::Ref<MatrixType, 0, Eigen::Stride<Eigen::Dynamic,
|
161 |
+
Eigen::Dynamic>>`` (or similar type with a fully dynamic stride type in the
|
162 |
+
third template argument). Since this is a rather cumbersome type, pybind11
|
163 |
+
provides a ``py::EigenDRef<MatrixType>`` type alias for your convenience (along
|
164 |
+
with EigenDMap for the equivalent Map, and EigenDStride for just the stride
|
165 |
+
type).
|
166 |
+
|
167 |
+
This type allows Eigen to map into any arbitrary storage order. This is not
|
168 |
+
the default in Eigen for performance reasons: contiguous storage allows
|
169 |
+
vectorization that cannot be done when storage is not known to be contiguous at
|
170 |
+
compile time. The default ``Eigen::Ref`` stride type allows non-contiguous
|
171 |
+
storage along the outer dimension (that is, the rows of a column-major matrix
|
172 |
+
or columns of a row-major matrix), but not along the inner dimension.
|
173 |
+
|
174 |
+
This type, however, has the added benefit of also being able to map numpy array
|
175 |
+
slices. For example, the following (contrived) example uses Eigen with a numpy
|
176 |
+
slice to multiply by 2 all coefficients that are both on even rows (0, 2, 4,
|
177 |
+
...) and in columns 2, 5, or 8:
|
178 |
+
|
179 |
+
.. code-block:: cpp
|
180 |
+
|
181 |
+
m.def("scale", [](py::EigenDRef<Eigen::MatrixXd> m, double c) { m *= c; });
|
182 |
+
|
183 |
+
.. code-block:: python
|
184 |
+
|
185 |
+
# a = np.array(...)
|
186 |
+
scale_by_2(myarray[0::2, 2:9:3])
|
187 |
+
|
188 |
+
The second approach to avoid copying is more intrusive: rearranging the
|
189 |
+
underlying data types to not run into the non-contiguous storage problem in the
|
190 |
+
first place. In particular, that means using matrices with ``Eigen::RowMajor``
|
191 |
+
storage, where appropriate, such as:
|
192 |
+
|
193 |
+
.. code-block:: cpp
|
194 |
+
|
195 |
+
using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
196 |
+
// Use RowMatrixXd instead of MatrixXd
|
197 |
+
|
198 |
+
Now bound functions accepting ``Eigen::Ref<RowMatrixXd>`` arguments will be
|
199 |
+
callable with numpy's (default) arrays without involving a copying.
|
200 |
+
|
201 |
+
You can, alternatively, change the storage order that numpy arrays use by
|
202 |
+
adding the ``order='F'`` option when creating an array:
|
203 |
+
|
204 |
+
.. code-block:: python
|
205 |
+
|
206 |
+
myarray = np.array(source, order="F")
|
207 |
+
|
208 |
+
Such an object will be passable to a bound function accepting an
|
209 |
+
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).
|
210 |
+
|
211 |
+
One major caveat with this approach, however, is that it is not entirely as
|
212 |
+
easy as simply flipping all Eigen or numpy usage from one to the other: some
|
213 |
+
operations may alter the storage order of a numpy array. For example, ``a2 =
|
214 |
+
array.transpose()`` results in ``a2`` being a view of ``array`` that references
|
215 |
+
the same data, but in the opposite storage order!
|
216 |
+
|
217 |
+
While this approach allows fully optimized vectorized calculations in Eigen, it
|
218 |
+
cannot be used with array slices, unlike the first approach.
|
219 |
+
|
220 |
+
When *returning* a matrix to Python (either a regular matrix, a reference via
|
221 |
+
``Eigen::Ref<>``, or a map/block into a matrix), no special storage
|
222 |
+
consideration is required: the created numpy array will have the required
|
223 |
+
stride that allows numpy to properly interpret the array, whatever its storage
|
224 |
+
order.
|
225 |
+
|
226 |
+
Failing rather than copying
|
227 |
+
===========================
|
228 |
+
|
229 |
+
The default behaviour when binding ``Eigen::Ref<const MatrixType>`` Eigen
|
230 |
+
references is to copy matrix values when passed a numpy array that does not
|
231 |
+
conform to the element type of ``MatrixType`` or does not have a compatible
|
232 |
+
stride layout. If you want to explicitly avoid copying in such a case, you
|
233 |
+
should bind arguments using the ``py::arg().noconvert()`` annotation (as
|
234 |
+
described in the :ref:`nonconverting_arguments` documentation).
|
235 |
+
|
236 |
+
The following example shows an example of arguments that don't allow data
|
237 |
+
copying to take place:
|
238 |
+
|
239 |
+
.. code-block:: cpp
|
240 |
+
|
241 |
+
// The method and function to be bound:
|
242 |
+
class MyClass {
|
243 |
+
// ...
|
244 |
+
double some_method(const Eigen::Ref<const MatrixXd> &matrix) { /* ... */ }
|
245 |
+
};
|
246 |
+
float some_function(const Eigen::Ref<const MatrixXf> &big,
|
247 |
+
const Eigen::Ref<const MatrixXf> &small) {
|
248 |
+
// ...
|
249 |
+
}
|
250 |
+
|
251 |
+
// The associated binding code:
|
252 |
+
using namespace pybind11::literals; // for "arg"_a
|
253 |
+
py::class_<MyClass>(m, "MyClass")
|
254 |
+
// ... other class definitions
|
255 |
+
.def("some_method", &MyClass::some_method, py::arg().noconvert());
|
256 |
+
|
257 |
+
m.def("some_function", &some_function,
|
258 |
+
"big"_a.noconvert(), // <- Don't allow copying for this arg
|
259 |
+
"small"_a // <- This one can be copied if needed
|
260 |
+
);
|
261 |
+
|
262 |
+
With the above binding code, attempting to call the the ``some_method(m)``
|
263 |
+
method on a ``MyClass`` object, or attempting to call ``some_function(m, m2)``
|
264 |
+
will raise a ``RuntimeError`` rather than making a temporary copy of the array.
|
265 |
+
It will, however, allow the ``m2`` argument to be copied into a temporary if
|
266 |
+
necessary.
|
267 |
+
|
268 |
+
Note that explicitly specifying ``.noconvert()`` is not required for *mutable*
|
269 |
+
Eigen references (e.g. ``Eigen::Ref<MatrixXd>`` without ``const`` on the
|
270 |
+
``MatrixXd``): mutable references will never be called with a temporary copy.
|
271 |
+
|
272 |
+
Vectors versus column/row matrices
|
273 |
+
==================================
|
274 |
+
|
275 |
+
Eigen and numpy have fundamentally different notions of a vector. In Eigen, a
|
276 |
+
vector is simply a matrix with the number of columns or rows set to 1 at
|
277 |
+
compile time (for a column vector or row vector, respectively). NumPy, in
|
278 |
+
contrast, has comparable 2-dimensional 1xN and Nx1 arrays, but *also* has
|
279 |
+
1-dimensional arrays of size N.
|
280 |
+
|
281 |
+
When passing a 2-dimensional 1xN or Nx1 array to Eigen, the Eigen type must
|
282 |
+
have matching dimensions: That is, you cannot pass a 2-dimensional Nx1 numpy
|
283 |
+
array to an Eigen value expecting a row vector, or a 1xN numpy array as a
|
284 |
+
column vector argument.
|
285 |
+
|
286 |
+
On the other hand, pybind11 allows you to pass 1-dimensional arrays of length N
|
287 |
+
as Eigen parameters. If the Eigen type can hold a column vector of length N it
|
288 |
+
will be passed as such a column vector. If not, but the Eigen type constraints
|
289 |
+
will accept a row vector, it will be passed as a row vector. (The column
|
290 |
+
vector takes precedence when both are supported, for example, when passing a
|
291 |
+
1D numpy array to a MatrixXd argument). Note that the type need not be
|
292 |
+
explicitly a vector: it is permitted to pass a 1D numpy array of size 5 to an
|
293 |
+
Eigen ``Matrix<double, Dynamic, 5>``: you would end up with a 1x5 Eigen matrix.
|
294 |
+
Passing the same to an ``Eigen::MatrixXd`` would result in a 5x1 Eigen matrix.
|
295 |
+
|
296 |
+
When returning an Eigen vector to numpy, the conversion is ambiguous: a row
|
297 |
+
vector of length 4 could be returned as either a 1D array of length 4, or as a
|
298 |
+
2D array of size 1x4. When encountering such a situation, pybind11 compromises
|
299 |
+
by considering the returned Eigen type: if it is a compile-time vector--that
|
300 |
+
is, the type has either the number of rows or columns set to 1 at compile
|
301 |
+
time--pybind11 converts to a 1D numpy array when returning the value. For
|
302 |
+
instances that are a vector only at run-time (e.g. ``MatrixXd``,
|
303 |
+
``Matrix<float, Dynamic, 4>``), pybind11 returns the vector as a 2D array to
|
304 |
+
numpy. If this isn't want you want, you can use ``array.reshape(...)`` to get
|
305 |
+
a view of the same data in the desired dimensions.
|
306 |
+
|
307 |
+
.. seealso::
|
308 |
+
|
309 |
+
The file :file:`tests/test_eigen.cpp` contains a complete example that
|
310 |
+
shows how to pass Eigen sparse and dense data types in more detail.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/functional.rst
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Functional
|
2 |
+
##########
|
3 |
+
|
4 |
+
The following features must be enabled by including :file:`pybind11/functional.h`.
|
5 |
+
|
6 |
+
|
7 |
+
Callbacks and passing anonymous functions
|
8 |
+
=========================================
|
9 |
+
|
10 |
+
The C++11 standard brought lambda functions and the generic polymorphic
|
11 |
+
function wrapper ``std::function<>`` to the C++ programming language, which
|
12 |
+
enable powerful new ways of working with functions. Lambda functions come in
|
13 |
+
two flavors: stateless lambda function resemble classic function pointers that
|
14 |
+
link to an anonymous piece of code, while stateful lambda functions
|
15 |
+
additionally depend on captured variables that are stored in an anonymous
|
16 |
+
*lambda closure object*.
|
17 |
+
|
18 |
+
Here is a simple example of a C++ function that takes an arbitrary function
|
19 |
+
(stateful or stateless) with signature ``int -> int`` as an argument and runs
|
20 |
+
it with the value 10.
|
21 |
+
|
22 |
+
.. code-block:: cpp
|
23 |
+
|
24 |
+
int func_arg(const std::function<int(int)> &f) {
|
25 |
+
return f(10);
|
26 |
+
}
|
27 |
+
|
28 |
+
The example below is more involved: it takes a function of signature ``int -> int``
|
29 |
+
and returns another function of the same kind. The return value is a stateful
|
30 |
+
lambda function, which stores the value ``f`` in the capture object and adds 1 to
|
31 |
+
its return value upon execution.
|
32 |
+
|
33 |
+
.. code-block:: cpp
|
34 |
+
|
35 |
+
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
|
36 |
+
return [f](int i) {
|
37 |
+
return f(i) + 1;
|
38 |
+
};
|
39 |
+
}
|
40 |
+
|
41 |
+
This example demonstrates using python named parameters in C++ callbacks which
|
42 |
+
requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
|
43 |
+
methods of classes:
|
44 |
+
|
45 |
+
.. code-block:: cpp
|
46 |
+
|
47 |
+
py::cpp_function func_cpp() {
|
48 |
+
return py::cpp_function([](int i) { return i+1; },
|
49 |
+
py::arg("number"));
|
50 |
+
}
|
51 |
+
|
52 |
+
After including the extra header file :file:`pybind11/functional.h`, it is almost
|
53 |
+
trivial to generate binding code for all of these functions.
|
54 |
+
|
55 |
+
.. code-block:: cpp
|
56 |
+
|
57 |
+
#include <pybind11/functional.h>
|
58 |
+
|
59 |
+
PYBIND11_MODULE(example, m) {
|
60 |
+
m.def("func_arg", &func_arg);
|
61 |
+
m.def("func_ret", &func_ret);
|
62 |
+
m.def("func_cpp", &func_cpp);
|
63 |
+
}
|
64 |
+
|
65 |
+
The following interactive session shows how to call them from Python.
|
66 |
+
|
67 |
+
.. code-block:: pycon
|
68 |
+
|
69 |
+
$ python
|
70 |
+
>>> import example
|
71 |
+
>>> def square(i):
|
72 |
+
... return i * i
|
73 |
+
...
|
74 |
+
>>> example.func_arg(square)
|
75 |
+
100L
|
76 |
+
>>> square_plus_1 = example.func_ret(square)
|
77 |
+
>>> square_plus_1(4)
|
78 |
+
17L
|
79 |
+
>>> plus_1 = func_cpp()
|
80 |
+
>>> plus_1(number=43)
|
81 |
+
44L
|
82 |
+
|
83 |
+
.. warning::
|
84 |
+
|
85 |
+
Keep in mind that passing a function from C++ to Python (or vice versa)
|
86 |
+
will instantiate a piece of wrapper code that translates function
|
87 |
+
invocations between the two languages. Naturally, this translation
|
88 |
+
increases the computational cost of each function call somewhat. A
|
89 |
+
problematic situation can arise when a function is copied back and forth
|
90 |
+
between Python and C++ many times in a row, in which case the underlying
|
91 |
+
wrappers will accumulate correspondingly. The resulting long sequence of
|
92 |
+
C++ -> Python -> C++ -> ... roundtrips can significantly decrease
|
93 |
+
performance.
|
94 |
+
|
95 |
+
There is one exception: pybind11 detects case where a stateless function
|
96 |
+
(i.e. a function pointer or a lambda function without captured variables)
|
97 |
+
is passed as an argument to another C++ function exposed in Python. In this
|
98 |
+
case, there is no overhead. Pybind11 will extract the underlying C++
|
99 |
+
function pointer from the wrapped function to sidestep a potential C++ ->
|
100 |
+
Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
|
101 |
+
|
102 |
+
.. note::
|
103 |
+
|
104 |
+
This functionality is very useful when generating bindings for callbacks in
|
105 |
+
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
|
106 |
+
|
107 |
+
The file :file:`tests/test_callbacks.cpp` contains a complete example
|
108 |
+
that demonstrates how to work with callbacks and anonymous functions in
|
109 |
+
more detail.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/index.rst
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.. _type-conversions:
|
2 |
+
|
3 |
+
Type conversions
|
4 |
+
################
|
5 |
+
|
6 |
+
Apart from enabling cross-language function calls, a fundamental problem
|
7 |
+
that a binding tool like pybind11 must address is to provide access to
|
8 |
+
native Python types in C++ and vice versa. There are three fundamentally
|
9 |
+
different ways to do this—which approach is preferable for a particular type
|
10 |
+
depends on the situation at hand.
|
11 |
+
|
12 |
+
1. Use a native C++ type everywhere. In this case, the type must be wrapped
|
13 |
+
using pybind11-generated bindings so that Python can interact with it.
|
14 |
+
|
15 |
+
2. Use a native Python type everywhere. It will need to be wrapped so that
|
16 |
+
C++ functions can interact with it.
|
17 |
+
|
18 |
+
3. Use a native C++ type on the C++ side and a native Python type on the
|
19 |
+
Python side. pybind11 refers to this as a *type conversion*.
|
20 |
+
|
21 |
+
Type conversions are the most "natural" option in the sense that native
|
22 |
+
(non-wrapped) types are used everywhere. The main downside is that a copy
|
23 |
+
of the data must be made on every Python ↔ C++ transition: this is
|
24 |
+
needed since the C++ and Python versions of the same type generally won't
|
25 |
+
have the same memory layout.
|
26 |
+
|
27 |
+
pybind11 can perform many kinds of conversions automatically. An overview
|
28 |
+
is provided in the table ":ref:`conversion_table`".
|
29 |
+
|
30 |
+
The following subsections discuss the differences between these options in more
|
31 |
+
detail. The main focus in this section is on type conversions, which represent
|
32 |
+
the last case of the above list.
|
33 |
+
|
34 |
+
.. toctree::
|
35 |
+
:maxdepth: 1
|
36 |
+
|
37 |
+
overview
|
38 |
+
strings
|
39 |
+
stl
|
40 |
+
functional
|
41 |
+
chrono
|
42 |
+
eigen
|
43 |
+
custom
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/overview.rst
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Overview
|
2 |
+
########
|
3 |
+
|
4 |
+
.. rubric:: 1. Native type in C++, wrapper in Python
|
5 |
+
|
6 |
+
Exposing a custom C++ type using :class:`py::class_` was covered in detail
|
7 |
+
in the :doc:`/classes` section. There, the underlying data structure is
|
8 |
+
always the original C++ class while the :class:`py::class_` wrapper provides
|
9 |
+
a Python interface. Internally, when an object like this is sent from C++ to
|
10 |
+
Python, pybind11 will just add the outer wrapper layer over the native C++
|
11 |
+
object. Getting it back from Python is just a matter of peeling off the
|
12 |
+
wrapper.
|
13 |
+
|
14 |
+
.. rubric:: 2. Wrapper in C++, native type in Python
|
15 |
+
|
16 |
+
This is the exact opposite situation. Now, we have a type which is native to
|
17 |
+
Python, like a ``tuple`` or a ``list``. One way to get this data into C++ is
|
18 |
+
with the :class:`py::object` family of wrappers. These are explained in more
|
19 |
+
detail in the :doc:`/advanced/pycpp/object` section. We'll just give a quick
|
20 |
+
example here:
|
21 |
+
|
22 |
+
.. code-block:: cpp
|
23 |
+
|
24 |
+
void print_list(py::list my_list) {
|
25 |
+
for (auto item : my_list)
|
26 |
+
std::cout << item << " ";
|
27 |
+
}
|
28 |
+
|
29 |
+
.. code-block:: pycon
|
30 |
+
|
31 |
+
>>> print_list([1, 2, 3])
|
32 |
+
1 2 3
|
33 |
+
|
34 |
+
The Python ``list`` is not converted in any way -- it's just wrapped in a C++
|
35 |
+
:class:`py::list` class. At its core it's still a Python object. Copying a
|
36 |
+
:class:`py::list` will do the usual reference-counting like in Python.
|
37 |
+
Returning the object to Python will just remove the thin wrapper.
|
38 |
+
|
39 |
+
.. rubric:: 3. Converting between native C++ and Python types
|
40 |
+
|
41 |
+
In the previous two cases we had a native type in one language and a wrapper in
|
42 |
+
the other. Now, we have native types on both sides and we convert between them.
|
43 |
+
|
44 |
+
.. code-block:: cpp
|
45 |
+
|
46 |
+
void print_vector(const std::vector<int> &v) {
|
47 |
+
for (auto item : v)
|
48 |
+
std::cout << item << "\n";
|
49 |
+
}
|
50 |
+
|
51 |
+
.. code-block:: pycon
|
52 |
+
|
53 |
+
>>> print_vector([1, 2, 3])
|
54 |
+
1 2 3
|
55 |
+
|
56 |
+
In this case, pybind11 will construct a new ``std::vector<int>`` and copy each
|
57 |
+
element from the Python ``list``. The newly constructed object will be passed
|
58 |
+
to ``print_vector``. The same thing happens in the other direction: a new
|
59 |
+
``list`` is made to match the value returned from C++.
|
60 |
+
|
61 |
+
Lots of these conversions are supported out of the box, as shown in the table
|
62 |
+
below. They are very convenient, but keep in mind that these conversions are
|
63 |
+
fundamentally based on copying data. This is perfectly fine for small immutable
|
64 |
+
types but it may become quite expensive for large data structures. This can be
|
65 |
+
avoided by overriding the automatic conversion with a custom wrapper (i.e. the
|
66 |
+
above-mentioned approach 1). This requires some manual effort and more details
|
67 |
+
are available in the :ref:`opaque` section.
|
68 |
+
|
69 |
+
.. _conversion_table:
|
70 |
+
|
71 |
+
List of all builtin conversions
|
72 |
+
-------------------------------
|
73 |
+
|
74 |
+
The following basic data types are supported out of the box (some may require
|
75 |
+
an additional extension header to be included). To pass other data structures
|
76 |
+
as arguments and return values, refer to the section on binding :ref:`classes`.
|
77 |
+
|
78 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
79 |
+
| Data type | Description | Header file |
|
80 |
+
+====================================+===========================+===================================+
|
81 |
+
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
|
82 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
83 |
+
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
|
84 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
85 |
+
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
|
86 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
87 |
+
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
|
88 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
89 |
+
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
|
90 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
91 |
+
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
|
92 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
93 |
+
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
|
94 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
95 |
+
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
|
96 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
97 |
+
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
|
98 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
99 |
+
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
|
100 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
101 |
+
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
|
102 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
103 |
+
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
|
104 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
105 |
+
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
|
106 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
107 |
+
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
|
108 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
109 |
+
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
|
110 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
111 |
+
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
|
112 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
113 |
+
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
|
114 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
115 |
+
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
|
116 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
117 |
+
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
|
118 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
119 |
+
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
|
120 |
+
| ``std::u16string_view``, etc. | | |
|
121 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
122 |
+
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
|
123 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
124 |
+
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
|
125 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
126 |
+
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
|
127 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
128 |
+
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
|
129 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
130 |
+
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
|
131 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
132 |
+
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
|
133 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
134 |
+
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
|
135 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
136 |
+
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
|
137 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
138 |
+
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
|
139 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
140 |
+
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
|
141 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
142 |
+
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
|
143 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
144 |
+
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
|
145 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
146 |
+
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
|
147 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
148 |
+
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
|
149 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
150 |
+
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
|
151 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
152 |
+
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
|
153 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
154 |
+
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl/filesystem.h` |
|
155 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
156 |
+
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
|
157 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
158 |
+
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
|
159 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
160 |
+
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
|
161 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
162 |
+
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
|
163 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
164 |
+
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
|
165 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
166 |
+
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
|
167 |
+
+------------------------------------+---------------------------+-----------------------------------+
|
168 |
+
|
169 |
+
.. [#] ``std::filesystem::path`` is converted to ``pathlib.Path`` and
|
170 |
+
``os.PathLike`` is converted to ``std::filesystem::path``, but this requires
|
171 |
+
Python 3.6 (for ``__fspath__`` support).
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/stl.rst
ADDED
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
STL containers
|
2 |
+
##############
|
3 |
+
|
4 |
+
Automatic conversion
|
5 |
+
====================
|
6 |
+
|
7 |
+
When including the additional header file :file:`pybind11/stl.h`, conversions
|
8 |
+
between ``std::vector<>``/``std::deque<>``/``std::list<>``/``std::array<>``/``std::valarray<>``,
|
9 |
+
``std::set<>``/``std::unordered_set<>``, and
|
10 |
+
``std::map<>``/``std::unordered_map<>`` and the Python ``list``, ``set`` and
|
11 |
+
``dict`` data structures are automatically enabled. The types ``std::pair<>``
|
12 |
+
and ``std::tuple<>`` are already supported out of the box with just the core
|
13 |
+
:file:`pybind11/pybind11.h` header.
|
14 |
+
|
15 |
+
The major downside of these implicit conversions is that containers must be
|
16 |
+
converted (i.e. copied) on every Python->C++ and C++->Python transition, which
|
17 |
+
can have implications on the program semantics and performance. Please read the
|
18 |
+
next sections for more details and alternative approaches that avoid this.
|
19 |
+
|
20 |
+
.. note::
|
21 |
+
|
22 |
+
Arbitrary nesting of any of these types is possible.
|
23 |
+
|
24 |
+
.. seealso::
|
25 |
+
|
26 |
+
The file :file:`tests/test_stl.cpp` contains a complete
|
27 |
+
example that demonstrates how to pass STL data types in more detail.
|
28 |
+
|
29 |
+
.. _cpp17_container_casters:
|
30 |
+
|
31 |
+
C++17 library containers
|
32 |
+
========================
|
33 |
+
|
34 |
+
The :file:`pybind11/stl.h` header also includes support for ``std::optional<>``
|
35 |
+
and ``std::variant<>``. These require a C++17 compiler and standard library.
|
36 |
+
In C++14 mode, ``std::experimental::optional<>`` is supported if available.
|
37 |
+
|
38 |
+
Various versions of these containers also exist for C++11 (e.g. in Boost).
|
39 |
+
pybind11 provides an easy way to specialize the ``type_caster`` for such
|
40 |
+
types:
|
41 |
+
|
42 |
+
.. code-block:: cpp
|
43 |
+
|
44 |
+
// `boost::optional` as an example -- can be any `std::optional`-like container
|
45 |
+
namespace pybind11 { namespace detail {
|
46 |
+
template <typename T>
|
47 |
+
struct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};
|
48 |
+
}}
|
49 |
+
|
50 |
+
The above should be placed in a header file and included in all translation units
|
51 |
+
where automatic conversion is needed. Similarly, a specialization can be provided
|
52 |
+
for custom variant types:
|
53 |
+
|
54 |
+
.. code-block:: cpp
|
55 |
+
|
56 |
+
// `boost::variant` as an example -- can be any `std::variant`-like container
|
57 |
+
namespace pybind11 { namespace detail {
|
58 |
+
template <typename... Ts>
|
59 |
+
struct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};
|
60 |
+
|
61 |
+
// Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
|
62 |
+
template <>
|
63 |
+
struct visit_helper<boost::variant> {
|
64 |
+
template <typename... Args>
|
65 |
+
static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {
|
66 |
+
return boost::apply_visitor(args...);
|
67 |
+
}
|
68 |
+
};
|
69 |
+
}} // namespace pybind11::detail
|
70 |
+
|
71 |
+
The ``visit_helper`` specialization is not required if your ``name::variant`` provides
|
72 |
+
a ``name::visit()`` function. For any other function name, the specialization must be
|
73 |
+
included to tell pybind11 how to visit the variant.
|
74 |
+
|
75 |
+
.. warning::
|
76 |
+
|
77 |
+
When converting a ``variant`` type, pybind11 follows the same rules as when
|
78 |
+
determining which function overload to call (:ref:`overload_resolution`), and
|
79 |
+
so the same caveats hold. In particular, the order in which the ``variant``'s
|
80 |
+
alternatives are listed is important, since pybind11 will try conversions in
|
81 |
+
this order. This means that, for example, when converting ``variant<int, bool>``,
|
82 |
+
the ``bool`` variant will never be selected, as any Python ``bool`` is already
|
83 |
+
an ``int`` and is convertible to a C++ ``int``. Changing the order of alternatives
|
84 |
+
(and using ``variant<bool, int>``, in this example) provides a solution.
|
85 |
+
|
86 |
+
.. note::
|
87 |
+
|
88 |
+
pybind11 only supports the modern implementation of ``boost::variant``
|
89 |
+
which makes use of variadic templates. This requires Boost 1.56 or newer.
|
90 |
+
Additionally, on Windows, MSVC 2017 is required because ``boost::variant``
|
91 |
+
falls back to the old non-variadic implementation on MSVC 2015.
|
92 |
+
|
93 |
+
.. _opaque:
|
94 |
+
|
95 |
+
Making opaque types
|
96 |
+
===================
|
97 |
+
|
98 |
+
pybind11 heavily relies on a template matching mechanism to convert parameters
|
99 |
+
and return values that are constructed from STL data types such as vectors,
|
100 |
+
linked lists, hash tables, etc. This even works in a recursive manner, for
|
101 |
+
instance to deal with lists of hash maps of pairs of elementary and custom
|
102 |
+
types, etc.
|
103 |
+
|
104 |
+
However, a fundamental limitation of this approach is that internal conversions
|
105 |
+
between Python and C++ types involve a copy operation that prevents
|
106 |
+
pass-by-reference semantics. What does this mean?
|
107 |
+
|
108 |
+
Suppose we bind the following function
|
109 |
+
|
110 |
+
.. code-block:: cpp
|
111 |
+
|
112 |
+
void append_1(std::vector<int> &v) {
|
113 |
+
v.push_back(1);
|
114 |
+
}
|
115 |
+
|
116 |
+
and call it from Python, the following happens:
|
117 |
+
|
118 |
+
.. code-block:: pycon
|
119 |
+
|
120 |
+
>>> v = [5, 6]
|
121 |
+
>>> append_1(v)
|
122 |
+
>>> print(v)
|
123 |
+
[5, 6]
|
124 |
+
|
125 |
+
As you can see, when passing STL data structures by reference, modifications
|
126 |
+
are not propagated back the Python side. A similar situation arises when
|
127 |
+
exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
|
128 |
+
functions:
|
129 |
+
|
130 |
+
.. code-block:: cpp
|
131 |
+
|
132 |
+
/* ... definition ... */
|
133 |
+
|
134 |
+
class MyClass {
|
135 |
+
std::vector<int> contents;
|
136 |
+
};
|
137 |
+
|
138 |
+
/* ... binding code ... */
|
139 |
+
|
140 |
+
py::class_<MyClass>(m, "MyClass")
|
141 |
+
.def(py::init<>())
|
142 |
+
.def_readwrite("contents", &MyClass::contents);
|
143 |
+
|
144 |
+
In this case, properties can be read and written in their entirety. However, an
|
145 |
+
``append`` operation involving such a list type has no effect:
|
146 |
+
|
147 |
+
.. code-block:: pycon
|
148 |
+
|
149 |
+
>>> m = MyClass()
|
150 |
+
>>> m.contents = [5, 6]
|
151 |
+
>>> print(m.contents)
|
152 |
+
[5, 6]
|
153 |
+
>>> m.contents.append(7)
|
154 |
+
>>> print(m.contents)
|
155 |
+
[5, 6]
|
156 |
+
|
157 |
+
Finally, the involved copy operations can be costly when dealing with very
|
158 |
+
large lists. To deal with all of the above situations, pybind11 provides a
|
159 |
+
macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based
|
160 |
+
conversion machinery of types, thus rendering them *opaque*. The contents of
|
161 |
+
opaque objects are never inspected or extracted, hence they *can* be passed by
|
162 |
+
reference. For instance, to turn ``std::vector<int>`` into an opaque type, add
|
163 |
+
the declaration
|
164 |
+
|
165 |
+
.. code-block:: cpp
|
166 |
+
|
167 |
+
PYBIND11_MAKE_OPAQUE(std::vector<int>);
|
168 |
+
|
169 |
+
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
|
170 |
+
macro must be specified at the top level (and outside of any namespaces), since
|
171 |
+
it adds a template instantiation of ``type_caster``. If your binding code consists of
|
172 |
+
multiple compilation units, it must be present in every file (typically via a
|
173 |
+
common header) preceding any usage of ``std::vector<int>``. Opaque types must
|
174 |
+
also have a corresponding ``class_`` declaration to associate them with a name
|
175 |
+
in Python, and to define a set of available operations, e.g.:
|
176 |
+
|
177 |
+
.. code-block:: cpp
|
178 |
+
|
179 |
+
py::class_<std::vector<int>>(m, "IntVector")
|
180 |
+
.def(py::init<>())
|
181 |
+
.def("clear", &std::vector<int>::clear)
|
182 |
+
.def("pop_back", &std::vector<int>::pop_back)
|
183 |
+
.def("__len__", [](const std::vector<int> &v) { return v.size(); })
|
184 |
+
.def("__iter__", [](std::vector<int> &v) {
|
185 |
+
return py::make_iterator(v.begin(), v.end());
|
186 |
+
}, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
|
187 |
+
// ....
|
188 |
+
|
189 |
+
.. seealso::
|
190 |
+
|
191 |
+
The file :file:`tests/test_opaque_types.cpp` contains a complete
|
192 |
+
example that demonstrates how to create and expose opaque types using
|
193 |
+
pybind11 in more detail.
|
194 |
+
|
195 |
+
.. _stl_bind:
|
196 |
+
|
197 |
+
Binding STL containers
|
198 |
+
======================
|
199 |
+
|
200 |
+
The ability to expose STL containers as native Python objects is a fairly
|
201 |
+
common request, hence pybind11 also provides an optional header file named
|
202 |
+
:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try
|
203 |
+
to match the behavior of their native Python counterparts as much as possible.
|
204 |
+
|
205 |
+
The following example showcases usage of :file:`pybind11/stl_bind.h`:
|
206 |
+
|
207 |
+
.. code-block:: cpp
|
208 |
+
|
209 |
+
// Don't forget this
|
210 |
+
#include <pybind11/stl_bind.h>
|
211 |
+
|
212 |
+
PYBIND11_MAKE_OPAQUE(std::vector<int>);
|
213 |
+
PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
|
214 |
+
|
215 |
+
// ...
|
216 |
+
|
217 |
+
// later in binding code:
|
218 |
+
py::bind_vector<std::vector<int>>(m, "VectorInt");
|
219 |
+
py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
|
220 |
+
|
221 |
+
When binding STL containers pybind11 considers the types of the container's
|
222 |
+
elements to decide whether the container should be confined to the local module
|
223 |
+
(via the :ref:`module_local` feature). If the container element types are
|
224 |
+
anything other than already-bound custom types bound without
|
225 |
+
``py::module_local()`` the container binding will have ``py::module_local()``
|
226 |
+
applied. This includes converting types such as numeric types, strings, Eigen
|
227 |
+
types; and types that have not yet been bound at the time of the stl container
|
228 |
+
binding. This module-local binding is designed to avoid potential conflicts
|
229 |
+
between module bindings (for example, from two separate modules each attempting
|
230 |
+
to bind ``std::vector<int>`` as a python type).
|
231 |
+
|
232 |
+
It is possible to override this behavior to force a definition to be either
|
233 |
+
module-local or global. To do so, you can pass the attributes
|
234 |
+
``py::module_local()`` (to make the binding module-local) or
|
235 |
+
``py::module_local(false)`` (to make the binding global) into the
|
236 |
+
``py::bind_vector`` or ``py::bind_map`` arguments:
|
237 |
+
|
238 |
+
.. code-block:: cpp
|
239 |
+
|
240 |
+
py::bind_vector<std::vector<int>>(m, "VectorInt", py::module_local(false));
|
241 |
+
|
242 |
+
Note, however, that such a global binding would make it impossible to load this
|
243 |
+
module at the same time as any other pybind module that also attempts to bind
|
244 |
+
the same container type (``std::vector<int>`` in the above example).
|
245 |
+
|
246 |
+
See :ref:`module_local` for more details on module-local bindings.
|
247 |
+
|
248 |
+
.. seealso::
|
249 |
+
|
250 |
+
The file :file:`tests/test_stl_binders.cpp` shows how to use the
|
251 |
+
convenience STL container wrappers.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/cast/strings.rst
ADDED
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Strings, bytes and Unicode conversions
|
2 |
+
######################################
|
3 |
+
|
4 |
+
.. note::
|
5 |
+
|
6 |
+
This section discusses string handling in terms of Python 3 strings. For
|
7 |
+
Python 2.7, replace all occurrences of ``str`` with ``unicode`` and
|
8 |
+
``bytes`` with ``str``. Python 2.7 users may find it best to use ``from
|
9 |
+
__future__ import unicode_literals`` to avoid unintentionally using ``str``
|
10 |
+
instead of ``unicode``.
|
11 |
+
|
12 |
+
Passing Python strings to C++
|
13 |
+
=============================
|
14 |
+
|
15 |
+
When a Python ``str`` is passed from Python to a C++ function that accepts
|
16 |
+
``std::string`` or ``char *`` as arguments, pybind11 will encode the Python
|
17 |
+
string to UTF-8. All Python ``str`` can be encoded in UTF-8, so this operation
|
18 |
+
does not fail.
|
19 |
+
|
20 |
+
The C++ language is encoding agnostic. It is the responsibility of the
|
21 |
+
programmer to track encodings. It's often easiest to simply `use UTF-8
|
22 |
+
everywhere <http://utf8everywhere.org/>`_.
|
23 |
+
|
24 |
+
.. code-block:: c++
|
25 |
+
|
26 |
+
m.def("utf8_test",
|
27 |
+
[](const std::string &s) {
|
28 |
+
cout << "utf-8 is icing on the cake.\n";
|
29 |
+
cout << s;
|
30 |
+
}
|
31 |
+
);
|
32 |
+
m.def("utf8_charptr",
|
33 |
+
[](const char *s) {
|
34 |
+
cout << "My favorite food is\n";
|
35 |
+
cout << s;
|
36 |
+
}
|
37 |
+
);
|
38 |
+
|
39 |
+
.. code-block:: pycon
|
40 |
+
|
41 |
+
>>> utf8_test("🎂")
|
42 |
+
utf-8 is icing on the cake.
|
43 |
+
🎂
|
44 |
+
|
45 |
+
>>> utf8_charptr("🍕")
|
46 |
+
My favorite food is
|
47 |
+
🍕
|
48 |
+
|
49 |
+
.. note::
|
50 |
+
|
51 |
+
Some terminal emulators do not support UTF-8 or emoji fonts and may not
|
52 |
+
display the example above correctly.
|
53 |
+
|
54 |
+
The results are the same whether the C++ function accepts arguments by value or
|
55 |
+
reference, and whether or not ``const`` is used.
|
56 |
+
|
57 |
+
Passing bytes to C++
|
58 |
+
--------------------
|
59 |
+
|
60 |
+
A Python ``bytes`` object will be passed to C++ functions that accept
|
61 |
+
``std::string`` or ``char*`` *without* conversion. On Python 3, in order to
|
62 |
+
make a function *only* accept ``bytes`` (and not ``str``), declare it as taking
|
63 |
+
a ``py::bytes`` argument.
|
64 |
+
|
65 |
+
|
66 |
+
Returning C++ strings to Python
|
67 |
+
===============================
|
68 |
+
|
69 |
+
When a C++ function returns a ``std::string`` or ``char*`` to a Python caller,
|
70 |
+
**pybind11 will assume that the string is valid UTF-8** and will decode it to a
|
71 |
+
native Python ``str``, using the same API as Python uses to perform
|
72 |
+
``bytes.decode('utf-8')``. If this implicit conversion fails, pybind11 will
|
73 |
+
raise a ``UnicodeDecodeError``.
|
74 |
+
|
75 |
+
.. code-block:: c++
|
76 |
+
|
77 |
+
m.def("std_string_return",
|
78 |
+
[]() {
|
79 |
+
return std::string("This string needs to be UTF-8 encoded");
|
80 |
+
}
|
81 |
+
);
|
82 |
+
|
83 |
+
.. code-block:: pycon
|
84 |
+
|
85 |
+
>>> isinstance(example.std_string_return(), str)
|
86 |
+
True
|
87 |
+
|
88 |
+
|
89 |
+
Because UTF-8 is inclusive of pure ASCII, there is never any issue with
|
90 |
+
returning a pure ASCII string to Python. If there is any possibility that the
|
91 |
+
string is not pure ASCII, it is necessary to ensure the encoding is valid
|
92 |
+
UTF-8.
|
93 |
+
|
94 |
+
.. warning::
|
95 |
+
|
96 |
+
Implicit conversion assumes that a returned ``char *`` is null-terminated.
|
97 |
+
If there is no null terminator a buffer overrun will occur.
|
98 |
+
|
99 |
+
Explicit conversions
|
100 |
+
--------------------
|
101 |
+
|
102 |
+
If some C++ code constructs a ``std::string`` that is not a UTF-8 string, one
|
103 |
+
can perform a explicit conversion and return a ``py::str`` object. Explicit
|
104 |
+
conversion has the same overhead as implicit conversion.
|
105 |
+
|
106 |
+
.. code-block:: c++
|
107 |
+
|
108 |
+
// This uses the Python C API to convert Latin-1 to Unicode
|
109 |
+
m.def("str_output",
|
110 |
+
[]() {
|
111 |
+
std::string s = "Send your r\xe9sum\xe9 to Alice in HR"; // Latin-1
|
112 |
+
py::str py_s = PyUnicode_DecodeLatin1(s.data(), s.length());
|
113 |
+
return py_s;
|
114 |
+
}
|
115 |
+
);
|
116 |
+
|
117 |
+
.. code-block:: pycon
|
118 |
+
|
119 |
+
>>> str_output()
|
120 |
+
'Send your résumé to Alice in HR'
|
121 |
+
|
122 |
+
The `Python C API
|
123 |
+
<https://docs.python.org/3/c-api/unicode.html#built-in-codecs>`_ provides
|
124 |
+
several built-in codecs.
|
125 |
+
|
126 |
+
|
127 |
+
One could also use a third party encoding library such as libiconv to transcode
|
128 |
+
to UTF-8.
|
129 |
+
|
130 |
+
Return C++ strings without conversion
|
131 |
+
-------------------------------------
|
132 |
+
|
133 |
+
If the data in a C++ ``std::string`` does not represent text and should be
|
134 |
+
returned to Python as ``bytes``, then one can return the data as a
|
135 |
+
``py::bytes`` object.
|
136 |
+
|
137 |
+
.. code-block:: c++
|
138 |
+
|
139 |
+
m.def("return_bytes",
|
140 |
+
[]() {
|
141 |
+
std::string s("\xba\xd0\xba\xd0"); // Not valid UTF-8
|
142 |
+
return py::bytes(s); // Return the data without transcoding
|
143 |
+
}
|
144 |
+
);
|
145 |
+
|
146 |
+
.. code-block:: pycon
|
147 |
+
|
148 |
+
>>> example.return_bytes()
|
149 |
+
b'\xba\xd0\xba\xd0'
|
150 |
+
|
151 |
+
|
152 |
+
Note the asymmetry: pybind11 will convert ``bytes`` to ``std::string`` without
|
153 |
+
encoding, but cannot convert ``std::string`` back to ``bytes`` implicitly.
|
154 |
+
|
155 |
+
.. code-block:: c++
|
156 |
+
|
157 |
+
m.def("asymmetry",
|
158 |
+
[](std::string s) { // Accepts str or bytes from Python
|
159 |
+
return s; // Looks harmless, but implicitly converts to str
|
160 |
+
}
|
161 |
+
);
|
162 |
+
|
163 |
+
.. code-block:: pycon
|
164 |
+
|
165 |
+
>>> isinstance(example.asymmetry(b"have some bytes"), str)
|
166 |
+
True
|
167 |
+
|
168 |
+
>>> example.asymmetry(b"\xba\xd0\xba\xd0") # invalid utf-8 as bytes
|
169 |
+
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xba in position 0: invalid start byte
|
170 |
+
|
171 |
+
|
172 |
+
Wide character strings
|
173 |
+
======================
|
174 |
+
|
175 |
+
When a Python ``str`` is passed to a C++ function expecting ``std::wstring``,
|
176 |
+
``wchar_t*``, ``std::u16string`` or ``std::u32string``, the ``str`` will be
|
177 |
+
encoded to UTF-16 or UTF-32 depending on how the C++ compiler implements each
|
178 |
+
type, in the platform's native endianness. When strings of these types are
|
179 |
+
returned, they are assumed to contain valid UTF-16 or UTF-32, and will be
|
180 |
+
decoded to Python ``str``.
|
181 |
+
|
182 |
+
.. code-block:: c++
|
183 |
+
|
184 |
+
#define UNICODE
|
185 |
+
#include <windows.h>
|
186 |
+
|
187 |
+
m.def("set_window_text",
|
188 |
+
[](HWND hwnd, std::wstring s) {
|
189 |
+
// Call SetWindowText with null-terminated UTF-16 string
|
190 |
+
::SetWindowText(hwnd, s.c_str());
|
191 |
+
}
|
192 |
+
);
|
193 |
+
m.def("get_window_text",
|
194 |
+
[](HWND hwnd) {
|
195 |
+
const int buffer_size = ::GetWindowTextLength(hwnd) + 1;
|
196 |
+
auto buffer = std::make_unique< wchar_t[] >(buffer_size);
|
197 |
+
|
198 |
+
::GetWindowText(hwnd, buffer.data(), buffer_size);
|
199 |
+
|
200 |
+
std::wstring text(buffer.get());
|
201 |
+
|
202 |
+
// wstring will be converted to Python str
|
203 |
+
return text;
|
204 |
+
}
|
205 |
+
);
|
206 |
+
|
207 |
+
.. warning::
|
208 |
+
|
209 |
+
Wide character strings may not work as described on Python 2.7 or Python
|
210 |
+
3.3 compiled with ``--enable-unicode=ucs2``.
|
211 |
+
|
212 |
+
Strings in multibyte encodings such as Shift-JIS must transcoded to a
|
213 |
+
UTF-8/16/32 before being returned to Python.
|
214 |
+
|
215 |
+
|
216 |
+
Character literals
|
217 |
+
==================
|
218 |
+
|
219 |
+
C++ functions that accept character literals as input will receive the first
|
220 |
+
character of a Python ``str`` as their input. If the string is longer than one
|
221 |
+
Unicode character, trailing characters will be ignored.
|
222 |
+
|
223 |
+
When a character literal is returned from C++ (such as a ``char`` or a
|
224 |
+
``wchar_t``), it will be converted to a ``str`` that represents the single
|
225 |
+
character.
|
226 |
+
|
227 |
+
.. code-block:: c++
|
228 |
+
|
229 |
+
m.def("pass_char", [](char c) { return c; });
|
230 |
+
m.def("pass_wchar", [](wchar_t w) { return w; });
|
231 |
+
|
232 |
+
.. code-block:: pycon
|
233 |
+
|
234 |
+
>>> example.pass_char("A")
|
235 |
+
'A'
|
236 |
+
|
237 |
+
While C++ will cast integers to character types (``char c = 0x65;``), pybind11
|
238 |
+
does not convert Python integers to characters implicitly. The Python function
|
239 |
+
``chr()`` can be used to convert integers to characters.
|
240 |
+
|
241 |
+
.. code-block:: pycon
|
242 |
+
|
243 |
+
>>> example.pass_char(0x65)
|
244 |
+
TypeError
|
245 |
+
|
246 |
+
>>> example.pass_char(chr(0x65))
|
247 |
+
'A'
|
248 |
+
|
249 |
+
If the desire is to work with an 8-bit integer, use ``int8_t`` or ``uint8_t``
|
250 |
+
as the argument type.
|
251 |
+
|
252 |
+
Grapheme clusters
|
253 |
+
-----------------
|
254 |
+
|
255 |
+
A single grapheme may be represented by two or more Unicode characters. For
|
256 |
+
example 'é' is usually represented as U+00E9 but can also be expressed as the
|
257 |
+
combining character sequence U+0065 U+0301 (that is, the letter 'e' followed by
|
258 |
+
a combining acute accent). The combining character will be lost if the
|
259 |
+
two-character sequence is passed as an argument, even though it renders as a
|
260 |
+
single grapheme.
|
261 |
+
|
262 |
+
.. code-block:: pycon
|
263 |
+
|
264 |
+
>>> example.pass_wchar("é")
|
265 |
+
'é'
|
266 |
+
|
267 |
+
>>> combining_e_acute = "e" + "\u0301"
|
268 |
+
|
269 |
+
>>> combining_e_acute
|
270 |
+
'é'
|
271 |
+
|
272 |
+
>>> combining_e_acute == "é"
|
273 |
+
False
|
274 |
+
|
275 |
+
>>> example.pass_wchar(combining_e_acute)
|
276 |
+
'e'
|
277 |
+
|
278 |
+
Normalizing combining characters before passing the character literal to C++
|
279 |
+
may resolve *some* of these issues:
|
280 |
+
|
281 |
+
.. code-block:: pycon
|
282 |
+
|
283 |
+
>>> example.pass_wchar(unicodedata.normalize("NFC", combining_e_acute))
|
284 |
+
'é'
|
285 |
+
|
286 |
+
In some languages (Thai for example), there are `graphemes that cannot be
|
287 |
+
expressed as a single Unicode code point
|
288 |
+
<http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries>`_, so there is
|
289 |
+
no way to capture them in a C++ character type.
|
290 |
+
|
291 |
+
|
292 |
+
C++17 string views
|
293 |
+
==================
|
294 |
+
|
295 |
+
C++17 string views are automatically supported when compiling in C++17 mode.
|
296 |
+
They follow the same rules for encoding and decoding as the corresponding STL
|
297 |
+
string type (for example, a ``std::u16string_view`` argument will be passed
|
298 |
+
UTF-16-encoded data, and a returned ``std::string_view`` will be decoded as
|
299 |
+
UTF-8).
|
300 |
+
|
301 |
+
References
|
302 |
+
==========
|
303 |
+
|
304 |
+
* `The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_
|
305 |
+
* `C++ - Using STL Strings at Win32 API Boundaries <https://msdn.microsoft.com/en-ca/magazine/mt238407.aspx>`_
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/classes.rst
ADDED
@@ -0,0 +1,1349 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Classes
|
2 |
+
#######
|
3 |
+
|
4 |
+
This section presents advanced binding code for classes and it is assumed
|
5 |
+
that you are already familiar with the basics from :doc:`/classes`.
|
6 |
+
|
7 |
+
.. _overriding_virtuals:
|
8 |
+
|
9 |
+
Overriding virtual functions in Python
|
10 |
+
======================================
|
11 |
+
|
12 |
+
Suppose that a C++ class or interface has a virtual function that we'd like
|
13 |
+
to override from within Python (we'll focus on the class ``Animal``; ``Dog`` is
|
14 |
+
given as a specific example of how one would do this with traditional C++
|
15 |
+
code).
|
16 |
+
|
17 |
+
.. code-block:: cpp
|
18 |
+
|
19 |
+
class Animal {
|
20 |
+
public:
|
21 |
+
virtual ~Animal() { }
|
22 |
+
virtual std::string go(int n_times) = 0;
|
23 |
+
};
|
24 |
+
|
25 |
+
class Dog : public Animal {
|
26 |
+
public:
|
27 |
+
std::string go(int n_times) override {
|
28 |
+
std::string result;
|
29 |
+
for (int i=0; i<n_times; ++i)
|
30 |
+
result += "woof! ";
|
31 |
+
return result;
|
32 |
+
}
|
33 |
+
};
|
34 |
+
|
35 |
+
Let's also suppose that we are given a plain function which calls the
|
36 |
+
function ``go()`` on an arbitrary ``Animal`` instance.
|
37 |
+
|
38 |
+
.. code-block:: cpp
|
39 |
+
|
40 |
+
std::string call_go(Animal *animal) {
|
41 |
+
return animal->go(3);
|
42 |
+
}
|
43 |
+
|
44 |
+
Normally, the binding code for these classes would look as follows:
|
45 |
+
|
46 |
+
.. code-block:: cpp
|
47 |
+
|
48 |
+
PYBIND11_MODULE(example, m) {
|
49 |
+
py::class_<Animal>(m, "Animal")
|
50 |
+
.def("go", &Animal::go);
|
51 |
+
|
52 |
+
py::class_<Dog, Animal>(m, "Dog")
|
53 |
+
.def(py::init<>());
|
54 |
+
|
55 |
+
m.def("call_go", &call_go);
|
56 |
+
}
|
57 |
+
|
58 |
+
However, these bindings are impossible to extend: ``Animal`` is not
|
59 |
+
constructible, and we clearly require some kind of "trampoline" that
|
60 |
+
redirects virtual calls back to Python.
|
61 |
+
|
62 |
+
Defining a new type of ``Animal`` from within Python is possible but requires a
|
63 |
+
helper class that is defined as follows:
|
64 |
+
|
65 |
+
.. code-block:: cpp
|
66 |
+
|
67 |
+
class PyAnimal : public Animal {
|
68 |
+
public:
|
69 |
+
/* Inherit the constructors */
|
70 |
+
using Animal::Animal;
|
71 |
+
|
72 |
+
/* Trampoline (need one for each virtual function) */
|
73 |
+
std::string go(int n_times) override {
|
74 |
+
PYBIND11_OVERRIDE_PURE(
|
75 |
+
std::string, /* Return type */
|
76 |
+
Animal, /* Parent class */
|
77 |
+
go, /* Name of function in C++ (must match Python name) */
|
78 |
+
n_times /* Argument(s) */
|
79 |
+
);
|
80 |
+
}
|
81 |
+
};
|
82 |
+
|
83 |
+
The macro :c:macro:`PYBIND11_OVERRIDE_PURE` should be used for pure virtual
|
84 |
+
functions, and :c:macro:`PYBIND11_OVERRIDE` should be used for functions which have
|
85 |
+
a default implementation. There are also two alternate macros
|
86 |
+
:c:macro:`PYBIND11_OVERRIDE_PURE_NAME` and :c:macro:`PYBIND11_OVERRIDE_NAME` which
|
87 |
+
take a string-valued name argument between the *Parent class* and *Name of the
|
88 |
+
function* slots, which defines the name of function in Python. This is required
|
89 |
+
when the C++ and Python versions of the
|
90 |
+
function have different names, e.g. ``operator()`` vs ``__call__``.
|
91 |
+
|
92 |
+
The binding code also needs a few minor adaptations (highlighted):
|
93 |
+
|
94 |
+
.. code-block:: cpp
|
95 |
+
:emphasize-lines: 2,3
|
96 |
+
|
97 |
+
PYBIND11_MODULE(example, m) {
|
98 |
+
py::class_<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal")
|
99 |
+
.def(py::init<>())
|
100 |
+
.def("go", &Animal::go);
|
101 |
+
|
102 |
+
py::class_<Dog, Animal>(m, "Dog")
|
103 |
+
.def(py::init<>());
|
104 |
+
|
105 |
+
m.def("call_go", &call_go);
|
106 |
+
}
|
107 |
+
|
108 |
+
Importantly, pybind11 is made aware of the trampoline helper class by
|
109 |
+
specifying it as an extra template argument to :class:`class_`. (This can also
|
110 |
+
be combined with other template arguments such as a custom holder type; the
|
111 |
+
order of template types does not matter). Following this, we are able to
|
112 |
+
define a constructor as usual.
|
113 |
+
|
114 |
+
Bindings should be made against the actual class, not the trampoline helper class.
|
115 |
+
|
116 |
+
.. code-block:: cpp
|
117 |
+
:emphasize-lines: 3
|
118 |
+
|
119 |
+
py::class_<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal");
|
120 |
+
.def(py::init<>())
|
121 |
+
.def("go", &PyAnimal::go); /* <--- THIS IS WRONG, use &Animal::go */
|
122 |
+
|
123 |
+
Note, however, that the above is sufficient for allowing python classes to
|
124 |
+
extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the
|
125 |
+
necessary steps required to providing proper overriding support for inherited
|
126 |
+
classes.
|
127 |
+
|
128 |
+
The Python session below shows how to override ``Animal::go`` and invoke it via
|
129 |
+
a virtual method call.
|
130 |
+
|
131 |
+
.. code-block:: pycon
|
132 |
+
|
133 |
+
>>> from example import *
|
134 |
+
>>> d = Dog()
|
135 |
+
>>> call_go(d)
|
136 |
+
u'woof! woof! woof! '
|
137 |
+
>>> class Cat(Animal):
|
138 |
+
... def go(self, n_times):
|
139 |
+
... return "meow! " * n_times
|
140 |
+
...
|
141 |
+
>>> c = Cat()
|
142 |
+
>>> call_go(c)
|
143 |
+
u'meow! meow! meow! '
|
144 |
+
|
145 |
+
If you are defining a custom constructor in a derived Python class, you *must*
|
146 |
+
ensure that you explicitly call the bound C++ constructor using ``__init__``,
|
147 |
+
*regardless* of whether it is a default constructor or not. Otherwise, the
|
148 |
+
memory for the C++ portion of the instance will be left uninitialized, which
|
149 |
+
will generally leave the C++ instance in an invalid state and cause undefined
|
150 |
+
behavior if the C++ instance is subsequently used.
|
151 |
+
|
152 |
+
.. versionchanged:: 2.6
|
153 |
+
The default pybind11 metaclass will throw a ``TypeError`` when it detects
|
154 |
+
that ``__init__`` was not called by a derived class.
|
155 |
+
|
156 |
+
Here is an example:
|
157 |
+
|
158 |
+
.. code-block:: python
|
159 |
+
|
160 |
+
class Dachshund(Dog):
|
161 |
+
def __init__(self, name):
|
162 |
+
Dog.__init__(self) # Without this, a TypeError is raised.
|
163 |
+
self.name = name
|
164 |
+
|
165 |
+
def bark(self):
|
166 |
+
return "yap!"
|
167 |
+
|
168 |
+
Note that a direct ``__init__`` constructor *should be called*, and ``super()``
|
169 |
+
should not be used. For simple cases of linear inheritance, ``super()``
|
170 |
+
may work, but once you begin mixing Python and C++ multiple inheritance,
|
171 |
+
things will fall apart due to differences between Python's MRO and C++'s
|
172 |
+
mechanisms.
|
173 |
+
|
174 |
+
Please take a look at the :ref:`macro_notes` before using this feature.
|
175 |
+
|
176 |
+
.. note::
|
177 |
+
|
178 |
+
When the overridden type returns a reference or pointer to a type that
|
179 |
+
pybind11 converts from Python (for example, numeric values, std::string,
|
180 |
+
and other built-in value-converting types), there are some limitations to
|
181 |
+
be aware of:
|
182 |
+
|
183 |
+
- because in these cases there is no C++ variable to reference (the value
|
184 |
+
is stored in the referenced Python variable), pybind11 provides one in
|
185 |
+
the PYBIND11_OVERRIDE macros (when needed) with static storage duration.
|
186 |
+
Note that this means that invoking the overridden method on *any*
|
187 |
+
instance will change the referenced value stored in *all* instances of
|
188 |
+
that type.
|
189 |
+
|
190 |
+
- Attempts to modify a non-const reference will not have the desired
|
191 |
+
effect: it will change only the static cache variable, but this change
|
192 |
+
will not propagate to underlying Python instance, and the change will be
|
193 |
+
replaced the next time the override is invoked.
|
194 |
+
|
195 |
+
.. warning::
|
196 |
+
|
197 |
+
The :c:macro:`PYBIND11_OVERRIDE` and accompanying macros used to be called
|
198 |
+
``PYBIND11_OVERLOAD`` up until pybind11 v2.5.0, and :func:`get_override`
|
199 |
+
used to be called ``get_overload``. This naming was corrected and the older
|
200 |
+
macro and function names may soon be deprecated, in order to reduce
|
201 |
+
confusion with overloaded functions and methods and ``py::overload_cast``
|
202 |
+
(see :ref:`classes`).
|
203 |
+
|
204 |
+
.. seealso::
|
205 |
+
|
206 |
+
The file :file:`tests/test_virtual_functions.cpp` contains a complete
|
207 |
+
example that demonstrates how to override virtual functions using pybind11
|
208 |
+
in more detail.
|
209 |
+
|
210 |
+
.. _virtual_and_inheritance:
|
211 |
+
|
212 |
+
Combining virtual functions and inheritance
|
213 |
+
===========================================
|
214 |
+
|
215 |
+
When combining virtual methods with inheritance, you need to be sure to provide
|
216 |
+
an override for each method for which you want to allow overrides from derived
|
217 |
+
python classes. For example, suppose we extend the above ``Animal``/``Dog``
|
218 |
+
example as follows:
|
219 |
+
|
220 |
+
.. code-block:: cpp
|
221 |
+
|
222 |
+
class Animal {
|
223 |
+
public:
|
224 |
+
virtual std::string go(int n_times) = 0;
|
225 |
+
virtual std::string name() { return "unknown"; }
|
226 |
+
};
|
227 |
+
class Dog : public Animal {
|
228 |
+
public:
|
229 |
+
std::string go(int n_times) override {
|
230 |
+
std::string result;
|
231 |
+
for (int i=0; i<n_times; ++i)
|
232 |
+
result += bark() + " ";
|
233 |
+
return result;
|
234 |
+
}
|
235 |
+
virtual std::string bark() { return "woof!"; }
|
236 |
+
};
|
237 |
+
|
238 |
+
then the trampoline class for ``Animal`` must, as described in the previous
|
239 |
+
section, override ``go()`` and ``name()``, but in order to allow python code to
|
240 |
+
inherit properly from ``Dog``, we also need a trampoline class for ``Dog`` that
|
241 |
+
overrides both the added ``bark()`` method *and* the ``go()`` and ``name()``
|
242 |
+
methods inherited from ``Animal`` (even though ``Dog`` doesn't directly
|
243 |
+
override the ``name()`` method):
|
244 |
+
|
245 |
+
.. code-block:: cpp
|
246 |
+
|
247 |
+
class PyAnimal : public Animal {
|
248 |
+
public:
|
249 |
+
using Animal::Animal; // Inherit constructors
|
250 |
+
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Animal, go, n_times); }
|
251 |
+
std::string name() override { PYBIND11_OVERRIDE(std::string, Animal, name, ); }
|
252 |
+
};
|
253 |
+
class PyDog : public Dog {
|
254 |
+
public:
|
255 |
+
using Dog::Dog; // Inherit constructors
|
256 |
+
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, Dog, go, n_times); }
|
257 |
+
std::string name() override { PYBIND11_OVERRIDE(std::string, Dog, name, ); }
|
258 |
+
std::string bark() override { PYBIND11_OVERRIDE(std::string, Dog, bark, ); }
|
259 |
+
};
|
260 |
+
|
261 |
+
.. note::
|
262 |
+
|
263 |
+
Note the trailing commas in the ``PYBIND11_OVERRIDE`` calls to ``name()``
|
264 |
+
and ``bark()``. These are needed to portably implement a trampoline for a
|
265 |
+
function that does not take any arguments. For functions that take
|
266 |
+
a nonzero number of arguments, the trailing comma must be omitted.
|
267 |
+
|
268 |
+
A registered class derived from a pybind11-registered class with virtual
|
269 |
+
methods requires a similar trampoline class, *even if* it doesn't explicitly
|
270 |
+
declare or override any virtual methods itself:
|
271 |
+
|
272 |
+
.. code-block:: cpp
|
273 |
+
|
274 |
+
class Husky : public Dog {};
|
275 |
+
class PyHusky : public Husky {
|
276 |
+
public:
|
277 |
+
using Husky::Husky; // Inherit constructors
|
278 |
+
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Husky, go, n_times); }
|
279 |
+
std::string name() override { PYBIND11_OVERRIDE(std::string, Husky, name, ); }
|
280 |
+
std::string bark() override { PYBIND11_OVERRIDE(std::string, Husky, bark, ); }
|
281 |
+
};
|
282 |
+
|
283 |
+
There is, however, a technique that can be used to avoid this duplication
|
284 |
+
(which can be especially helpful for a base class with several virtual
|
285 |
+
methods). The technique involves using template trampoline classes, as
|
286 |
+
follows:
|
287 |
+
|
288 |
+
.. code-block:: cpp
|
289 |
+
|
290 |
+
template <class AnimalBase = Animal> class PyAnimal : public AnimalBase {
|
291 |
+
public:
|
292 |
+
using AnimalBase::AnimalBase; // Inherit constructors
|
293 |
+
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, AnimalBase, go, n_times); }
|
294 |
+
std::string name() override { PYBIND11_OVERRIDE(std::string, AnimalBase, name, ); }
|
295 |
+
};
|
296 |
+
template <class DogBase = Dog> class PyDog : public PyAnimal<DogBase> {
|
297 |
+
public:
|
298 |
+
using PyAnimal<DogBase>::PyAnimal; // Inherit constructors
|
299 |
+
// Override PyAnimal's pure virtual go() with a non-pure one:
|
300 |
+
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, DogBase, go, n_times); }
|
301 |
+
std::string bark() override { PYBIND11_OVERRIDE(std::string, DogBase, bark, ); }
|
302 |
+
};
|
303 |
+
|
304 |
+
This technique has the advantage of requiring just one trampoline method to be
|
305 |
+
declared per virtual method and pure virtual method override. It does,
|
306 |
+
however, require the compiler to generate at least as many methods (and
|
307 |
+
possibly more, if both pure virtual and overridden pure virtual methods are
|
308 |
+
exposed, as above).
|
309 |
+
|
310 |
+
The classes are then registered with pybind11 using:
|
311 |
+
|
312 |
+
.. code-block:: cpp
|
313 |
+
|
314 |
+
py::class_<Animal, PyAnimal<>> animal(m, "Animal");
|
315 |
+
py::class_<Dog, Animal, PyDog<>> dog(m, "Dog");
|
316 |
+
py::class_<Husky, Dog, PyDog<Husky>> husky(m, "Husky");
|
317 |
+
// ... add animal, dog, husky definitions
|
318 |
+
|
319 |
+
Note that ``Husky`` did not require a dedicated trampoline template class at
|
320 |
+
all, since it neither declares any new virtual methods nor provides any pure
|
321 |
+
virtual method implementations.
|
322 |
+
|
323 |
+
With either the repeated-virtuals or templated trampoline methods in place, you
|
324 |
+
can now create a python class that inherits from ``Dog``:
|
325 |
+
|
326 |
+
.. code-block:: python
|
327 |
+
|
328 |
+
class ShihTzu(Dog):
|
329 |
+
def bark(self):
|
330 |
+
return "yip!"
|
331 |
+
|
332 |
+
.. seealso::
|
333 |
+
|
334 |
+
See the file :file:`tests/test_virtual_functions.cpp` for complete examples
|
335 |
+
using both the duplication and templated trampoline approaches.
|
336 |
+
|
337 |
+
.. _extended_aliases:
|
338 |
+
|
339 |
+
Extended trampoline class functionality
|
340 |
+
=======================================
|
341 |
+
|
342 |
+
.. _extended_class_functionality_forced_trampoline:
|
343 |
+
|
344 |
+
Forced trampoline class initialisation
|
345 |
+
--------------------------------------
|
346 |
+
The trampoline classes described in the previous sections are, by default, only
|
347 |
+
initialized when needed. More specifically, they are initialized when a python
|
348 |
+
class actually inherits from a registered type (instead of merely creating an
|
349 |
+
instance of the registered type), or when a registered constructor is only
|
350 |
+
valid for the trampoline class but not the registered class. This is primarily
|
351 |
+
for performance reasons: when the trampoline class is not needed for anything
|
352 |
+
except virtual method dispatching, not initializing the trampoline class
|
353 |
+
improves performance by avoiding needing to do a run-time check to see if the
|
354 |
+
inheriting python instance has an overridden method.
|
355 |
+
|
356 |
+
Sometimes, however, it is useful to always initialize a trampoline class as an
|
357 |
+
intermediate class that does more than just handle virtual method dispatching.
|
358 |
+
For example, such a class might perform extra class initialization, extra
|
359 |
+
destruction operations, and might define new members and methods to enable a
|
360 |
+
more python-like interface to a class.
|
361 |
+
|
362 |
+
In order to tell pybind11 that it should *always* initialize the trampoline
|
363 |
+
class when creating new instances of a type, the class constructors should be
|
364 |
+
declared using ``py::init_alias<Args, ...>()`` instead of the usual
|
365 |
+
``py::init<Args, ...>()``. This forces construction via the trampoline class,
|
366 |
+
ensuring member initialization and (eventual) destruction.
|
367 |
+
|
368 |
+
.. seealso::
|
369 |
+
|
370 |
+
See the file :file:`tests/test_virtual_functions.cpp` for complete examples
|
371 |
+
showing both normal and forced trampoline instantiation.
|
372 |
+
|
373 |
+
Different method signatures
|
374 |
+
---------------------------
|
375 |
+
The macro's introduced in :ref:`overriding_virtuals` cover most of the standard
|
376 |
+
use cases when exposing C++ classes to Python. Sometimes it is hard or unwieldy
|
377 |
+
to create a direct one-on-one mapping between the arguments and method return
|
378 |
+
type.
|
379 |
+
|
380 |
+
An example would be when the C++ signature contains output arguments using
|
381 |
+
references (See also :ref:`faq_reference_arguments`). Another way of solving
|
382 |
+
this is to use the method body of the trampoline class to do conversions to the
|
383 |
+
input and return of the Python method.
|
384 |
+
|
385 |
+
The main building block to do so is the :func:`get_override`, this function
|
386 |
+
allows retrieving a method implemented in Python from within the trampoline's
|
387 |
+
methods. Consider for example a C++ method which has the signature
|
388 |
+
``bool myMethod(int32_t& value)``, where the return indicates whether
|
389 |
+
something should be done with the ``value``. This can be made convenient on the
|
390 |
+
Python side by allowing the Python function to return ``None`` or an ``int``:
|
391 |
+
|
392 |
+
.. code-block:: cpp
|
393 |
+
|
394 |
+
bool MyClass::myMethod(int32_t& value)
|
395 |
+
{
|
396 |
+
pybind11::gil_scoped_acquire gil; // Acquire the GIL while in this scope.
|
397 |
+
// Try to look up the overridden method on the Python side.
|
398 |
+
pybind11::function override = pybind11::get_override(this, "myMethod");
|
399 |
+
if (override) { // method is found
|
400 |
+
auto obj = override(value); // Call the Python function.
|
401 |
+
if (py::isinstance<py::int_>(obj)) { // check if it returned a Python integer type
|
402 |
+
value = obj.cast<int32_t>(); // Cast it and assign it to the value.
|
403 |
+
return true; // Return true; value should be used.
|
404 |
+
} else {
|
405 |
+
return false; // Python returned none, return false.
|
406 |
+
}
|
407 |
+
}
|
408 |
+
return false; // Alternatively return MyClass::myMethod(value);
|
409 |
+
}
|
410 |
+
|
411 |
+
|
412 |
+
.. _custom_constructors:
|
413 |
+
|
414 |
+
Custom constructors
|
415 |
+
===================
|
416 |
+
|
417 |
+
The syntax for binding constructors was previously introduced, but it only
|
418 |
+
works when a constructor of the appropriate arguments actually exists on the
|
419 |
+
C++ side. To extend this to more general cases, pybind11 makes it possible
|
420 |
+
to bind factory functions as constructors. For example, suppose you have a
|
421 |
+
class like this:
|
422 |
+
|
423 |
+
.. code-block:: cpp
|
424 |
+
|
425 |
+
class Example {
|
426 |
+
private:
|
427 |
+
Example(int); // private constructor
|
428 |
+
public:
|
429 |
+
// Factory function:
|
430 |
+
static Example create(int a) { return Example(a); }
|
431 |
+
};
|
432 |
+
|
433 |
+
py::class_<Example>(m, "Example")
|
434 |
+
.def(py::init(&Example::create));
|
435 |
+
|
436 |
+
While it is possible to create a straightforward binding of the static
|
437 |
+
``create`` method, it may sometimes be preferable to expose it as a constructor
|
438 |
+
on the Python side. This can be accomplished by calling ``.def(py::init(...))``
|
439 |
+
with the function reference returning the new instance passed as an argument.
|
440 |
+
It is also possible to use this approach to bind a function returning a new
|
441 |
+
instance by raw pointer or by the holder (e.g. ``std::unique_ptr``).
|
442 |
+
|
443 |
+
The following example shows the different approaches:
|
444 |
+
|
445 |
+
.. code-block:: cpp
|
446 |
+
|
447 |
+
class Example {
|
448 |
+
private:
|
449 |
+
Example(int); // private constructor
|
450 |
+
public:
|
451 |
+
// Factory function - returned by value:
|
452 |
+
static Example create(int a) { return Example(a); }
|
453 |
+
|
454 |
+
// These constructors are publicly callable:
|
455 |
+
Example(double);
|
456 |
+
Example(int, int);
|
457 |
+
Example(std::string);
|
458 |
+
};
|
459 |
+
|
460 |
+
py::class_<Example>(m, "Example")
|
461 |
+
// Bind the factory function as a constructor:
|
462 |
+
.def(py::init(&Example::create))
|
463 |
+
// Bind a lambda function returning a pointer wrapped in a holder:
|
464 |
+
.def(py::init([](std::string arg) {
|
465 |
+
return std::unique_ptr<Example>(new Example(arg));
|
466 |
+
}))
|
467 |
+
// Return a raw pointer:
|
468 |
+
.def(py::init([](int a, int b) { return new Example(a, b); }))
|
469 |
+
// You can mix the above with regular C++ constructor bindings as well:
|
470 |
+
.def(py::init<double>())
|
471 |
+
;
|
472 |
+
|
473 |
+
When the constructor is invoked from Python, pybind11 will call the factory
|
474 |
+
function and store the resulting C++ instance in the Python instance.
|
475 |
+
|
476 |
+
When combining factory functions constructors with :ref:`virtual function
|
477 |
+
trampolines <overriding_virtuals>` there are two approaches. The first is to
|
478 |
+
add a constructor to the alias class that takes a base value by
|
479 |
+
rvalue-reference. If such a constructor is available, it will be used to
|
480 |
+
construct an alias instance from the value returned by the factory function.
|
481 |
+
The second option is to provide two factory functions to ``py::init()``: the
|
482 |
+
first will be invoked when no alias class is required (i.e. when the class is
|
483 |
+
being used but not inherited from in Python), and the second will be invoked
|
484 |
+
when an alias is required.
|
485 |
+
|
486 |
+
You can also specify a single factory function that always returns an alias
|
487 |
+
instance: this will result in behaviour similar to ``py::init_alias<...>()``,
|
488 |
+
as described in the :ref:`extended trampoline class documentation
|
489 |
+
<extended_aliases>`.
|
490 |
+
|
491 |
+
The following example shows the different factory approaches for a class with
|
492 |
+
an alias:
|
493 |
+
|
494 |
+
.. code-block:: cpp
|
495 |
+
|
496 |
+
#include <pybind11/factory.h>
|
497 |
+
class Example {
|
498 |
+
public:
|
499 |
+
// ...
|
500 |
+
virtual ~Example() = default;
|
501 |
+
};
|
502 |
+
class PyExample : public Example {
|
503 |
+
public:
|
504 |
+
using Example::Example;
|
505 |
+
PyExample(Example &&base) : Example(std::move(base)) {}
|
506 |
+
};
|
507 |
+
py::class_<Example, PyExample>(m, "Example")
|
508 |
+
// Returns an Example pointer. If a PyExample is needed, the Example
|
509 |
+
// instance will be moved via the extra constructor in PyExample, above.
|
510 |
+
.def(py::init([]() { return new Example(); }))
|
511 |
+
// Two callbacks:
|
512 |
+
.def(py::init([]() { return new Example(); } /* no alias needed */,
|
513 |
+
[]() { return new PyExample(); } /* alias needed */))
|
514 |
+
// *Always* returns an alias instance (like py::init_alias<>())
|
515 |
+
.def(py::init([]() { return new PyExample(); }))
|
516 |
+
;
|
517 |
+
|
518 |
+
Brace initialization
|
519 |
+
--------------------
|
520 |
+
|
521 |
+
``pybind11::init<>`` internally uses C++11 brace initialization to call the
|
522 |
+
constructor of the target class. This means that it can be used to bind
|
523 |
+
*implicit* constructors as well:
|
524 |
+
|
525 |
+
.. code-block:: cpp
|
526 |
+
|
527 |
+
struct Aggregate {
|
528 |
+
int a;
|
529 |
+
std::string b;
|
530 |
+
};
|
531 |
+
|
532 |
+
py::class_<Aggregate>(m, "Aggregate")
|
533 |
+
.def(py::init<int, const std::string &>());
|
534 |
+
|
535 |
+
.. note::
|
536 |
+
|
537 |
+
Note that brace initialization preferentially invokes constructor overloads
|
538 |
+
taking a ``std::initializer_list``. In the rare event that this causes an
|
539 |
+
issue, you can work around it by using ``py::init(...)`` with a lambda
|
540 |
+
function that constructs the new object as desired.
|
541 |
+
|
542 |
+
.. _classes_with_non_public_destructors:
|
543 |
+
|
544 |
+
Non-public destructors
|
545 |
+
======================
|
546 |
+
|
547 |
+
If a class has a private or protected destructor (as might e.g. be the case in
|
548 |
+
a singleton pattern), a compile error will occur when creating bindings via
|
549 |
+
pybind11. The underlying issue is that the ``std::unique_ptr`` holder type that
|
550 |
+
is responsible for managing the lifetime of instances will reference the
|
551 |
+
destructor even if no deallocations ever take place. In order to expose classes
|
552 |
+
with private or protected destructors, it is possible to override the holder
|
553 |
+
type via a holder type argument to ``class_``. Pybind11 provides a helper class
|
554 |
+
``py::nodelete`` that disables any destructor invocations. In this case, it is
|
555 |
+
crucial that instances are deallocated on the C++ side to avoid memory leaks.
|
556 |
+
|
557 |
+
.. code-block:: cpp
|
558 |
+
|
559 |
+
/* ... definition ... */
|
560 |
+
|
561 |
+
class MyClass {
|
562 |
+
private:
|
563 |
+
~MyClass() { }
|
564 |
+
};
|
565 |
+
|
566 |
+
/* ... binding code ... */
|
567 |
+
|
568 |
+
py::class_<MyClass, std::unique_ptr<MyClass, py::nodelete>>(m, "MyClass")
|
569 |
+
.def(py::init<>())
|
570 |
+
|
571 |
+
.. _destructors_that_call_python:
|
572 |
+
|
573 |
+
Destructors that call Python
|
574 |
+
============================
|
575 |
+
|
576 |
+
If a Python function is invoked from a C++ destructor, an exception may be thrown
|
577 |
+
of type :class:`error_already_set`. If this error is thrown out of a class destructor,
|
578 |
+
``std::terminate()`` will be called, terminating the process. Class destructors
|
579 |
+
must catch all exceptions of type :class:`error_already_set` to discard the Python
|
580 |
+
exception using :func:`error_already_set::discard_as_unraisable`.
|
581 |
+
|
582 |
+
Every Python function should be treated as *possibly throwing*. When a Python generator
|
583 |
+
stops yielding items, Python will throw a ``StopIteration`` exception, which can pass
|
584 |
+
though C++ destructors if the generator's stack frame holds the last reference to C++
|
585 |
+
objects.
|
586 |
+
|
587 |
+
For more information, see :ref:`the documentation on exceptions <unraisable_exceptions>`.
|
588 |
+
|
589 |
+
.. code-block:: cpp
|
590 |
+
|
591 |
+
class MyClass {
|
592 |
+
public:
|
593 |
+
~MyClass() {
|
594 |
+
try {
|
595 |
+
py::print("Even printing is dangerous in a destructor");
|
596 |
+
py::exec("raise ValueError('This is an unraisable exception')");
|
597 |
+
} catch (py::error_already_set &e) {
|
598 |
+
// error_context should be information about where/why the occurred,
|
599 |
+
// e.g. use __func__ to get the name of the current function
|
600 |
+
e.discard_as_unraisable(__func__);
|
601 |
+
}
|
602 |
+
}
|
603 |
+
};
|
604 |
+
|
605 |
+
.. note::
|
606 |
+
|
607 |
+
pybind11 does not support C++ destructors marked ``noexcept(false)``.
|
608 |
+
|
609 |
+
.. versionadded:: 2.6
|
610 |
+
|
611 |
+
.. _implicit_conversions:
|
612 |
+
|
613 |
+
Implicit conversions
|
614 |
+
====================
|
615 |
+
|
616 |
+
Suppose that instances of two types ``A`` and ``B`` are used in a project, and
|
617 |
+
that an ``A`` can easily be converted into an instance of type ``B`` (examples of this
|
618 |
+
could be a fixed and an arbitrary precision number type).
|
619 |
+
|
620 |
+
.. code-block:: cpp
|
621 |
+
|
622 |
+
py::class_<A>(m, "A")
|
623 |
+
/// ... members ...
|
624 |
+
|
625 |
+
py::class_<B>(m, "B")
|
626 |
+
.def(py::init<A>())
|
627 |
+
/// ... members ...
|
628 |
+
|
629 |
+
m.def("func",
|
630 |
+
[](const B &) { /* .... */ }
|
631 |
+
);
|
632 |
+
|
633 |
+
To invoke the function ``func`` using a variable ``a`` containing an ``A``
|
634 |
+
instance, we'd have to write ``func(B(a))`` in Python. On the other hand, C++
|
635 |
+
will automatically apply an implicit type conversion, which makes it possible
|
636 |
+
to directly write ``func(a)``.
|
637 |
+
|
638 |
+
In this situation (i.e. where ``B`` has a constructor that converts from
|
639 |
+
``A``), the following statement enables similar implicit conversions on the
|
640 |
+
Python side:
|
641 |
+
|
642 |
+
.. code-block:: cpp
|
643 |
+
|
644 |
+
py::implicitly_convertible<A, B>();
|
645 |
+
|
646 |
+
.. note::
|
647 |
+
|
648 |
+
Implicit conversions from ``A`` to ``B`` only work when ``B`` is a custom
|
649 |
+
data type that is exposed to Python via pybind11.
|
650 |
+
|
651 |
+
To prevent runaway recursion, implicit conversions are non-reentrant: an
|
652 |
+
implicit conversion invoked as part of another implicit conversion of the
|
653 |
+
same type (i.e. from ``A`` to ``B``) will fail.
|
654 |
+
|
655 |
+
.. _static_properties:
|
656 |
+
|
657 |
+
Static properties
|
658 |
+
=================
|
659 |
+
|
660 |
+
The section on :ref:`properties` discussed the creation of instance properties
|
661 |
+
that are implemented in terms of C++ getters and setters.
|
662 |
+
|
663 |
+
Static properties can also be created in a similar way to expose getters and
|
664 |
+
setters of static class attributes. Note that the implicit ``self`` argument
|
665 |
+
also exists in this case and is used to pass the Python ``type`` subclass
|
666 |
+
instance. This parameter will often not be needed by the C++ side, and the
|
667 |
+
following example illustrates how to instantiate a lambda getter function
|
668 |
+
that ignores it:
|
669 |
+
|
670 |
+
.. code-block:: cpp
|
671 |
+
|
672 |
+
py::class_<Foo>(m, "Foo")
|
673 |
+
.def_property_readonly_static("foo", [](py::object /* self */) { return Foo(); });
|
674 |
+
|
675 |
+
Operator overloading
|
676 |
+
====================
|
677 |
+
|
678 |
+
Suppose that we're given the following ``Vector2`` class with a vector addition
|
679 |
+
and scalar multiplication operation, all implemented using overloaded operators
|
680 |
+
in C++.
|
681 |
+
|
682 |
+
.. code-block:: cpp
|
683 |
+
|
684 |
+
class Vector2 {
|
685 |
+
public:
|
686 |
+
Vector2(float x, float y) : x(x), y(y) { }
|
687 |
+
|
688 |
+
Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); }
|
689 |
+
Vector2 operator*(float value) const { return Vector2(x * value, y * value); }
|
690 |
+
Vector2& operator+=(const Vector2 &v) { x += v.x; y += v.y; return *this; }
|
691 |
+
Vector2& operator*=(float v) { x *= v; y *= v; return *this; }
|
692 |
+
|
693 |
+
friend Vector2 operator*(float f, const Vector2 &v) {
|
694 |
+
return Vector2(f * v.x, f * v.y);
|
695 |
+
}
|
696 |
+
|
697 |
+
std::string toString() const {
|
698 |
+
return "[" + std::to_string(x) + ", " + std::to_string(y) + "]";
|
699 |
+
}
|
700 |
+
private:
|
701 |
+
float x, y;
|
702 |
+
};
|
703 |
+
|
704 |
+
The following snippet shows how the above operators can be conveniently exposed
|
705 |
+
to Python.
|
706 |
+
|
707 |
+
.. code-block:: cpp
|
708 |
+
|
709 |
+
#include <pybind11/operators.h>
|
710 |
+
|
711 |
+
PYBIND11_MODULE(example, m) {
|
712 |
+
py::class_<Vector2>(m, "Vector2")
|
713 |
+
.def(py::init<float, float>())
|
714 |
+
.def(py::self + py::self)
|
715 |
+
.def(py::self += py::self)
|
716 |
+
.def(py::self *= float())
|
717 |
+
.def(float() * py::self)
|
718 |
+
.def(py::self * float())
|
719 |
+
.def(-py::self)
|
720 |
+
.def("__repr__", &Vector2::toString);
|
721 |
+
}
|
722 |
+
|
723 |
+
Note that a line like
|
724 |
+
|
725 |
+
.. code-block:: cpp
|
726 |
+
|
727 |
+
.def(py::self * float())
|
728 |
+
|
729 |
+
is really just short hand notation for
|
730 |
+
|
731 |
+
.. code-block:: cpp
|
732 |
+
|
733 |
+
.def("__mul__", [](const Vector2 &a, float b) {
|
734 |
+
return a * b;
|
735 |
+
}, py::is_operator())
|
736 |
+
|
737 |
+
This can be useful for exposing additional operators that don't exist on the
|
738 |
+
C++ side, or to perform other types of customization. The ``py::is_operator``
|
739 |
+
flag marker is needed to inform pybind11 that this is an operator, which
|
740 |
+
returns ``NotImplemented`` when invoked with incompatible arguments rather than
|
741 |
+
throwing a type error.
|
742 |
+
|
743 |
+
.. note::
|
744 |
+
|
745 |
+
To use the more convenient ``py::self`` notation, the additional
|
746 |
+
header file :file:`pybind11/operators.h` must be included.
|
747 |
+
|
748 |
+
.. seealso::
|
749 |
+
|
750 |
+
The file :file:`tests/test_operator_overloading.cpp` contains a
|
751 |
+
complete example that demonstrates how to work with overloaded operators in
|
752 |
+
more detail.
|
753 |
+
|
754 |
+
.. _pickling:
|
755 |
+
|
756 |
+
Pickling support
|
757 |
+
================
|
758 |
+
|
759 |
+
Python's ``pickle`` module provides a powerful facility to serialize and
|
760 |
+
de-serialize a Python object graph into a binary data stream. To pickle and
|
761 |
+
unpickle C++ classes using pybind11, a ``py::pickle()`` definition must be
|
762 |
+
provided. Suppose the class in question has the following signature:
|
763 |
+
|
764 |
+
.. code-block:: cpp
|
765 |
+
|
766 |
+
class Pickleable {
|
767 |
+
public:
|
768 |
+
Pickleable(const std::string &value) : m_value(value) { }
|
769 |
+
const std::string &value() const { return m_value; }
|
770 |
+
|
771 |
+
void setExtra(int extra) { m_extra = extra; }
|
772 |
+
int extra() const { return m_extra; }
|
773 |
+
private:
|
774 |
+
std::string m_value;
|
775 |
+
int m_extra = 0;
|
776 |
+
};
|
777 |
+
|
778 |
+
Pickling support in Python is enabled by defining the ``__setstate__`` and
|
779 |
+
``__getstate__`` methods [#f3]_. For pybind11 classes, use ``py::pickle()``
|
780 |
+
to bind these two functions:
|
781 |
+
|
782 |
+
.. code-block:: cpp
|
783 |
+
|
784 |
+
py::class_<Pickleable>(m, "Pickleable")
|
785 |
+
.def(py::init<std::string>())
|
786 |
+
.def("value", &Pickleable::value)
|
787 |
+
.def("extra", &Pickleable::extra)
|
788 |
+
.def("setExtra", &Pickleable::setExtra)
|
789 |
+
.def(py::pickle(
|
790 |
+
[](const Pickleable &p) { // __getstate__
|
791 |
+
/* Return a tuple that fully encodes the state of the object */
|
792 |
+
return py::make_tuple(p.value(), p.extra());
|
793 |
+
},
|
794 |
+
[](py::tuple t) { // __setstate__
|
795 |
+
if (t.size() != 2)
|
796 |
+
throw std::runtime_error("Invalid state!");
|
797 |
+
|
798 |
+
/* Create a new C++ instance */
|
799 |
+
Pickleable p(t[0].cast<std::string>());
|
800 |
+
|
801 |
+
/* Assign any additional state */
|
802 |
+
p.setExtra(t[1].cast<int>());
|
803 |
+
|
804 |
+
return p;
|
805 |
+
}
|
806 |
+
));
|
807 |
+
|
808 |
+
The ``__setstate__`` part of the ``py::pickle()`` definition follows the same
|
809 |
+
rules as the single-argument version of ``py::init()``. The return type can be
|
810 |
+
a value, pointer or holder type. See :ref:`custom_constructors` for details.
|
811 |
+
|
812 |
+
An instance can now be pickled as follows:
|
813 |
+
|
814 |
+
.. code-block:: python
|
815 |
+
|
816 |
+
try:
|
817 |
+
import cPickle as pickle # Use cPickle on Python 2.7
|
818 |
+
except ImportError:
|
819 |
+
import pickle
|
820 |
+
|
821 |
+
p = Pickleable("test_value")
|
822 |
+
p.setExtra(15)
|
823 |
+
data = pickle.dumps(p, 2)
|
824 |
+
|
825 |
+
|
826 |
+
.. note::
|
827 |
+
Note that only the cPickle module is supported on Python 2.7.
|
828 |
+
|
829 |
+
The second argument to ``dumps`` is also crucial: it selects the pickle
|
830 |
+
protocol version 2, since the older version 1 is not supported. Newer
|
831 |
+
versions are also fine—for instance, specify ``-1`` to always use the
|
832 |
+
latest available version. Beware: failure to follow these instructions
|
833 |
+
will cause important pybind11 memory allocation routines to be skipped
|
834 |
+
during unpickling, which will likely lead to memory corruption and/or
|
835 |
+
segmentation faults.
|
836 |
+
|
837 |
+
.. seealso::
|
838 |
+
|
839 |
+
The file :file:`tests/test_pickling.cpp` contains a complete example
|
840 |
+
that demonstrates how to pickle and unpickle types using pybind11 in more
|
841 |
+
detail.
|
842 |
+
|
843 |
+
.. [#f3] http://docs.python.org/3/library/pickle.html#pickling-class-instances
|
844 |
+
|
845 |
+
Deepcopy support
|
846 |
+
================
|
847 |
+
|
848 |
+
Python normally uses references in assignments. Sometimes a real copy is needed
|
849 |
+
to prevent changing all copies. The ``copy`` module [#f5]_ provides these
|
850 |
+
capabilities.
|
851 |
+
|
852 |
+
On Python 3, a class with pickle support is automatically also (deep)copy
|
853 |
+
compatible. However, performance can be improved by adding custom
|
854 |
+
``__copy__`` and ``__deepcopy__`` methods. With Python 2.7, these custom methods
|
855 |
+
are mandatory for (deep)copy compatibility, because pybind11 only supports
|
856 |
+
cPickle.
|
857 |
+
|
858 |
+
For simple classes (deep)copy can be enabled by using the copy constructor,
|
859 |
+
which should look as follows:
|
860 |
+
|
861 |
+
.. code-block:: cpp
|
862 |
+
|
863 |
+
py::class_<Copyable>(m, "Copyable")
|
864 |
+
.def("__copy__", [](const Copyable &self) {
|
865 |
+
return Copyable(self);
|
866 |
+
})
|
867 |
+
.def("__deepcopy__", [](const Copyable &self, py::dict) {
|
868 |
+
return Copyable(self);
|
869 |
+
}, "memo"_a);
|
870 |
+
|
871 |
+
.. note::
|
872 |
+
|
873 |
+
Dynamic attributes will not be copied in this example.
|
874 |
+
|
875 |
+
.. [#f5] https://docs.python.org/3/library/copy.html
|
876 |
+
|
877 |
+
Multiple Inheritance
|
878 |
+
====================
|
879 |
+
|
880 |
+
pybind11 can create bindings for types that derive from multiple base types
|
881 |
+
(aka. *multiple inheritance*). To do so, specify all bases in the template
|
882 |
+
arguments of the ``class_`` declaration:
|
883 |
+
|
884 |
+
.. code-block:: cpp
|
885 |
+
|
886 |
+
py::class_<MyType, BaseType1, BaseType2, BaseType3>(m, "MyType")
|
887 |
+
...
|
888 |
+
|
889 |
+
The base types can be specified in arbitrary order, and they can even be
|
890 |
+
interspersed with alias types and holder types (discussed earlier in this
|
891 |
+
document)---pybind11 will automatically find out which is which. The only
|
892 |
+
requirement is that the first template argument is the type to be declared.
|
893 |
+
|
894 |
+
It is also permitted to inherit multiply from exported C++ classes in Python,
|
895 |
+
as well as inheriting from multiple Python and/or pybind11-exported classes.
|
896 |
+
|
897 |
+
There is one caveat regarding the implementation of this feature:
|
898 |
+
|
899 |
+
When only one base type is specified for a C++ type that actually has multiple
|
900 |
+
bases, pybind11 will assume that it does not participate in multiple
|
901 |
+
inheritance, which can lead to undefined behavior. In such cases, add the tag
|
902 |
+
``multiple_inheritance`` to the class constructor:
|
903 |
+
|
904 |
+
.. code-block:: cpp
|
905 |
+
|
906 |
+
py::class_<MyType, BaseType2>(m, "MyType", py::multiple_inheritance());
|
907 |
+
|
908 |
+
The tag is redundant and does not need to be specified when multiple base types
|
909 |
+
are listed.
|
910 |
+
|
911 |
+
.. _module_local:
|
912 |
+
|
913 |
+
Module-local class bindings
|
914 |
+
===========================
|
915 |
+
|
916 |
+
When creating a binding for a class, pybind11 by default makes that binding
|
917 |
+
"global" across modules. What this means is that a type defined in one module
|
918 |
+
can be returned from any module resulting in the same Python type. For
|
919 |
+
example, this allows the following:
|
920 |
+
|
921 |
+
.. code-block:: cpp
|
922 |
+
|
923 |
+
// In the module1.cpp binding code for module1:
|
924 |
+
py::class_<Pet>(m, "Pet")
|
925 |
+
.def(py::init<std::string>())
|
926 |
+
.def_readonly("name", &Pet::name);
|
927 |
+
|
928 |
+
.. code-block:: cpp
|
929 |
+
|
930 |
+
// In the module2.cpp binding code for module2:
|
931 |
+
m.def("create_pet", [](std::string name) { return new Pet(name); });
|
932 |
+
|
933 |
+
.. code-block:: pycon
|
934 |
+
|
935 |
+
>>> from module1 import Pet
|
936 |
+
>>> from module2 import create_pet
|
937 |
+
>>> pet1 = Pet("Kitty")
|
938 |
+
>>> pet2 = create_pet("Doggy")
|
939 |
+
>>> pet2.name()
|
940 |
+
'Doggy'
|
941 |
+
|
942 |
+
When writing binding code for a library, this is usually desirable: this
|
943 |
+
allows, for example, splitting up a complex library into multiple Python
|
944 |
+
modules.
|
945 |
+
|
946 |
+
In some cases, however, this can cause conflicts. For example, suppose two
|
947 |
+
unrelated modules make use of an external C++ library and each provide custom
|
948 |
+
bindings for one of that library's classes. This will result in an error when
|
949 |
+
a Python program attempts to import both modules (directly or indirectly)
|
950 |
+
because of conflicting definitions on the external type:
|
951 |
+
|
952 |
+
.. code-block:: cpp
|
953 |
+
|
954 |
+
// dogs.cpp
|
955 |
+
|
956 |
+
// Binding for external library class:
|
957 |
+
py::class<pets::Pet>(m, "Pet")
|
958 |
+
.def("name", &pets::Pet::name);
|
959 |
+
|
960 |
+
// Binding for local extension class:
|
961 |
+
py::class<Dog, pets::Pet>(m, "Dog")
|
962 |
+
.def(py::init<std::string>());
|
963 |
+
|
964 |
+
.. code-block:: cpp
|
965 |
+
|
966 |
+
// cats.cpp, in a completely separate project from the above dogs.cpp.
|
967 |
+
|
968 |
+
// Binding for external library class:
|
969 |
+
py::class<pets::Pet>(m, "Pet")
|
970 |
+
.def("get_name", &pets::Pet::name);
|
971 |
+
|
972 |
+
// Binding for local extending class:
|
973 |
+
py::class<Cat, pets::Pet>(m, "Cat")
|
974 |
+
.def(py::init<std::string>());
|
975 |
+
|
976 |
+
.. code-block:: pycon
|
977 |
+
|
978 |
+
>>> import cats
|
979 |
+
>>> import dogs
|
980 |
+
Traceback (most recent call last):
|
981 |
+
File "<stdin>", line 1, in <module>
|
982 |
+
ImportError: generic_type: type "Pet" is already registered!
|
983 |
+
|
984 |
+
To get around this, you can tell pybind11 to keep the external class binding
|
985 |
+
localized to the module by passing the ``py::module_local()`` attribute into
|
986 |
+
the ``py::class_`` constructor:
|
987 |
+
|
988 |
+
.. code-block:: cpp
|
989 |
+
|
990 |
+
// Pet binding in dogs.cpp:
|
991 |
+
py::class<pets::Pet>(m, "Pet", py::module_local())
|
992 |
+
.def("name", &pets::Pet::name);
|
993 |
+
|
994 |
+
.. code-block:: cpp
|
995 |
+
|
996 |
+
// Pet binding in cats.cpp:
|
997 |
+
py::class<pets::Pet>(m, "Pet", py::module_local())
|
998 |
+
.def("get_name", &pets::Pet::name);
|
999 |
+
|
1000 |
+
This makes the Python-side ``dogs.Pet`` and ``cats.Pet`` into distinct classes,
|
1001 |
+
avoiding the conflict and allowing both modules to be loaded. C++ code in the
|
1002 |
+
``dogs`` module that casts or returns a ``Pet`` instance will result in a
|
1003 |
+
``dogs.Pet`` Python instance, while C++ code in the ``cats`` module will result
|
1004 |
+
in a ``cats.Pet`` Python instance.
|
1005 |
+
|
1006 |
+
This does come with two caveats, however: First, external modules cannot return
|
1007 |
+
or cast a ``Pet`` instance to Python (unless they also provide their own local
|
1008 |
+
bindings). Second, from the Python point of view they are two distinct classes.
|
1009 |
+
|
1010 |
+
Note that the locality only applies in the C++ -> Python direction. When
|
1011 |
+
passing such a ``py::module_local`` type into a C++ function, the module-local
|
1012 |
+
classes are still considered. This means that if the following function is
|
1013 |
+
added to any module (including but not limited to the ``cats`` and ``dogs``
|
1014 |
+
modules above) it will be callable with either a ``dogs.Pet`` or ``cats.Pet``
|
1015 |
+
argument:
|
1016 |
+
|
1017 |
+
.. code-block:: cpp
|
1018 |
+
|
1019 |
+
m.def("pet_name", [](const pets::Pet &pet) { return pet.name(); });
|
1020 |
+
|
1021 |
+
For example, suppose the above function is added to each of ``cats.cpp``,
|
1022 |
+
``dogs.cpp`` and ``frogs.cpp`` (where ``frogs.cpp`` is some other module that
|
1023 |
+
does *not* bind ``Pets`` at all).
|
1024 |
+
|
1025 |
+
.. code-block:: pycon
|
1026 |
+
|
1027 |
+
>>> import cats, dogs, frogs # No error because of the added py::module_local()
|
1028 |
+
>>> mycat, mydog = cats.Cat("Fluffy"), dogs.Dog("Rover")
|
1029 |
+
>>> (cats.pet_name(mycat), dogs.pet_name(mydog))
|
1030 |
+
('Fluffy', 'Rover')
|
1031 |
+
>>> (cats.pet_name(mydog), dogs.pet_name(mycat), frogs.pet_name(mycat))
|
1032 |
+
('Rover', 'Fluffy', 'Fluffy')
|
1033 |
+
|
1034 |
+
It is possible to use ``py::module_local()`` registrations in one module even
|
1035 |
+
if another module registers the same type globally: within the module with the
|
1036 |
+
module-local definition, all C++ instances will be cast to the associated bound
|
1037 |
+
Python type. In other modules any such values are converted to the global
|
1038 |
+
Python type created elsewhere.
|
1039 |
+
|
1040 |
+
.. note::
|
1041 |
+
|
1042 |
+
STL bindings (as provided via the optional :file:`pybind11/stl_bind.h`
|
1043 |
+
header) apply ``py::module_local`` by default when the bound type might
|
1044 |
+
conflict with other modules; see :ref:`stl_bind` for details.
|
1045 |
+
|
1046 |
+
.. note::
|
1047 |
+
|
1048 |
+
The localization of the bound types is actually tied to the shared object
|
1049 |
+
or binary generated by the compiler/linker. For typical modules created
|
1050 |
+
with ``PYBIND11_MODULE()``, this distinction is not significant. It is
|
1051 |
+
possible, however, when :ref:`embedding` to embed multiple modules in the
|
1052 |
+
same binary (see :ref:`embedding_modules`). In such a case, the
|
1053 |
+
localization will apply across all embedded modules within the same binary.
|
1054 |
+
|
1055 |
+
.. seealso::
|
1056 |
+
|
1057 |
+
The file :file:`tests/test_local_bindings.cpp` contains additional examples
|
1058 |
+
that demonstrate how ``py::module_local()`` works.
|
1059 |
+
|
1060 |
+
Binding protected member functions
|
1061 |
+
==================================
|
1062 |
+
|
1063 |
+
It's normally not possible to expose ``protected`` member functions to Python:
|
1064 |
+
|
1065 |
+
.. code-block:: cpp
|
1066 |
+
|
1067 |
+
class A {
|
1068 |
+
protected:
|
1069 |
+
int foo() const { return 42; }
|
1070 |
+
};
|
1071 |
+
|
1072 |
+
py::class_<A>(m, "A")
|
1073 |
+
.def("foo", &A::foo); // error: 'foo' is a protected member of 'A'
|
1074 |
+
|
1075 |
+
On one hand, this is good because non-``public`` members aren't meant to be
|
1076 |
+
accessed from the outside. But we may want to make use of ``protected``
|
1077 |
+
functions in derived Python classes.
|
1078 |
+
|
1079 |
+
The following pattern makes this possible:
|
1080 |
+
|
1081 |
+
.. code-block:: cpp
|
1082 |
+
|
1083 |
+
class A {
|
1084 |
+
protected:
|
1085 |
+
int foo() const { return 42; }
|
1086 |
+
};
|
1087 |
+
|
1088 |
+
class Publicist : public A { // helper type for exposing protected functions
|
1089 |
+
public:
|
1090 |
+
using A::foo; // inherited with different access modifier
|
1091 |
+
};
|
1092 |
+
|
1093 |
+
py::class_<A>(m, "A") // bind the primary class
|
1094 |
+
.def("foo", &Publicist::foo); // expose protected methods via the publicist
|
1095 |
+
|
1096 |
+
This works because ``&Publicist::foo`` is exactly the same function as
|
1097 |
+
``&A::foo`` (same signature and address), just with a different access
|
1098 |
+
modifier. The only purpose of the ``Publicist`` helper class is to make
|
1099 |
+
the function name ``public``.
|
1100 |
+
|
1101 |
+
If the intent is to expose ``protected`` ``virtual`` functions which can be
|
1102 |
+
overridden in Python, the publicist pattern can be combined with the previously
|
1103 |
+
described trampoline:
|
1104 |
+
|
1105 |
+
.. code-block:: cpp
|
1106 |
+
|
1107 |
+
class A {
|
1108 |
+
public:
|
1109 |
+
virtual ~A() = default;
|
1110 |
+
|
1111 |
+
protected:
|
1112 |
+
virtual int foo() const { return 42; }
|
1113 |
+
};
|
1114 |
+
|
1115 |
+
class Trampoline : public A {
|
1116 |
+
public:
|
1117 |
+
int foo() const override { PYBIND11_OVERRIDE(int, A, foo, ); }
|
1118 |
+
};
|
1119 |
+
|
1120 |
+
class Publicist : public A {
|
1121 |
+
public:
|
1122 |
+
using A::foo;
|
1123 |
+
};
|
1124 |
+
|
1125 |
+
py::class_<A, Trampoline>(m, "A") // <-- `Trampoline` here
|
1126 |
+
.def("foo", &Publicist::foo); // <-- `Publicist` here, not `Trampoline`!
|
1127 |
+
|
1128 |
+
.. note::
|
1129 |
+
|
1130 |
+
MSVC 2015 has a compiler bug (fixed in version 2017) which
|
1131 |
+
requires a more explicit function binding in the form of
|
1132 |
+
``.def("foo", static_cast<int (A::*)() const>(&Publicist::foo));``
|
1133 |
+
where ``int (A::*)() const`` is the type of ``A::foo``.
|
1134 |
+
|
1135 |
+
Binding final classes
|
1136 |
+
=====================
|
1137 |
+
|
1138 |
+
Some classes may not be appropriate to inherit from. In C++11, classes can
|
1139 |
+
use the ``final`` specifier to ensure that a class cannot be inherited from.
|
1140 |
+
The ``py::is_final`` attribute can be used to ensure that Python classes
|
1141 |
+
cannot inherit from a specified type. The underlying C++ type does not need
|
1142 |
+
to be declared final.
|
1143 |
+
|
1144 |
+
.. code-block:: cpp
|
1145 |
+
|
1146 |
+
class IsFinal final {};
|
1147 |
+
|
1148 |
+
py::class_<IsFinal>(m, "IsFinal", py::is_final());
|
1149 |
+
|
1150 |
+
When you try to inherit from such a class in Python, you will now get this
|
1151 |
+
error:
|
1152 |
+
|
1153 |
+
.. code-block:: pycon
|
1154 |
+
|
1155 |
+
>>> class PyFinalChild(IsFinal):
|
1156 |
+
... pass
|
1157 |
+
...
|
1158 |
+
TypeError: type 'IsFinal' is not an acceptable base type
|
1159 |
+
|
1160 |
+
.. note:: This attribute is currently ignored on PyPy
|
1161 |
+
|
1162 |
+
.. versionadded:: 2.6
|
1163 |
+
|
1164 |
+
Binding classes with template parameters
|
1165 |
+
========================================
|
1166 |
+
|
1167 |
+
pybind11 can also wrap classes that have template parameters. Consider these classes:
|
1168 |
+
|
1169 |
+
.. code-block:: cpp
|
1170 |
+
|
1171 |
+
struct Cat {};
|
1172 |
+
struct Dog {};
|
1173 |
+
|
1174 |
+
template <typename PetType>
|
1175 |
+
struct Cage {
|
1176 |
+
Cage(PetType& pet);
|
1177 |
+
PetType& get();
|
1178 |
+
};
|
1179 |
+
|
1180 |
+
C++ templates may only be instantiated at compile time, so pybind11 can only
|
1181 |
+
wrap instantiated templated classes. You cannot wrap a non-instantiated template:
|
1182 |
+
|
1183 |
+
.. code-block:: cpp
|
1184 |
+
|
1185 |
+
// BROKEN (this will not compile)
|
1186 |
+
py::class_<Cage>(m, "Cage");
|
1187 |
+
.def("get", &Cage::get);
|
1188 |
+
|
1189 |
+
You must explicitly specify each template/type combination that you want to
|
1190 |
+
wrap separately.
|
1191 |
+
|
1192 |
+
.. code-block:: cpp
|
1193 |
+
|
1194 |
+
// ok
|
1195 |
+
py::class_<Cage<Cat>>(m, "CatCage")
|
1196 |
+
.def("get", &Cage<Cat>::get);
|
1197 |
+
|
1198 |
+
// ok
|
1199 |
+
py::class_<Cage<Dog>>(m, "DogCage")
|
1200 |
+
.def("get", &Cage<Dog>::get);
|
1201 |
+
|
1202 |
+
If your class methods have template parameters you can wrap those as well,
|
1203 |
+
but once again each instantiation must be explicitly specified:
|
1204 |
+
|
1205 |
+
.. code-block:: cpp
|
1206 |
+
|
1207 |
+
typename <typename T>
|
1208 |
+
struct MyClass {
|
1209 |
+
template <typename V>
|
1210 |
+
T fn(V v);
|
1211 |
+
};
|
1212 |
+
|
1213 |
+
py::class<MyClass<int>>(m, "MyClassT")
|
1214 |
+
.def("fn", &MyClass<int>::fn<std::string>);
|
1215 |
+
|
1216 |
+
Custom automatic downcasters
|
1217 |
+
============================
|
1218 |
+
|
1219 |
+
As explained in :ref:`inheritance`, pybind11 comes with built-in
|
1220 |
+
understanding of the dynamic type of polymorphic objects in C++; that
|
1221 |
+
is, returning a Pet to Python produces a Python object that knows it's
|
1222 |
+
wrapping a Dog, if Pet has virtual methods and pybind11 knows about
|
1223 |
+
Dog and this Pet is in fact a Dog. Sometimes, you might want to
|
1224 |
+
provide this automatic downcasting behavior when creating bindings for
|
1225 |
+
a class hierarchy that does not use standard C++ polymorphism, such as
|
1226 |
+
LLVM [#f4]_. As long as there's some way to determine at runtime
|
1227 |
+
whether a downcast is safe, you can proceed by specializing the
|
1228 |
+
``pybind11::polymorphic_type_hook`` template:
|
1229 |
+
|
1230 |
+
.. code-block:: cpp
|
1231 |
+
|
1232 |
+
enum class PetKind { Cat, Dog, Zebra };
|
1233 |
+
struct Pet { // Not polymorphic: has no virtual methods
|
1234 |
+
const PetKind kind;
|
1235 |
+
int age = 0;
|
1236 |
+
protected:
|
1237 |
+
Pet(PetKind _kind) : kind(_kind) {}
|
1238 |
+
};
|
1239 |
+
struct Dog : Pet {
|
1240 |
+
Dog() : Pet(PetKind::Dog) {}
|
1241 |
+
std::string sound = "woof!";
|
1242 |
+
std::string bark() const { return sound; }
|
1243 |
+
};
|
1244 |
+
|
1245 |
+
namespace pybind11 {
|
1246 |
+
template<> struct polymorphic_type_hook<Pet> {
|
1247 |
+
static const void *get(const Pet *src, const std::type_info*& type) {
|
1248 |
+
// note that src may be nullptr
|
1249 |
+
if (src && src->kind == PetKind::Dog) {
|
1250 |
+
type = &typeid(Dog);
|
1251 |
+
return static_cast<const Dog*>(src);
|
1252 |
+
}
|
1253 |
+
return src;
|
1254 |
+
}
|
1255 |
+
};
|
1256 |
+
} // namespace pybind11
|
1257 |
+
|
1258 |
+
When pybind11 wants to convert a C++ pointer of type ``Base*`` to a
|
1259 |
+
Python object, it calls ``polymorphic_type_hook<Base>::get()`` to
|
1260 |
+
determine if a downcast is possible. The ``get()`` function should use
|
1261 |
+
whatever runtime information is available to determine if its ``src``
|
1262 |
+
parameter is in fact an instance of some class ``Derived`` that
|
1263 |
+
inherits from ``Base``. If it finds such a ``Derived``, it sets ``type
|
1264 |
+
= &typeid(Derived)`` and returns a pointer to the ``Derived`` object
|
1265 |
+
that contains ``src``. Otherwise, it just returns ``src``, leaving
|
1266 |
+
``type`` at its default value of nullptr. If you set ``type`` to a
|
1267 |
+
type that pybind11 doesn't know about, no downcasting will occur, and
|
1268 |
+
the original ``src`` pointer will be used with its static type
|
1269 |
+
``Base*``.
|
1270 |
+
|
1271 |
+
It is critical that the returned pointer and ``type`` argument of
|
1272 |
+
``get()`` agree with each other: if ``type`` is set to something
|
1273 |
+
non-null, the returned pointer must point to the start of an object
|
1274 |
+
whose type is ``type``. If the hierarchy being exposed uses only
|
1275 |
+
single inheritance, a simple ``return src;`` will achieve this just
|
1276 |
+
fine, but in the general case, you must cast ``src`` to the
|
1277 |
+
appropriate derived-class pointer (e.g. using
|
1278 |
+
``static_cast<Derived>(src)``) before allowing it to be returned as a
|
1279 |
+
``void*``.
|
1280 |
+
|
1281 |
+
.. [#f4] https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html
|
1282 |
+
|
1283 |
+
.. note::
|
1284 |
+
|
1285 |
+
pybind11's standard support for downcasting objects whose types
|
1286 |
+
have virtual methods is implemented using
|
1287 |
+
``polymorphic_type_hook`` too, using the standard C++ ability to
|
1288 |
+
determine the most-derived type of a polymorphic object using
|
1289 |
+
``typeid()`` and to cast a base pointer to that most-derived type
|
1290 |
+
(even if you don't know what it is) using ``dynamic_cast<void*>``.
|
1291 |
+
|
1292 |
+
.. seealso::
|
1293 |
+
|
1294 |
+
The file :file:`tests/test_tagbased_polymorphic.cpp` contains a
|
1295 |
+
more complete example, including a demonstration of how to provide
|
1296 |
+
automatic downcasting for an entire class hierarchy without
|
1297 |
+
writing one get() function for each class.
|
1298 |
+
|
1299 |
+
Accessing the type object
|
1300 |
+
=========================
|
1301 |
+
|
1302 |
+
You can get the type object from a C++ class that has already been registered using:
|
1303 |
+
|
1304 |
+
.. code-block:: cpp
|
1305 |
+
|
1306 |
+
py::type T_py = py::type::of<T>();
|
1307 |
+
|
1308 |
+
You can directly use ``py::type::of(ob)`` to get the type object from any python
|
1309 |
+
object, just like ``type(ob)`` in Python.
|
1310 |
+
|
1311 |
+
.. note::
|
1312 |
+
|
1313 |
+
Other types, like ``py::type::of<int>()``, do not work, see :ref:`type-conversions`.
|
1314 |
+
|
1315 |
+
.. versionadded:: 2.6
|
1316 |
+
|
1317 |
+
Custom type setup
|
1318 |
+
=================
|
1319 |
+
|
1320 |
+
For advanced use cases, such as enabling garbage collection support, you may
|
1321 |
+
wish to directly manipulate the ``PyHeapTypeObject`` corresponding to a
|
1322 |
+
``py::class_`` definition.
|
1323 |
+
|
1324 |
+
You can do that using ``py::custom_type_setup``:
|
1325 |
+
|
1326 |
+
.. code-block:: cpp
|
1327 |
+
|
1328 |
+
struct OwnsPythonObjects {
|
1329 |
+
py::object value = py::none();
|
1330 |
+
};
|
1331 |
+
py::class_<OwnsPythonObjects> cls(
|
1332 |
+
m, "OwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {
|
1333 |
+
auto *type = &heap_type->ht_type;
|
1334 |
+
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
1335 |
+
type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {
|
1336 |
+
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
|
1337 |
+
Py_VISIT(self.value.ptr());
|
1338 |
+
return 0;
|
1339 |
+
};
|
1340 |
+
type->tp_clear = [](PyObject *self_base) {
|
1341 |
+
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
|
1342 |
+
self.value = py::none();
|
1343 |
+
return 0;
|
1344 |
+
};
|
1345 |
+
}));
|
1346 |
+
cls.def(py::init<>());
|
1347 |
+
cls.def_readwrite("value", &OwnsPythonObjects::value);
|
1348 |
+
|
1349 |
+
.. versionadded:: 2.8
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/embedding.rst
ADDED
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.. _embedding:
|
2 |
+
|
3 |
+
Embedding the interpreter
|
4 |
+
#########################
|
5 |
+
|
6 |
+
While pybind11 is mainly focused on extending Python using C++, it's also
|
7 |
+
possible to do the reverse: embed the Python interpreter into a C++ program.
|
8 |
+
All of the other documentation pages still apply here, so refer to them for
|
9 |
+
general pybind11 usage. This section will cover a few extra things required
|
10 |
+
for embedding.
|
11 |
+
|
12 |
+
Getting started
|
13 |
+
===============
|
14 |
+
|
15 |
+
A basic executable with an embedded interpreter can be created with just a few
|
16 |
+
lines of CMake and the ``pybind11::embed`` target, as shown below. For more
|
17 |
+
information, see :doc:`/compiling`.
|
18 |
+
|
19 |
+
.. code-block:: cmake
|
20 |
+
|
21 |
+
cmake_minimum_required(VERSION 3.4)
|
22 |
+
project(example)
|
23 |
+
|
24 |
+
find_package(pybind11 REQUIRED) # or `add_subdirectory(pybind11)`
|
25 |
+
|
26 |
+
add_executable(example main.cpp)
|
27 |
+
target_link_libraries(example PRIVATE pybind11::embed)
|
28 |
+
|
29 |
+
The essential structure of the ``main.cpp`` file looks like this:
|
30 |
+
|
31 |
+
.. code-block:: cpp
|
32 |
+
|
33 |
+
#include <pybind11/embed.h> // everything needed for embedding
|
34 |
+
namespace py = pybind11;
|
35 |
+
|
36 |
+
int main() {
|
37 |
+
py::scoped_interpreter guard{}; // start the interpreter and keep it alive
|
38 |
+
|
39 |
+
py::print("Hello, World!"); // use the Python API
|
40 |
+
}
|
41 |
+
|
42 |
+
The interpreter must be initialized before using any Python API, which includes
|
43 |
+
all the functions and classes in pybind11. The RAII guard class ``scoped_interpreter``
|
44 |
+
takes care of the interpreter lifetime. After the guard is destroyed, the interpreter
|
45 |
+
shuts down and clears its memory. No Python functions can be called after this.
|
46 |
+
|
47 |
+
Executing Python code
|
48 |
+
=====================
|
49 |
+
|
50 |
+
There are a few different ways to run Python code. One option is to use ``eval``,
|
51 |
+
``exec`` or ``eval_file``, as explained in :ref:`eval`. Here is a quick example in
|
52 |
+
the context of an executable with an embedded interpreter:
|
53 |
+
|
54 |
+
.. code-block:: cpp
|
55 |
+
|
56 |
+
#include <pybind11/embed.h>
|
57 |
+
namespace py = pybind11;
|
58 |
+
|
59 |
+
int main() {
|
60 |
+
py::scoped_interpreter guard{};
|
61 |
+
|
62 |
+
py::exec(R"(
|
63 |
+
kwargs = dict(name="World", number=42)
|
64 |
+
message = "Hello, {name}! The answer is {number}".format(**kwargs)
|
65 |
+
print(message)
|
66 |
+
)");
|
67 |
+
}
|
68 |
+
|
69 |
+
Alternatively, similar results can be achieved using pybind11's API (see
|
70 |
+
:doc:`/advanced/pycpp/index` for more details).
|
71 |
+
|
72 |
+
.. code-block:: cpp
|
73 |
+
|
74 |
+
#include <pybind11/embed.h>
|
75 |
+
namespace py = pybind11;
|
76 |
+
using namespace py::literals;
|
77 |
+
|
78 |
+
int main() {
|
79 |
+
py::scoped_interpreter guard{};
|
80 |
+
|
81 |
+
auto kwargs = py::dict("name"_a="World", "number"_a=42);
|
82 |
+
auto message = "Hello, {name}! The answer is {number}"_s.format(**kwargs);
|
83 |
+
py::print(message);
|
84 |
+
}
|
85 |
+
|
86 |
+
The two approaches can also be combined:
|
87 |
+
|
88 |
+
.. code-block:: cpp
|
89 |
+
|
90 |
+
#include <pybind11/embed.h>
|
91 |
+
#include <iostream>
|
92 |
+
|
93 |
+
namespace py = pybind11;
|
94 |
+
using namespace py::literals;
|
95 |
+
|
96 |
+
int main() {
|
97 |
+
py::scoped_interpreter guard{};
|
98 |
+
|
99 |
+
auto locals = py::dict("name"_a="World", "number"_a=42);
|
100 |
+
py::exec(R"(
|
101 |
+
message = "Hello, {name}! The answer is {number}".format(**locals())
|
102 |
+
)", py::globals(), locals);
|
103 |
+
|
104 |
+
auto message = locals["message"].cast<std::string>();
|
105 |
+
std::cout << message;
|
106 |
+
}
|
107 |
+
|
108 |
+
Importing modules
|
109 |
+
=================
|
110 |
+
|
111 |
+
Python modules can be imported using ``module_::import()``:
|
112 |
+
|
113 |
+
.. code-block:: cpp
|
114 |
+
|
115 |
+
py::module_ sys = py::module_::import("sys");
|
116 |
+
py::print(sys.attr("path"));
|
117 |
+
|
118 |
+
For convenience, the current working directory is included in ``sys.path`` when
|
119 |
+
embedding the interpreter. This makes it easy to import local Python files:
|
120 |
+
|
121 |
+
.. code-block:: python
|
122 |
+
|
123 |
+
"""calc.py located in the working directory"""
|
124 |
+
|
125 |
+
|
126 |
+
def add(i, j):
|
127 |
+
return i + j
|
128 |
+
|
129 |
+
|
130 |
+
.. code-block:: cpp
|
131 |
+
|
132 |
+
py::module_ calc = py::module_::import("calc");
|
133 |
+
py::object result = calc.attr("add")(1, 2);
|
134 |
+
int n = result.cast<int>();
|
135 |
+
assert(n == 3);
|
136 |
+
|
137 |
+
Modules can be reloaded using ``module_::reload()`` if the source is modified e.g.
|
138 |
+
by an external process. This can be useful in scenarios where the application
|
139 |
+
imports a user defined data processing script which needs to be updated after
|
140 |
+
changes by the user. Note that this function does not reload modules recursively.
|
141 |
+
|
142 |
+
.. _embedding_modules:
|
143 |
+
|
144 |
+
Adding embedded modules
|
145 |
+
=======================
|
146 |
+
|
147 |
+
Embedded binary modules can be added using the ``PYBIND11_EMBEDDED_MODULE`` macro.
|
148 |
+
Note that the definition must be placed at global scope. They can be imported
|
149 |
+
like any other module.
|
150 |
+
|
151 |
+
.. code-block:: cpp
|
152 |
+
|
153 |
+
#include <pybind11/embed.h>
|
154 |
+
namespace py = pybind11;
|
155 |
+
|
156 |
+
PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
|
157 |
+
// `m` is a `py::module_` which is used to bind functions and classes
|
158 |
+
m.def("add", [](int i, int j) {
|
159 |
+
return i + j;
|
160 |
+
});
|
161 |
+
}
|
162 |
+
|
163 |
+
int main() {
|
164 |
+
py::scoped_interpreter guard{};
|
165 |
+
|
166 |
+
auto fast_calc = py::module_::import("fast_calc");
|
167 |
+
auto result = fast_calc.attr("add")(1, 2).cast<int>();
|
168 |
+
assert(result == 3);
|
169 |
+
}
|
170 |
+
|
171 |
+
Unlike extension modules where only a single binary module can be created, on
|
172 |
+
the embedded side an unlimited number of modules can be added using multiple
|
173 |
+
``PYBIND11_EMBEDDED_MODULE`` definitions (as long as they have unique names).
|
174 |
+
|
175 |
+
These modules are added to Python's list of builtins, so they can also be
|
176 |
+
imported in pure Python files loaded by the interpreter. Everything interacts
|
177 |
+
naturally:
|
178 |
+
|
179 |
+
.. code-block:: python
|
180 |
+
|
181 |
+
"""py_module.py located in the working directory"""
|
182 |
+
import cpp_module
|
183 |
+
|
184 |
+
a = cpp_module.a
|
185 |
+
b = a + 1
|
186 |
+
|
187 |
+
|
188 |
+
.. code-block:: cpp
|
189 |
+
|
190 |
+
#include <pybind11/embed.h>
|
191 |
+
namespace py = pybind11;
|
192 |
+
|
193 |
+
PYBIND11_EMBEDDED_MODULE(cpp_module, m) {
|
194 |
+
m.attr("a") = 1;
|
195 |
+
}
|
196 |
+
|
197 |
+
int main() {
|
198 |
+
py::scoped_interpreter guard{};
|
199 |
+
|
200 |
+
auto py_module = py::module_::import("py_module");
|
201 |
+
|
202 |
+
auto locals = py::dict("fmt"_a="{} + {} = {}", **py_module.attr("__dict__"));
|
203 |
+
assert(locals["a"].cast<int>() == 1);
|
204 |
+
assert(locals["b"].cast<int>() == 2);
|
205 |
+
|
206 |
+
py::exec(R"(
|
207 |
+
c = a + b
|
208 |
+
message = fmt.format(a, b, c)
|
209 |
+
)", py::globals(), locals);
|
210 |
+
|
211 |
+
assert(locals["c"].cast<int>() == 3);
|
212 |
+
assert(locals["message"].cast<std::string>() == "1 + 2 = 3");
|
213 |
+
}
|
214 |
+
|
215 |
+
|
216 |
+
Interpreter lifetime
|
217 |
+
====================
|
218 |
+
|
219 |
+
The Python interpreter shuts down when ``scoped_interpreter`` is destroyed. After
|
220 |
+
this, creating a new instance will restart the interpreter. Alternatively, the
|
221 |
+
``initialize_interpreter`` / ``finalize_interpreter`` pair of functions can be used
|
222 |
+
to directly set the state at any time.
|
223 |
+
|
224 |
+
Modules created with pybind11 can be safely re-initialized after the interpreter
|
225 |
+
has been restarted. However, this may not apply to third-party extension modules.
|
226 |
+
The issue is that Python itself cannot completely unload extension modules and
|
227 |
+
there are several caveats with regard to interpreter restarting. In short, not
|
228 |
+
all memory may be freed, either due to Python reference cycles or user-created
|
229 |
+
global data. All the details can be found in the CPython documentation.
|
230 |
+
|
231 |
+
.. warning::
|
232 |
+
|
233 |
+
Creating two concurrent ``scoped_interpreter`` guards is a fatal error. So is
|
234 |
+
calling ``initialize_interpreter`` for a second time after the interpreter
|
235 |
+
has already been initialized.
|
236 |
+
|
237 |
+
Do not use the raw CPython API functions ``Py_Initialize`` and
|
238 |
+
``Py_Finalize`` as these do not properly handle the lifetime of
|
239 |
+
pybind11's internal data.
|
240 |
+
|
241 |
+
|
242 |
+
Sub-interpreter support
|
243 |
+
=======================
|
244 |
+
|
245 |
+
Creating multiple copies of ``scoped_interpreter`` is not possible because it
|
246 |
+
represents the main Python interpreter. Sub-interpreters are something different
|
247 |
+
and they do permit the existence of multiple interpreters. This is an advanced
|
248 |
+
feature of the CPython API and should be handled with care. pybind11 does not
|
249 |
+
currently offer a C++ interface for sub-interpreters, so refer to the CPython
|
250 |
+
documentation for all the details regarding this feature.
|
251 |
+
|
252 |
+
We'll just mention a couple of caveats the sub-interpreters support in pybind11:
|
253 |
+
|
254 |
+
1. Sub-interpreters will not receive independent copies of embedded modules.
|
255 |
+
Instead, these are shared and modifications in one interpreter may be
|
256 |
+
reflected in another.
|
257 |
+
|
258 |
+
2. Managing multiple threads, multiple interpreters and the GIL can be
|
259 |
+
challenging and there are several caveats here, even within the pure
|
260 |
+
CPython API (please refer to the Python docs for details). As for
|
261 |
+
pybind11, keep in mind that ``gil_scoped_release`` and ``gil_scoped_acquire``
|
262 |
+
do not take sub-interpreters into account.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/exceptions.rst
ADDED
@@ -0,0 +1,398 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Exceptions
|
2 |
+
##########
|
3 |
+
|
4 |
+
Built-in C++ to Python exception translation
|
5 |
+
============================================
|
6 |
+
|
7 |
+
When Python calls C++ code through pybind11, pybind11 provides a C++ exception handler
|
8 |
+
that will trap C++ exceptions, translate them to the corresponding Python exception,
|
9 |
+
and raise them so that Python code can handle them.
|
10 |
+
|
11 |
+
pybind11 defines translations for ``std::exception`` and its standard
|
12 |
+
subclasses, and several special exception classes that translate to specific
|
13 |
+
Python exceptions. Note that these are not actually Python exceptions, so they
|
14 |
+
cannot be examined using the Python C API. Instead, they are pure C++ objects
|
15 |
+
that pybind11 will translate the corresponding Python exception when they arrive
|
16 |
+
at its exception handler.
|
17 |
+
|
18 |
+
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
19 |
+
|
20 |
+
+--------------------------------------+--------------------------------------+
|
21 |
+
| Exception thrown by C++ | Translated to Python exception type |
|
22 |
+
+======================================+======================================+
|
23 |
+
| :class:`std::exception` | ``RuntimeError`` |
|
24 |
+
+--------------------------------------+--------------------------------------+
|
25 |
+
| :class:`std::bad_alloc` | ``MemoryError`` |
|
26 |
+
+--------------------------------------+--------------------------------------+
|
27 |
+
| :class:`std::domain_error` | ``ValueError`` |
|
28 |
+
+--------------------------------------+--------------------------------------+
|
29 |
+
| :class:`std::invalid_argument` | ``ValueError`` |
|
30 |
+
+--------------------------------------+--------------------------------------+
|
31 |
+
| :class:`std::length_error` | ``ValueError`` |
|
32 |
+
+--------------------------------------+--------------------------------------+
|
33 |
+
| :class:`std::out_of_range` | ``IndexError`` |
|
34 |
+
+--------------------------------------+--------------------------------------+
|
35 |
+
| :class:`std::range_error` | ``ValueError`` |
|
36 |
+
+--------------------------------------+--------------------------------------+
|
37 |
+
| :class:`std::overflow_error` | ``OverflowError`` |
|
38 |
+
+--------------------------------------+--------------------------------------+
|
39 |
+
| :class:`pybind11::stop_iteration` | ``StopIteration`` (used to implement |
|
40 |
+
| | custom iterators) |
|
41 |
+
+--------------------------------------+--------------------------------------+
|
42 |
+
| :class:`pybind11::index_error` | ``IndexError`` (used to indicate out |
|
43 |
+
| | of bounds access in ``__getitem__``, |
|
44 |
+
| | ``__setitem__``, etc.) |
|
45 |
+
+--------------------------------------+--------------------------------------+
|
46 |
+
| :class:`pybind11::key_error` | ``KeyError`` (used to indicate out |
|
47 |
+
| | of bounds access in ``__getitem__``, |
|
48 |
+
| | ``__setitem__`` in dict-like |
|
49 |
+
| | objects, etc.) |
|
50 |
+
+--------------------------------------+--------------------------------------+
|
51 |
+
| :class:`pybind11::value_error` | ``ValueError`` (used to indicate |
|
52 |
+
| | wrong value passed in |
|
53 |
+
| | ``container.remove(...)``) |
|
54 |
+
+--------------------------------------+--------------------------------------+
|
55 |
+
| :class:`pybind11::type_error` | ``TypeError`` |
|
56 |
+
+--------------------------------------+--------------------------------------+
|
57 |
+
| :class:`pybind11::buffer_error` | ``BufferError`` |
|
58 |
+
+--------------------------------------+--------------------------------------+
|
59 |
+
| :class:`pybind11::import_error` | ``ImportError`` |
|
60 |
+
+--------------------------------------+--------------------------------------+
|
61 |
+
| :class:`pybind11::attribute_error` | ``AttributeError`` |
|
62 |
+
+--------------------------------------+--------------------------------------+
|
63 |
+
| Any other exception | ``RuntimeError`` |
|
64 |
+
+--------------------------------------+--------------------------------------+
|
65 |
+
|
66 |
+
Exception translation is not bidirectional. That is, *catching* the C++
|
67 |
+
exceptions defined above will not trap exceptions that originate from
|
68 |
+
Python. For that, catch :class:`pybind11::error_already_set`. See :ref:`below
|
69 |
+
<handling_python_exceptions_cpp>` for further details.
|
70 |
+
|
71 |
+
There is also a special exception :class:`cast_error` that is thrown by
|
72 |
+
:func:`handle::call` when the input arguments cannot be converted to Python
|
73 |
+
objects.
|
74 |
+
|
75 |
+
Registering custom translators
|
76 |
+
==============================
|
77 |
+
|
78 |
+
If the default exception conversion policy described above is insufficient,
|
79 |
+
pybind11 also provides support for registering custom exception translators.
|
80 |
+
Similar to pybind11 classes, exception translators can be local to the module
|
81 |
+
they are defined in or global to the entire python session. To register a simple
|
82 |
+
exception conversion that translates a C++ exception into a new Python exception
|
83 |
+
using the C++ exception's ``what()`` method, a helper function is available:
|
84 |
+
|
85 |
+
.. code-block:: cpp
|
86 |
+
|
87 |
+
py::register_exception<CppExp>(module, "PyExp");
|
88 |
+
|
89 |
+
This call creates a Python exception class with the name ``PyExp`` in the given
|
90 |
+
module and automatically converts any encountered exceptions of type ``CppExp``
|
91 |
+
into Python exceptions of type ``PyExp``.
|
92 |
+
|
93 |
+
A matching function is available for registering a local exception translator:
|
94 |
+
|
95 |
+
.. code-block:: cpp
|
96 |
+
|
97 |
+
py::register_local_exception<CppExp>(module, "PyExp");
|
98 |
+
|
99 |
+
|
100 |
+
It is possible to specify base class for the exception using the third
|
101 |
+
parameter, a ``handle``:
|
102 |
+
|
103 |
+
.. code-block:: cpp
|
104 |
+
|
105 |
+
py::register_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
106 |
+
py::register_local_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
107 |
+
|
108 |
+
Then ``PyExp`` can be caught both as ``PyExp`` and ``RuntimeError``.
|
109 |
+
|
110 |
+
The class objects of the built-in Python exceptions are listed in the Python
|
111 |
+
documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
|
112 |
+
The default base class is ``PyExc_Exception``.
|
113 |
+
|
114 |
+
When more advanced exception translation is needed, the functions
|
115 |
+
``py::register_exception_translator(translator)`` and
|
116 |
+
``py::register_local_exception_translator(translator)`` can be used to register
|
117 |
+
functions that can translate arbitrary exception types (and which may include
|
118 |
+
additional logic to do so). The functions takes a stateless callable (e.g. a
|
119 |
+
function pointer or a lambda function without captured variables) with the call
|
120 |
+
signature ``void(std::exception_ptr)``.
|
121 |
+
|
122 |
+
When a C++ exception is thrown, the registered exception translators are tried
|
123 |
+
in reverse order of registration (i.e. the last registered translator gets the
|
124 |
+
first shot at handling the exception). All local translators will be tried
|
125 |
+
before a global translator is tried.
|
126 |
+
|
127 |
+
Inside the translator, ``std::rethrow_exception`` should be used within
|
128 |
+
a try block to re-throw the exception. One or more catch clauses to catch
|
129 |
+
the appropriate exceptions should then be used with each clause using
|
130 |
+
``PyErr_SetString`` to set a Python exception or ``ex(string)`` to set
|
131 |
+
the python exception to a custom exception type (see below).
|
132 |
+
|
133 |
+
To declare a custom Python exception type, declare a ``py::exception`` variable
|
134 |
+
and use this in the associated exception translator (note: it is often useful
|
135 |
+
to make this a static declaration when using it inside a lambda expression
|
136 |
+
without requiring capturing).
|
137 |
+
|
138 |
+
The following example demonstrates this for a hypothetical exception classes
|
139 |
+
``MyCustomException`` and ``OtherException``: the first is translated to a
|
140 |
+
custom python exception ``MyCustomError``, while the second is translated to a
|
141 |
+
standard python RuntimeError:
|
142 |
+
|
143 |
+
.. code-block:: cpp
|
144 |
+
|
145 |
+
static py::exception<MyCustomException> exc(m, "MyCustomError");
|
146 |
+
py::register_exception_translator([](std::exception_ptr p) {
|
147 |
+
try {
|
148 |
+
if (p) std::rethrow_exception(p);
|
149 |
+
} catch (const MyCustomException &e) {
|
150 |
+
exc(e.what());
|
151 |
+
} catch (const OtherException &e) {
|
152 |
+
PyErr_SetString(PyExc_RuntimeError, e.what());
|
153 |
+
}
|
154 |
+
});
|
155 |
+
|
156 |
+
Multiple exceptions can be handled by a single translator, as shown in the
|
157 |
+
example above. If the exception is not caught by the current translator, the
|
158 |
+
previously registered one gets a chance.
|
159 |
+
|
160 |
+
If none of the registered exception translators is able to handle the
|
161 |
+
exception, it is handled by the default converter as described in the previous
|
162 |
+
section.
|
163 |
+
|
164 |
+
.. seealso::
|
165 |
+
|
166 |
+
The file :file:`tests/test_exceptions.cpp` contains examples
|
167 |
+
of various custom exception translators and custom exception types.
|
168 |
+
|
169 |
+
.. note::
|
170 |
+
|
171 |
+
Call either ``PyErr_SetString`` or a custom exception's call
|
172 |
+
operator (``exc(string)``) for every exception caught in a custom exception
|
173 |
+
translator. Failure to do so will cause Python to crash with ``SystemError:
|
174 |
+
error return without exception set``.
|
175 |
+
|
176 |
+
Exceptions that you do not plan to handle should simply not be caught, or
|
177 |
+
may be explicitly (re-)thrown to delegate it to the other,
|
178 |
+
previously-declared existing exception translators.
|
179 |
+
|
180 |
+
Note that ``libc++`` and ``libstdc++`` `behave differently <https://stackoverflow.com/questions/19496643/using-clang-fvisibility-hidden-and-typeinfo-and-type-erasure/28827430>`_
|
181 |
+
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI boundaries need to be explicitly exported, as exercised in ``tests/test_exceptions.h``.
|
182 |
+
See also: "Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
|
183 |
+
|
184 |
+
|
185 |
+
Local vs Global Exception Translators
|
186 |
+
=====================================
|
187 |
+
|
188 |
+
When a global exception translator is registered, it will be applied across all
|
189 |
+
modules in the reverse order of registration. This can create behavior where the
|
190 |
+
order of module import influences how exceptions are translated.
|
191 |
+
|
192 |
+
If module1 has the following translator:
|
193 |
+
|
194 |
+
.. code-block:: cpp
|
195 |
+
|
196 |
+
py::register_exception_translator([](std::exception_ptr p) {
|
197 |
+
try {
|
198 |
+
if (p) std::rethrow_exception(p);
|
199 |
+
} catch (const std::invalid_argument &e) {
|
200 |
+
PyErr_SetString("module1 handled this")
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
and module2 has the following similar translator:
|
205 |
+
|
206 |
+
.. code-block:: cpp
|
207 |
+
|
208 |
+
py::register_exception_translator([](std::exception_ptr p) {
|
209 |
+
try {
|
210 |
+
if (p) std::rethrow_exception(p);
|
211 |
+
} catch (const std::invalid_argument &e) {
|
212 |
+
PyErr_SetString("module2 handled this")
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
then which translator handles the invalid_argument will be determined by the
|
217 |
+
order that module1 and module2 are imported. Since exception translators are
|
218 |
+
applied in the reverse order of registration, which ever module was imported
|
219 |
+
last will "win" and that translator will be applied.
|
220 |
+
|
221 |
+
If there are multiple pybind11 modules that share exception types (either
|
222 |
+
standard built-in or custom) loaded into a single python instance and
|
223 |
+
consistent error handling behavior is needed, then local translators should be
|
224 |
+
used.
|
225 |
+
|
226 |
+
Changing the previous example to use ``register_local_exception_translator``
|
227 |
+
would mean that when invalid_argument is thrown in the module2 code, the
|
228 |
+
module2 translator will always handle it, while in module1, the module1
|
229 |
+
translator will do the same.
|
230 |
+
|
231 |
+
.. _handling_python_exceptions_cpp:
|
232 |
+
|
233 |
+
Handling exceptions from Python in C++
|
234 |
+
======================================
|
235 |
+
|
236 |
+
When C++ calls Python functions, such as in a callback function or when
|
237 |
+
manipulating Python objects, and Python raises an ``Exception``, pybind11
|
238 |
+
converts the Python exception into a C++ exception of type
|
239 |
+
:class:`pybind11::error_already_set` whose payload contains a C++ string textual
|
240 |
+
summary and the actual Python exception. ``error_already_set`` is used to
|
241 |
+
propagate Python exception back to Python (or possibly, handle them in C++).
|
242 |
+
|
243 |
+
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
244 |
+
|
245 |
+
+--------------------------------------+--------------------------------------+
|
246 |
+
| Exception raised in Python | Thrown as C++ exception type |
|
247 |
+
+======================================+======================================+
|
248 |
+
| Any Python ``Exception`` | :class:`pybind11::error_already_set` |
|
249 |
+
+--------------------------------------+--------------------------------------+
|
250 |
+
|
251 |
+
For example:
|
252 |
+
|
253 |
+
.. code-block:: cpp
|
254 |
+
|
255 |
+
try {
|
256 |
+
// open("missing.txt", "r")
|
257 |
+
auto file = py::module_::import("io").attr("open")("missing.txt", "r");
|
258 |
+
auto text = file.attr("read")();
|
259 |
+
file.attr("close")();
|
260 |
+
} catch (py::error_already_set &e) {
|
261 |
+
if (e.matches(PyExc_FileNotFoundError)) {
|
262 |
+
py::print("missing.txt not found");
|
263 |
+
} else if (e.matches(PyExc_PermissionError)) {
|
264 |
+
py::print("missing.txt found but not accessible");
|
265 |
+
} else {
|
266 |
+
throw;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
|
270 |
+
Note that C++ to Python exception translation does not apply here, since that is
|
271 |
+
a method for translating C++ exceptions to Python, not vice versa. The error raised
|
272 |
+
from Python is always ``error_already_set``.
|
273 |
+
|
274 |
+
This example illustrates this behavior:
|
275 |
+
|
276 |
+
.. code-block:: cpp
|
277 |
+
|
278 |
+
try {
|
279 |
+
py::eval("raise ValueError('The Ring')");
|
280 |
+
} catch (py::value_error &boromir) {
|
281 |
+
// Boromir never gets the ring
|
282 |
+
assert(false);
|
283 |
+
} catch (py::error_already_set &frodo) {
|
284 |
+
// Frodo gets the ring
|
285 |
+
py::print("I will take the ring");
|
286 |
+
}
|
287 |
+
|
288 |
+
try {
|
289 |
+
// py::value_error is a request for pybind11 to raise a Python exception
|
290 |
+
throw py::value_error("The ball");
|
291 |
+
} catch (py::error_already_set &cat) {
|
292 |
+
// cat won't catch the ball since
|
293 |
+
// py::value_error is not a Python exception
|
294 |
+
assert(false);
|
295 |
+
} catch (py::value_error &dog) {
|
296 |
+
// dog will catch the ball
|
297 |
+
py::print("Run Spot run");
|
298 |
+
throw; // Throw it again (pybind11 will raise ValueError)
|
299 |
+
}
|
300 |
+
|
301 |
+
Handling errors from the Python C API
|
302 |
+
=====================================
|
303 |
+
|
304 |
+
Where possible, use :ref:`pybind11 wrappers <wrappers>` instead of calling
|
305 |
+
the Python C API directly. When calling the Python C API directly, in
|
306 |
+
addition to manually managing reference counts, one must follow the pybind11
|
307 |
+
error protocol, which is outlined here.
|
308 |
+
|
309 |
+
After calling the Python C API, if Python returns an error,
|
310 |
+
``throw py::error_already_set();``, which allows pybind11 to deal with the
|
311 |
+
exception and pass it back to the Python interpreter. This includes calls to
|
312 |
+
the error setting functions such as ``PyErr_SetString``.
|
313 |
+
|
314 |
+
.. code-block:: cpp
|
315 |
+
|
316 |
+
PyErr_SetString(PyExc_TypeError, "C API type error demo");
|
317 |
+
throw py::error_already_set();
|
318 |
+
|
319 |
+
// But it would be easier to simply...
|
320 |
+
throw py::type_error("pybind11 wrapper type error");
|
321 |
+
|
322 |
+
Alternately, to ignore the error, call `PyErr_Clear
|
323 |
+
<https://docs.python.org/3/c-api/exceptions.html#c.PyErr_Clear>`_.
|
324 |
+
|
325 |
+
Any Python error must be thrown or cleared, or Python/pybind11 will be left in
|
326 |
+
an invalid state.
|
327 |
+
|
328 |
+
Chaining exceptions ('raise from')
|
329 |
+
==================================
|
330 |
+
|
331 |
+
In Python 3.3 a mechanism for indicating that exceptions were caused by other
|
332 |
+
exceptions was introduced:
|
333 |
+
|
334 |
+
.. code-block:: py
|
335 |
+
|
336 |
+
try:
|
337 |
+
print(1 / 0)
|
338 |
+
except Exception as exc:
|
339 |
+
raise RuntimeError("could not divide by zero") from exc
|
340 |
+
|
341 |
+
To do a similar thing in pybind11, you can use the ``py::raise_from`` function. It
|
342 |
+
sets the current python error indicator, so to continue propagating the exception
|
343 |
+
you should ``throw py::error_already_set()`` (Python 3 only).
|
344 |
+
|
345 |
+
.. code-block:: cpp
|
346 |
+
|
347 |
+
try {
|
348 |
+
py::eval("print(1 / 0"));
|
349 |
+
} catch (py::error_already_set &e) {
|
350 |
+
py::raise_from(e, PyExc_RuntimeError, "could not divide by zero");
|
351 |
+
throw py::error_already_set();
|
352 |
+
}
|
353 |
+
|
354 |
+
.. versionadded:: 2.8
|
355 |
+
|
356 |
+
.. _unraisable_exceptions:
|
357 |
+
|
358 |
+
Handling unraisable exceptions
|
359 |
+
==============================
|
360 |
+
|
361 |
+
If a Python function invoked from a C++ destructor or any function marked
|
362 |
+
``noexcept(true)`` (collectively, "noexcept functions") throws an exception, there
|
363 |
+
is no way to propagate the exception, as such functions may not throw.
|
364 |
+
Should they throw or fail to catch any exceptions in their call graph,
|
365 |
+
the C++ runtime calls ``std::terminate()`` to abort immediately.
|
366 |
+
|
367 |
+
Similarly, Python exceptions raised in a class's ``__del__`` method do not
|
368 |
+
propagate, but are logged by Python as an unraisable error. In Python 3.8+, a
|
369 |
+
`system hook is triggered
|
370 |
+
<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`_
|
371 |
+
and an auditing event is logged.
|
372 |
+
|
373 |
+
Any noexcept function should have a try-catch block that traps
|
374 |
+
class:`error_already_set` (or any other exception that can occur). Note that
|
375 |
+
pybind11 wrappers around Python exceptions such as
|
376 |
+
:class:`pybind11::value_error` are *not* Python exceptions; they are C++
|
377 |
+
exceptions that pybind11 catches and converts to Python exceptions. Noexcept
|
378 |
+
functions cannot propagate these exceptions either. A useful approach is to
|
379 |
+
convert them to Python exceptions and then ``discard_as_unraisable`` as shown
|
380 |
+
below.
|
381 |
+
|
382 |
+
.. code-block:: cpp
|
383 |
+
|
384 |
+
void nonthrowing_func() noexcept(true) {
|
385 |
+
try {
|
386 |
+
// ...
|
387 |
+
} catch (py::error_already_set &eas) {
|
388 |
+
// Discard the Python error using Python APIs, using the C++ magic
|
389 |
+
// variable __func__. Python already knows the type and value and of the
|
390 |
+
// exception object.
|
391 |
+
eas.discard_as_unraisable(__func__);
|
392 |
+
} catch (const std::exception &e) {
|
393 |
+
// Log and discard C++ exceptions.
|
394 |
+
third_party::log(e);
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
.. versionadded:: 2.6
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/functions.rst
ADDED
@@ -0,0 +1,615 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Functions
|
2 |
+
#########
|
3 |
+
|
4 |
+
Before proceeding with this section, make sure that you are already familiar
|
5 |
+
with the basics of binding functions and classes, as explained in :doc:`/basics`
|
6 |
+
and :doc:`/classes`. The following guide is applicable to both free and member
|
7 |
+
functions, i.e. *methods* in Python.
|
8 |
+
|
9 |
+
.. _return_value_policies:
|
10 |
+
|
11 |
+
Return value policies
|
12 |
+
=====================
|
13 |
+
|
14 |
+
Python and C++ use fundamentally different ways of managing the memory and
|
15 |
+
lifetime of objects managed by them. This can lead to issues when creating
|
16 |
+
bindings for functions that return a non-trivial type. Just by looking at the
|
17 |
+
type information, it is not clear whether Python should take charge of the
|
18 |
+
returned value and eventually free its resources, or if this is handled on the
|
19 |
+
C++ side. For this reason, pybind11 provides a several *return value policy*
|
20 |
+
annotations that can be passed to the :func:`module_::def` and
|
21 |
+
:func:`class_::def` functions. The default policy is
|
22 |
+
:enum:`return_value_policy::automatic`.
|
23 |
+
|
24 |
+
Return value policies are tricky, and it's very important to get them right.
|
25 |
+
Just to illustrate what can go wrong, consider the following simple example:
|
26 |
+
|
27 |
+
.. code-block:: cpp
|
28 |
+
|
29 |
+
/* Function declaration */
|
30 |
+
Data *get_data() { return _data; /* (pointer to a static data structure) */ }
|
31 |
+
...
|
32 |
+
|
33 |
+
/* Binding code */
|
34 |
+
m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python
|
35 |
+
|
36 |
+
What's going on here? When ``get_data()`` is called from Python, the return
|
37 |
+
value (a native C++ type) must be wrapped to turn it into a usable Python type.
|
38 |
+
In this case, the default return value policy (:enum:`return_value_policy::automatic`)
|
39 |
+
causes pybind11 to assume ownership of the static ``_data`` instance.
|
40 |
+
|
41 |
+
When Python's garbage collector eventually deletes the Python
|
42 |
+
wrapper, pybind11 will also attempt to delete the C++ instance (via ``operator
|
43 |
+
delete()``) due to the implied ownership. At this point, the entire application
|
44 |
+
will come crashing down, though errors could also be more subtle and involve
|
45 |
+
silent data corruption.
|
46 |
+
|
47 |
+
In the above example, the policy :enum:`return_value_policy::reference` should have
|
48 |
+
been specified so that the global data instance is only *referenced* without any
|
49 |
+
implied transfer of ownership, i.e.:
|
50 |
+
|
51 |
+
.. code-block:: cpp
|
52 |
+
|
53 |
+
m.def("get_data", &get_data, py::return_value_policy::reference);
|
54 |
+
|
55 |
+
On the other hand, this is not the right policy for many other situations,
|
56 |
+
where ignoring ownership could lead to resource leaks.
|
57 |
+
As a developer using pybind11, it's important to be familiar with the different
|
58 |
+
return value policies, including which situation calls for which one of them.
|
59 |
+
The following table provides an overview of available policies:
|
60 |
+
|
61 |
+
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
62 |
+
|
63 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
64 |
+
| Return value policy | Description |
|
65 |
+
+==================================================+============================================================================+
|
66 |
+
| :enum:`return_value_policy::take_ownership` | Reference an existing object (i.e. do not create a new copy) and take |
|
67 |
+
| | ownership. Python will call the destructor and delete operator when the |
|
68 |
+
| | object's reference count reaches zero. Undefined behavior ensues when the |
|
69 |
+
| | C++ side does the same, or when the data was not dynamically allocated. |
|
70 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
71 |
+
| :enum:`return_value_policy::copy` | Create a new copy of the returned object, which will be owned by Python. |
|
72 |
+
| | This policy is comparably safe because the lifetimes of the two instances |
|
73 |
+
| | are decoupled. |
|
74 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
75 |
+
| :enum:`return_value_policy::move` | Use ``std::move`` to move the return value contents into a new instance |
|
76 |
+
| | that will be owned by Python. This policy is comparably safe because the |
|
77 |
+
| | lifetimes of the two instances (move source and destination) are decoupled.|
|
78 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
79 |
+
| :enum:`return_value_policy::reference` | Reference an existing object, but do not take ownership. The C++ side is |
|
80 |
+
| | responsible for managing the object's lifetime and deallocating it when |
|
81 |
+
| | it is no longer used. Warning: undefined behavior will ensue when the C++ |
|
82 |
+
| | side deletes an object that is still referenced and used by Python. |
|
83 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
84 |
+
| :enum:`return_value_policy::reference_internal` | Indicates that the lifetime of the return value is tied to the lifetime |
|
85 |
+
| | of a parent object, namely the implicit ``this``, or ``self`` argument of |
|
86 |
+
| | the called method or property. Internally, this policy works just like |
|
87 |
+
| | :enum:`return_value_policy::reference` but additionally applies a |
|
88 |
+
| | ``keep_alive<0, 1>`` *call policy* (described in the next section) that |
|
89 |
+
| | prevents the parent object from being garbage collected as long as the |
|
90 |
+
| | return value is referenced by Python. This is the default policy for |
|
91 |
+
| | property getters created via ``def_property``, ``def_readwrite``, etc. |
|
92 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
93 |
+
| :enum:`return_value_policy::automatic` | This policy falls back to the policy |
|
94 |
+
| | :enum:`return_value_policy::take_ownership` when the return value is a |
|
95 |
+
| | pointer. Otherwise, it uses :enum:`return_value_policy::move` or |
|
96 |
+
| | :enum:`return_value_policy::copy` for rvalue and lvalue references, |
|
97 |
+
| | respectively. See above for a description of what all of these different |
|
98 |
+
| | policies do. This is the default policy for ``py::class_``-wrapped types. |
|
99 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
100 |
+
| :enum:`return_value_policy::automatic_reference` | As above, but use policy :enum:`return_value_policy::reference` when the |
|
101 |
+
| | return value is a pointer. This is the default conversion policy for |
|
102 |
+
| | function arguments when calling Python functions manually from C++ code |
|
103 |
+
| | (i.e. via ``handle::operator()``) and the casters in ``pybind11/stl.h``. |
|
104 |
+
| | You probably won't need to use this explicitly. |
|
105 |
+
+--------------------------------------------------+----------------------------------------------------------------------------+
|
106 |
+
|
107 |
+
Return value policies can also be applied to properties:
|
108 |
+
|
109 |
+
.. code-block:: cpp
|
110 |
+
|
111 |
+
class_<MyClass>(m, "MyClass")
|
112 |
+
.def_property("data", &MyClass::getData, &MyClass::setData,
|
113 |
+
py::return_value_policy::copy);
|
114 |
+
|
115 |
+
Technically, the code above applies the policy to both the getter and the
|
116 |
+
setter function, however, the setter doesn't really care about *return*
|
117 |
+
value policies which makes this a convenient terse syntax. Alternatively,
|
118 |
+
targeted arguments can be passed through the :class:`cpp_function` constructor:
|
119 |
+
|
120 |
+
.. code-block:: cpp
|
121 |
+
|
122 |
+
class_<MyClass>(m, "MyClass")
|
123 |
+
.def_property("data",
|
124 |
+
py::cpp_function(&MyClass::getData, py::return_value_policy::copy),
|
125 |
+
py::cpp_function(&MyClass::setData)
|
126 |
+
);
|
127 |
+
|
128 |
+
.. warning::
|
129 |
+
|
130 |
+
Code with invalid return value policies might access uninitialized memory or
|
131 |
+
free data structures multiple times, which can lead to hard-to-debug
|
132 |
+
non-determinism and segmentation faults, hence it is worth spending the
|
133 |
+
time to understand all the different options in the table above.
|
134 |
+
|
135 |
+
.. note::
|
136 |
+
|
137 |
+
One important aspect of the above policies is that they only apply to
|
138 |
+
instances which pybind11 has *not* seen before, in which case the policy
|
139 |
+
clarifies essential questions about the return value's lifetime and
|
140 |
+
ownership. When pybind11 knows the instance already (as identified by its
|
141 |
+
type and address in memory), it will return the existing Python object
|
142 |
+
wrapper rather than creating a new copy.
|
143 |
+
|
144 |
+
.. note::
|
145 |
+
|
146 |
+
The next section on :ref:`call_policies` discusses *call policies* that can be
|
147 |
+
specified *in addition* to a return value policy from the list above. Call
|
148 |
+
policies indicate reference relationships that can involve both return values
|
149 |
+
and parameters of functions.
|
150 |
+
|
151 |
+
.. note::
|
152 |
+
|
153 |
+
As an alternative to elaborate call policies and lifetime management logic,
|
154 |
+
consider using smart pointers (see the section on :ref:`smart_pointers` for
|
155 |
+
details). Smart pointers can tell whether an object is still referenced from
|
156 |
+
C++ or Python, which generally eliminates the kinds of inconsistencies that
|
157 |
+
can lead to crashes or undefined behavior. For functions returning smart
|
158 |
+
pointers, it is not necessary to specify a return value policy.
|
159 |
+
|
160 |
+
.. _call_policies:
|
161 |
+
|
162 |
+
Additional call policies
|
163 |
+
========================
|
164 |
+
|
165 |
+
In addition to the above return value policies, further *call policies* can be
|
166 |
+
specified to indicate dependencies between parameters or ensure a certain state
|
167 |
+
for the function call.
|
168 |
+
|
169 |
+
Keep alive
|
170 |
+
----------
|
171 |
+
|
172 |
+
In general, this policy is required when the C++ object is any kind of container
|
173 |
+
and another object is being added to the container. ``keep_alive<Nurse, Patient>``
|
174 |
+
indicates that the argument with index ``Patient`` should be kept alive at least
|
175 |
+
until the argument with index ``Nurse`` is freed by the garbage collector. Argument
|
176 |
+
indices start at one, while zero refers to the return value. For methods, index
|
177 |
+
``1`` refers to the implicit ``this`` pointer, while regular arguments begin at
|
178 |
+
index ``2``. Arbitrarily many call policies can be specified. When a ``Nurse``
|
179 |
+
with value ``None`` is detected at runtime, the call policy does nothing.
|
180 |
+
|
181 |
+
When the nurse is not a pybind11-registered type, the implementation internally
|
182 |
+
relies on the ability to create a *weak reference* to the nurse object. When
|
183 |
+
the nurse object is not a pybind11-registered type and does not support weak
|
184 |
+
references, an exception will be thrown.
|
185 |
+
|
186 |
+
If you use an incorrect argument index, you will get a ``RuntimeError`` saying
|
187 |
+
``Could not activate keep_alive!``. You should review the indices you're using.
|
188 |
+
|
189 |
+
Consider the following example: here, the binding code for a list append
|
190 |
+
operation ties the lifetime of the newly added element to the underlying
|
191 |
+
container:
|
192 |
+
|
193 |
+
.. code-block:: cpp
|
194 |
+
|
195 |
+
py::class_<List>(m, "List")
|
196 |
+
.def("append", &List::append, py::keep_alive<1, 2>());
|
197 |
+
|
198 |
+
For consistency, the argument indexing is identical for constructors. Index
|
199 |
+
``1`` still refers to the implicit ``this`` pointer, i.e. the object which is
|
200 |
+
being constructed. Index ``0`` refers to the return type which is presumed to
|
201 |
+
be ``void`` when a constructor is viewed like a function. The following example
|
202 |
+
ties the lifetime of the constructor element to the constructed object:
|
203 |
+
|
204 |
+
.. code-block:: cpp
|
205 |
+
|
206 |
+
py::class_<Nurse>(m, "Nurse")
|
207 |
+
.def(py::init<Patient &>(), py::keep_alive<1, 2>());
|
208 |
+
|
209 |
+
.. note::
|
210 |
+
|
211 |
+
``keep_alive`` is analogous to the ``with_custodian_and_ward`` (if Nurse,
|
212 |
+
Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient ==
|
213 |
+
0) policies from Boost.Python.
|
214 |
+
|
215 |
+
Call guard
|
216 |
+
----------
|
217 |
+
|
218 |
+
The ``call_guard<T>`` policy allows any scope guard type ``T`` to be placed
|
219 |
+
around the function call. For example, this definition:
|
220 |
+
|
221 |
+
.. code-block:: cpp
|
222 |
+
|
223 |
+
m.def("foo", foo, py::call_guard<T>());
|
224 |
+
|
225 |
+
is equivalent to the following pseudocode:
|
226 |
+
|
227 |
+
.. code-block:: cpp
|
228 |
+
|
229 |
+
m.def("foo", [](args...) {
|
230 |
+
T scope_guard;
|
231 |
+
return foo(args...); // forwarded arguments
|
232 |
+
});
|
233 |
+
|
234 |
+
The only requirement is that ``T`` is default-constructible, but otherwise any
|
235 |
+
scope guard will work. This is very useful in combination with ``gil_scoped_release``.
|
236 |
+
See :ref:`gil`.
|
237 |
+
|
238 |
+
Multiple guards can also be specified as ``py::call_guard<T1, T2, T3...>``. The
|
239 |
+
constructor order is left to right and destruction happens in reverse.
|
240 |
+
|
241 |
+
.. seealso::
|
242 |
+
|
243 |
+
The file :file:`tests/test_call_policies.cpp` contains a complete example
|
244 |
+
that demonstrates using `keep_alive` and `call_guard` in more detail.
|
245 |
+
|
246 |
+
.. _python_objects_as_args:
|
247 |
+
|
248 |
+
Python objects as arguments
|
249 |
+
===========================
|
250 |
+
|
251 |
+
pybind11 exposes all major Python types using thin C++ wrapper classes. These
|
252 |
+
wrapper classes can also be used as parameters of functions in bindings, which
|
253 |
+
makes it possible to directly work with native Python types on the C++ side.
|
254 |
+
For instance, the following statement iterates over a Python ``dict``:
|
255 |
+
|
256 |
+
.. code-block:: cpp
|
257 |
+
|
258 |
+
void print_dict(const py::dict& dict) {
|
259 |
+
/* Easily interact with Python types */
|
260 |
+
for (auto item : dict)
|
261 |
+
std::cout << "key=" << std::string(py::str(item.first)) << ", "
|
262 |
+
<< "value=" << std::string(py::str(item.second)) << std::endl;
|
263 |
+
}
|
264 |
+
|
265 |
+
It can be exported:
|
266 |
+
|
267 |
+
.. code-block:: cpp
|
268 |
+
|
269 |
+
m.def("print_dict", &print_dict);
|
270 |
+
|
271 |
+
And used in Python as usual:
|
272 |
+
|
273 |
+
.. code-block:: pycon
|
274 |
+
|
275 |
+
>>> print_dict({"foo": 123, "bar": "hello"})
|
276 |
+
key=foo, value=123
|
277 |
+
key=bar, value=hello
|
278 |
+
|
279 |
+
For more information on using Python objects in C++, see :doc:`/advanced/pycpp/index`.
|
280 |
+
|
281 |
+
Accepting \*args and \*\*kwargs
|
282 |
+
===============================
|
283 |
+
|
284 |
+
Python provides a useful mechanism to define functions that accept arbitrary
|
285 |
+
numbers of arguments and keyword arguments:
|
286 |
+
|
287 |
+
.. code-block:: python
|
288 |
+
|
289 |
+
def generic(*args, **kwargs):
|
290 |
+
... # do something with args and kwargs
|
291 |
+
|
292 |
+
Such functions can also be created using pybind11:
|
293 |
+
|
294 |
+
.. code-block:: cpp
|
295 |
+
|
296 |
+
void generic(py::args args, const py::kwargs& kwargs) {
|
297 |
+
/// .. do something with args
|
298 |
+
if (kwargs)
|
299 |
+
/// .. do something with kwargs
|
300 |
+
}
|
301 |
+
|
302 |
+
/// Binding code
|
303 |
+
m.def("generic", &generic);
|
304 |
+
|
305 |
+
The class ``py::args`` derives from ``py::tuple`` and ``py::kwargs`` derives
|
306 |
+
from ``py::dict``.
|
307 |
+
|
308 |
+
You may also use just one or the other, and may combine these with other
|
309 |
+
arguments. Note, however, that ``py::kwargs`` must always be the last argument
|
310 |
+
of the function, and ``py::args`` implies that any further arguments are
|
311 |
+
keyword-only (see :ref:`keyword_only_arguments`).
|
312 |
+
|
313 |
+
Please refer to the other examples for details on how to iterate over these,
|
314 |
+
and on how to cast their entries into C++ objects. A demonstration is also
|
315 |
+
available in ``tests/test_kwargs_and_defaults.cpp``.
|
316 |
+
|
317 |
+
.. note::
|
318 |
+
|
319 |
+
When combining \*args or \*\*kwargs with :ref:`keyword_args` you should
|
320 |
+
*not* include ``py::arg`` tags for the ``py::args`` and ``py::kwargs``
|
321 |
+
arguments.
|
322 |
+
|
323 |
+
Default arguments revisited
|
324 |
+
===========================
|
325 |
+
|
326 |
+
The section on :ref:`default_args` previously discussed basic usage of default
|
327 |
+
arguments using pybind11. One noteworthy aspect of their implementation is that
|
328 |
+
default arguments are converted to Python objects right at declaration time.
|
329 |
+
Consider the following example:
|
330 |
+
|
331 |
+
.. code-block:: cpp
|
332 |
+
|
333 |
+
py::class_<MyClass>("MyClass")
|
334 |
+
.def("myFunction", py::arg("arg") = SomeType(123));
|
335 |
+
|
336 |
+
In this case, pybind11 must already be set up to deal with values of the type
|
337 |
+
``SomeType`` (via a prior instantiation of ``py::class_<SomeType>``), or an
|
338 |
+
exception will be thrown.
|
339 |
+
|
340 |
+
Another aspect worth highlighting is that the "preview" of the default argument
|
341 |
+
in the function signature is generated using the object's ``__repr__`` method.
|
342 |
+
If not available, the signature may not be very helpful, e.g.:
|
343 |
+
|
344 |
+
.. code-block:: pycon
|
345 |
+
|
346 |
+
FUNCTIONS
|
347 |
+
...
|
348 |
+
| myFunction(...)
|
349 |
+
| Signature : (MyClass, arg : SomeType = <SomeType object at 0x101b7b080>) -> NoneType
|
350 |
+
...
|
351 |
+
|
352 |
+
The first way of addressing this is by defining ``SomeType.__repr__``.
|
353 |
+
Alternatively, it is possible to specify the human-readable preview of the
|
354 |
+
default argument manually using the ``arg_v`` notation:
|
355 |
+
|
356 |
+
.. code-block:: cpp
|
357 |
+
|
358 |
+
py::class_<MyClass>("MyClass")
|
359 |
+
.def("myFunction", py::arg_v("arg", SomeType(123), "SomeType(123)"));
|
360 |
+
|
361 |
+
Sometimes it may be necessary to pass a null pointer value as a default
|
362 |
+
argument. In this case, remember to cast it to the underlying type in question,
|
363 |
+
like so:
|
364 |
+
|
365 |
+
.. code-block:: cpp
|
366 |
+
|
367 |
+
py::class_<MyClass>("MyClass")
|
368 |
+
.def("myFunction", py::arg("arg") = static_cast<SomeType *>(nullptr));
|
369 |
+
|
370 |
+
.. _keyword_only_arguments:
|
371 |
+
|
372 |
+
Keyword-only arguments
|
373 |
+
======================
|
374 |
+
|
375 |
+
Python 3 introduced keyword-only arguments by specifying an unnamed ``*``
|
376 |
+
argument in a function definition:
|
377 |
+
|
378 |
+
.. code-block:: python
|
379 |
+
|
380 |
+
def f(a, *, b): # a can be positional or via keyword; b must be via keyword
|
381 |
+
pass
|
382 |
+
|
383 |
+
|
384 |
+
f(a=1, b=2) # good
|
385 |
+
f(b=2, a=1) # good
|
386 |
+
f(1, b=2) # good
|
387 |
+
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
|
388 |
+
|
389 |
+
Pybind11 provides a ``py::kw_only`` object that allows you to implement
|
390 |
+
the same behaviour by specifying the object between positional and keyword-only
|
391 |
+
argument annotations when registering the function:
|
392 |
+
|
393 |
+
.. code-block:: cpp
|
394 |
+
|
395 |
+
m.def("f", [](int a, int b) { /* ... */ },
|
396 |
+
py::arg("a"), py::kw_only(), py::arg("b"));
|
397 |
+
|
398 |
+
Note that you currently cannot combine this with a ``py::args`` argument. This
|
399 |
+
feature does *not* require Python 3 to work.
|
400 |
+
|
401 |
+
.. versionadded:: 2.6
|
402 |
+
|
403 |
+
As of pybind11 2.9, a ``py::args`` argument implies that any following arguments
|
404 |
+
are keyword-only, as if ``py::kw_only()`` had been specified in the same
|
405 |
+
relative location of the argument list as the ``py::args`` argument. The
|
406 |
+
``py::kw_only()`` may be included to be explicit about this, but is not
|
407 |
+
required. (Prior to 2.9 ``py::args`` may only occur at the end of the argument
|
408 |
+
list, or immediately before a ``py::kwargs`` argument at the end).
|
409 |
+
|
410 |
+
.. versionadded:: 2.9
|
411 |
+
|
412 |
+
Positional-only arguments
|
413 |
+
=========================
|
414 |
+
|
415 |
+
Python 3.8 introduced a new positional-only argument syntax, using ``/`` in the
|
416 |
+
function definition (note that this has been a convention for CPython
|
417 |
+
positional arguments, such as in ``pow()``, since Python 2). You can
|
418 |
+
do the same thing in any version of Python using ``py::pos_only()``:
|
419 |
+
|
420 |
+
.. code-block:: cpp
|
421 |
+
|
422 |
+
m.def("f", [](int a, int b) { /* ... */ },
|
423 |
+
py::arg("a"), py::pos_only(), py::arg("b"));
|
424 |
+
|
425 |
+
You now cannot give argument ``a`` by keyword. This can be combined with
|
426 |
+
keyword-only arguments, as well.
|
427 |
+
|
428 |
+
.. versionadded:: 2.6
|
429 |
+
|
430 |
+
.. _nonconverting_arguments:
|
431 |
+
|
432 |
+
Non-converting arguments
|
433 |
+
========================
|
434 |
+
|
435 |
+
Certain argument types may support conversion from one type to another. Some
|
436 |
+
examples of conversions are:
|
437 |
+
|
438 |
+
* :ref:`implicit_conversions` declared using ``py::implicitly_convertible<A,B>()``
|
439 |
+
* Calling a method accepting a double with an integer argument
|
440 |
+
* Calling a ``std::complex<float>`` argument with a non-complex python type
|
441 |
+
(for example, with a float). (Requires the optional ``pybind11/complex.h``
|
442 |
+
header).
|
443 |
+
* Calling a function taking an Eigen matrix reference with a numpy array of the
|
444 |
+
wrong type or of an incompatible data layout. (Requires the optional
|
445 |
+
``pybind11/eigen.h`` header).
|
446 |
+
|
447 |
+
This behaviour is sometimes undesirable: the binding code may prefer to raise
|
448 |
+
an error rather than convert the argument. This behaviour can be obtained
|
449 |
+
through ``py::arg`` by calling the ``.noconvert()`` method of the ``py::arg``
|
450 |
+
object, such as:
|
451 |
+
|
452 |
+
.. code-block:: cpp
|
453 |
+
|
454 |
+
m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
|
455 |
+
m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
|
456 |
+
|
457 |
+
Attempting the call the second function (the one without ``.noconvert()``) with
|
458 |
+
an integer will succeed, but attempting to call the ``.noconvert()`` version
|
459 |
+
will fail with a ``TypeError``:
|
460 |
+
|
461 |
+
.. code-block:: pycon
|
462 |
+
|
463 |
+
>>> floats_preferred(4)
|
464 |
+
2.0
|
465 |
+
>>> floats_only(4)
|
466 |
+
Traceback (most recent call last):
|
467 |
+
File "<stdin>", line 1, in <module>
|
468 |
+
TypeError: floats_only(): incompatible function arguments. The following argument types are supported:
|
469 |
+
1. (f: float) -> float
|
470 |
+
|
471 |
+
Invoked with: 4
|
472 |
+
|
473 |
+
You may, of course, combine this with the :var:`_a` shorthand notation (see
|
474 |
+
:ref:`keyword_args`) and/or :ref:`default_args`. It is also permitted to omit
|
475 |
+
the argument name by using the ``py::arg()`` constructor without an argument
|
476 |
+
name, i.e. by specifying ``py::arg().noconvert()``.
|
477 |
+
|
478 |
+
.. note::
|
479 |
+
|
480 |
+
When specifying ``py::arg`` options it is necessary to provide the same
|
481 |
+
number of options as the bound function has arguments. Thus if you want to
|
482 |
+
enable no-convert behaviour for just one of several arguments, you will
|
483 |
+
need to specify a ``py::arg()`` annotation for each argument with the
|
484 |
+
no-convert argument modified to ``py::arg().noconvert()``.
|
485 |
+
|
486 |
+
.. _none_arguments:
|
487 |
+
|
488 |
+
Allow/Prohibiting None arguments
|
489 |
+
================================
|
490 |
+
|
491 |
+
When a C++ type registered with :class:`py::class_` is passed as an argument to
|
492 |
+
a function taking the instance as pointer or shared holder (e.g. ``shared_ptr``
|
493 |
+
or a custom, copyable holder as described in :ref:`smart_pointers`), pybind
|
494 |
+
allows ``None`` to be passed from Python which results in calling the C++
|
495 |
+
function with ``nullptr`` (or an empty holder) for the argument.
|
496 |
+
|
497 |
+
To explicitly enable or disable this behaviour, using the
|
498 |
+
``.none`` method of the :class:`py::arg` object:
|
499 |
+
|
500 |
+
.. code-block:: cpp
|
501 |
+
|
502 |
+
py::class_<Dog>(m, "Dog").def(py::init<>());
|
503 |
+
py::class_<Cat>(m, "Cat").def(py::init<>());
|
504 |
+
m.def("bark", [](Dog *dog) -> std::string {
|
505 |
+
if (dog) return "woof!"; /* Called with a Dog instance */
|
506 |
+
else return "(no dog)"; /* Called with None, dog == nullptr */
|
507 |
+
}, py::arg("dog").none(true));
|
508 |
+
m.def("meow", [](Cat *cat) -> std::string {
|
509 |
+
// Can't be called with None argument
|
510 |
+
return "meow";
|
511 |
+
}, py::arg("cat").none(false));
|
512 |
+
|
513 |
+
With the above, the Python call ``bark(None)`` will return the string ``"(no
|
514 |
+
dog)"``, while attempting to call ``meow(None)`` will raise a ``TypeError``:
|
515 |
+
|
516 |
+
.. code-block:: pycon
|
517 |
+
|
518 |
+
>>> from animals import Dog, Cat, bark, meow
|
519 |
+
>>> bark(Dog())
|
520 |
+
'woof!'
|
521 |
+
>>> meow(Cat())
|
522 |
+
'meow'
|
523 |
+
>>> bark(None)
|
524 |
+
'(no dog)'
|
525 |
+
>>> meow(None)
|
526 |
+
Traceback (most recent call last):
|
527 |
+
File "<stdin>", line 1, in <module>
|
528 |
+
TypeError: meow(): incompatible function arguments. The following argument types are supported:
|
529 |
+
1. (cat: animals.Cat) -> str
|
530 |
+
|
531 |
+
Invoked with: None
|
532 |
+
|
533 |
+
The default behaviour when the tag is unspecified is to allow ``None``.
|
534 |
+
|
535 |
+
.. note::
|
536 |
+
|
537 |
+
Even when ``.none(true)`` is specified for an argument, ``None`` will be converted to a
|
538 |
+
``nullptr`` *only* for custom and :ref:`opaque <opaque>` types. Pointers to built-in types
|
539 |
+
(``double *``, ``int *``, ...) and STL types (``std::vector<T> *``, ...; if ``pybind11/stl.h``
|
540 |
+
is included) are copied when converted to C++ (see :doc:`/advanced/cast/overview`) and will
|
541 |
+
not allow ``None`` as argument. To pass optional argument of these copied types consider
|
542 |
+
using ``std::optional<T>``
|
543 |
+
|
544 |
+
.. _overload_resolution:
|
545 |
+
|
546 |
+
Overload resolution order
|
547 |
+
=========================
|
548 |
+
|
549 |
+
When a function or method with multiple overloads is called from Python,
|
550 |
+
pybind11 determines which overload to call in two passes. The first pass
|
551 |
+
attempts to call each overload without allowing argument conversion (as if
|
552 |
+
every argument had been specified as ``py::arg().noconvert()`` as described
|
553 |
+
above).
|
554 |
+
|
555 |
+
If no overload succeeds in the no-conversion first pass, a second pass is
|
556 |
+
attempted in which argument conversion is allowed (except where prohibited via
|
557 |
+
an explicit ``py::arg().noconvert()`` attribute in the function definition).
|
558 |
+
|
559 |
+
If the second pass also fails a ``TypeError`` is raised.
|
560 |
+
|
561 |
+
Within each pass, overloads are tried in the order they were registered with
|
562 |
+
pybind11. If the ``py::prepend()`` tag is added to the definition, a function
|
563 |
+
can be placed at the beginning of the overload sequence instead, allowing user
|
564 |
+
overloads to proceed built in functions.
|
565 |
+
|
566 |
+
What this means in practice is that pybind11 will prefer any overload that does
|
567 |
+
not require conversion of arguments to an overload that does, but otherwise
|
568 |
+
prefers earlier-defined overloads to later-defined ones.
|
569 |
+
|
570 |
+
.. note::
|
571 |
+
|
572 |
+
pybind11 does *not* further prioritize based on the number/pattern of
|
573 |
+
overloaded arguments. That is, pybind11 does not prioritize a function
|
574 |
+
requiring one conversion over one requiring three, but only prioritizes
|
575 |
+
overloads requiring no conversion at all to overloads that require
|
576 |
+
conversion of at least one argument.
|
577 |
+
|
578 |
+
.. versionadded:: 2.6
|
579 |
+
|
580 |
+
The ``py::prepend()`` tag.
|
581 |
+
|
582 |
+
Binding functions with template parameters
|
583 |
+
==========================================
|
584 |
+
|
585 |
+
You can bind functions that have template parameters. Here's a function:
|
586 |
+
|
587 |
+
.. code-block:: cpp
|
588 |
+
|
589 |
+
template <typename T>
|
590 |
+
void set(T t);
|
591 |
+
|
592 |
+
C++ templates cannot be instantiated at runtime, so you cannot bind the
|
593 |
+
non-instantiated function:
|
594 |
+
|
595 |
+
.. code-block:: cpp
|
596 |
+
|
597 |
+
// BROKEN (this will not compile)
|
598 |
+
m.def("set", &set);
|
599 |
+
|
600 |
+
You must bind each instantiated function template separately. You may bind
|
601 |
+
each instantiation with the same name, which will be treated the same as
|
602 |
+
an overloaded function:
|
603 |
+
|
604 |
+
.. code-block:: cpp
|
605 |
+
|
606 |
+
m.def("set", &set<int>);
|
607 |
+
m.def("set", &set<std::string>);
|
608 |
+
|
609 |
+
Sometimes it's more clear to bind them with separate names, which is also
|
610 |
+
an option:
|
611 |
+
|
612 |
+
.. code-block:: cpp
|
613 |
+
|
614 |
+
m.def("setInt", &set<int>);
|
615 |
+
m.def("setString", &set<std::string>);
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/misc.rst
ADDED
@@ -0,0 +1,337 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Miscellaneous
|
2 |
+
#############
|
3 |
+
|
4 |
+
.. _macro_notes:
|
5 |
+
|
6 |
+
General notes regarding convenience macros
|
7 |
+
==========================================
|
8 |
+
|
9 |
+
pybind11 provides a few convenience macros such as
|
10 |
+
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERRIDE_*``. Since these
|
11 |
+
are "just" macros that are evaluated in the preprocessor (which has no concept
|
12 |
+
of types), they *will* get confused by commas in a template argument; for
|
13 |
+
example, consider:
|
14 |
+
|
15 |
+
.. code-block:: cpp
|
16 |
+
|
17 |
+
PYBIND11_OVERRIDE(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
18 |
+
|
19 |
+
The limitation of the C preprocessor interprets this as five arguments (with new
|
20 |
+
arguments beginning after each comma) rather than three. To get around this,
|
21 |
+
there are two alternatives: you can use a type alias, or you can wrap the type
|
22 |
+
using the ``PYBIND11_TYPE`` macro:
|
23 |
+
|
24 |
+
.. code-block:: cpp
|
25 |
+
|
26 |
+
// Version 1: using a type alias
|
27 |
+
using ReturnType = MyReturnType<T1, T2>;
|
28 |
+
using ClassType = Class<T3, T4>;
|
29 |
+
PYBIND11_OVERRIDE(ReturnType, ClassType, func);
|
30 |
+
|
31 |
+
// Version 2: using the PYBIND11_TYPE macro:
|
32 |
+
PYBIND11_OVERRIDE(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
33 |
+
PYBIND11_TYPE(Class<T3, T4>), func)
|
34 |
+
|
35 |
+
The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
|
36 |
+
|
37 |
+
.. _gil:
|
38 |
+
|
39 |
+
Global Interpreter Lock (GIL)
|
40 |
+
=============================
|
41 |
+
|
42 |
+
When calling a C++ function from Python, the GIL is always held.
|
43 |
+
The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be
|
44 |
+
used to acquire and release the global interpreter lock in the body of a C++
|
45 |
+
function call. In this way, long-running C++ code can be parallelized using
|
46 |
+
multiple Python threads. Taking :ref:`overriding_virtuals` as an example, this
|
47 |
+
could be realized as follows (important changes highlighted):
|
48 |
+
|
49 |
+
.. code-block:: cpp
|
50 |
+
:emphasize-lines: 8,9,31,32
|
51 |
+
|
52 |
+
class PyAnimal : public Animal {
|
53 |
+
public:
|
54 |
+
/* Inherit the constructors */
|
55 |
+
using Animal::Animal;
|
56 |
+
|
57 |
+
/* Trampoline (need one for each virtual function) */
|
58 |
+
std::string go(int n_times) {
|
59 |
+
/* Acquire GIL before calling Python code */
|
60 |
+
py::gil_scoped_acquire acquire;
|
61 |
+
|
62 |
+
PYBIND11_OVERRIDE_PURE(
|
63 |
+
std::string, /* Return type */
|
64 |
+
Animal, /* Parent class */
|
65 |
+
go, /* Name of function */
|
66 |
+
n_times /* Argument(s) */
|
67 |
+
);
|
68 |
+
}
|
69 |
+
};
|
70 |
+
|
71 |
+
PYBIND11_MODULE(example, m) {
|
72 |
+
py::class_<Animal, PyAnimal> animal(m, "Animal");
|
73 |
+
animal
|
74 |
+
.def(py::init<>())
|
75 |
+
.def("go", &Animal::go);
|
76 |
+
|
77 |
+
py::class_<Dog>(m, "Dog", animal)
|
78 |
+
.def(py::init<>());
|
79 |
+
|
80 |
+
m.def("call_go", [](Animal *animal) -> std::string {
|
81 |
+
/* Release GIL before calling into (potentially long-running) C++ code */
|
82 |
+
py::gil_scoped_release release;
|
83 |
+
return call_go(animal);
|
84 |
+
});
|
85 |
+
}
|
86 |
+
|
87 |
+
The ``call_go`` wrapper can also be simplified using the ``call_guard`` policy
|
88 |
+
(see :ref:`call_policies`) which yields the same result:
|
89 |
+
|
90 |
+
.. code-block:: cpp
|
91 |
+
|
92 |
+
m.def("call_go", &call_go, py::call_guard<py::gil_scoped_release>());
|
93 |
+
|
94 |
+
|
95 |
+
Binding sequence data types, iterators, the slicing protocol, etc.
|
96 |
+
==================================================================
|
97 |
+
|
98 |
+
Please refer to the supplemental example for details.
|
99 |
+
|
100 |
+
.. seealso::
|
101 |
+
|
102 |
+
The file :file:`tests/test_sequences_and_iterators.cpp` contains a
|
103 |
+
complete example that shows how to bind a sequence data type, including
|
104 |
+
length queries (``__len__``), iterators (``__iter__``), the slicing
|
105 |
+
protocol and other kinds of useful operations.
|
106 |
+
|
107 |
+
|
108 |
+
Partitioning code over multiple extension modules
|
109 |
+
=================================================
|
110 |
+
|
111 |
+
It's straightforward to split binding code over multiple extension modules,
|
112 |
+
while referencing types that are declared elsewhere. Everything "just" works
|
113 |
+
without any special precautions. One exception to this rule occurs when
|
114 |
+
extending a type declared in another extension module. Recall the basic example
|
115 |
+
from Section :ref:`inheritance`.
|
116 |
+
|
117 |
+
.. code-block:: cpp
|
118 |
+
|
119 |
+
py::class_<Pet> pet(m, "Pet");
|
120 |
+
pet.def(py::init<const std::string &>())
|
121 |
+
.def_readwrite("name", &Pet::name);
|
122 |
+
|
123 |
+
py::class_<Dog>(m, "Dog", pet /* <- specify parent */)
|
124 |
+
.def(py::init<const std::string &>())
|
125 |
+
.def("bark", &Dog::bark);
|
126 |
+
|
127 |
+
Suppose now that ``Pet`` bindings are defined in a module named ``basic``,
|
128 |
+
whereas the ``Dog`` bindings are defined somewhere else. The challenge is of
|
129 |
+
course that the variable ``pet`` is not available anymore though it is needed
|
130 |
+
to indicate the inheritance relationship to the constructor of ``class_<Dog>``.
|
131 |
+
However, it can be acquired as follows:
|
132 |
+
|
133 |
+
.. code-block:: cpp
|
134 |
+
|
135 |
+
py::object pet = (py::object) py::module_::import("basic").attr("Pet");
|
136 |
+
|
137 |
+
py::class_<Dog>(m, "Dog", pet)
|
138 |
+
.def(py::init<const std::string &>())
|
139 |
+
.def("bark", &Dog::bark);
|
140 |
+
|
141 |
+
Alternatively, you can specify the base class as a template parameter option to
|
142 |
+
``class_``, which performs an automated lookup of the corresponding Python
|
143 |
+
type. Like the above code, however, this also requires invoking the ``import``
|
144 |
+
function once to ensure that the pybind11 binding code of the module ``basic``
|
145 |
+
has been executed:
|
146 |
+
|
147 |
+
.. code-block:: cpp
|
148 |
+
|
149 |
+
py::module_::import("basic");
|
150 |
+
|
151 |
+
py::class_<Dog, Pet>(m, "Dog")
|
152 |
+
.def(py::init<const std::string &>())
|
153 |
+
.def("bark", &Dog::bark);
|
154 |
+
|
155 |
+
Naturally, both methods will fail when there are cyclic dependencies.
|
156 |
+
|
157 |
+
Note that pybind11 code compiled with hidden-by-default symbol visibility (e.g.
|
158 |
+
via the command line flag ``-fvisibility=hidden`` on GCC/Clang), which is
|
159 |
+
required for proper pybind11 functionality, can interfere with the ability to
|
160 |
+
access types defined in another extension module. Working around this requires
|
161 |
+
manually exporting types that are accessed by multiple extension modules;
|
162 |
+
pybind11 provides a macro to do just this:
|
163 |
+
|
164 |
+
.. code-block:: cpp
|
165 |
+
|
166 |
+
class PYBIND11_EXPORT Dog : public Animal {
|
167 |
+
...
|
168 |
+
};
|
169 |
+
|
170 |
+
Note also that it is possible (although would rarely be required) to share arbitrary
|
171 |
+
C++ objects between extension modules at runtime. Internal library data is shared
|
172 |
+
between modules using capsule machinery [#f6]_ which can be also utilized for
|
173 |
+
storing, modifying and accessing user-defined data. Note that an extension module
|
174 |
+
will "see" other extensions' data if and only if they were built with the same
|
175 |
+
pybind11 version. Consider the following example:
|
176 |
+
|
177 |
+
.. code-block:: cpp
|
178 |
+
|
179 |
+
auto data = reinterpret_cast<MyData *>(py::get_shared_data("mydata"));
|
180 |
+
if (!data)
|
181 |
+
data = static_cast<MyData *>(py::set_shared_data("mydata", new MyData(42)));
|
182 |
+
|
183 |
+
If the above snippet was used in several separately compiled extension modules,
|
184 |
+
the first one to be imported would create a ``MyData`` instance and associate
|
185 |
+
a ``"mydata"`` key with a pointer to it. Extensions that are imported later
|
186 |
+
would be then able to access the data behind the same pointer.
|
187 |
+
|
188 |
+
.. [#f6] https://docs.python.org/3/extending/extending.html#using-capsules
|
189 |
+
|
190 |
+
Module Destructors
|
191 |
+
==================
|
192 |
+
|
193 |
+
pybind11 does not provide an explicit mechanism to invoke cleanup code at
|
194 |
+
module destruction time. In rare cases where such functionality is required, it
|
195 |
+
is possible to emulate it using Python capsules or weak references with a
|
196 |
+
destruction callback.
|
197 |
+
|
198 |
+
.. code-block:: cpp
|
199 |
+
|
200 |
+
auto cleanup_callback = []() {
|
201 |
+
// perform cleanup here -- this function is called with the GIL held
|
202 |
+
};
|
203 |
+
|
204 |
+
m.add_object("_cleanup", py::capsule(cleanup_callback));
|
205 |
+
|
206 |
+
This approach has the potential downside that instances of classes exposed
|
207 |
+
within the module may still be alive when the cleanup callback is invoked
|
208 |
+
(whether this is acceptable will generally depend on the application).
|
209 |
+
|
210 |
+
Alternatively, the capsule may also be stashed within a type object, which
|
211 |
+
ensures that it not called before all instances of that type have been
|
212 |
+
collected:
|
213 |
+
|
214 |
+
.. code-block:: cpp
|
215 |
+
|
216 |
+
auto cleanup_callback = []() { /* ... */ };
|
217 |
+
m.attr("BaseClass").attr("_cleanup") = py::capsule(cleanup_callback);
|
218 |
+
|
219 |
+
Both approaches also expose a potentially dangerous ``_cleanup`` attribute in
|
220 |
+
Python, which may be undesirable from an API standpoint (a premature explicit
|
221 |
+
call from Python might lead to undefined behavior). Yet another approach that
|
222 |
+
avoids this issue involves weak reference with a cleanup callback:
|
223 |
+
|
224 |
+
.. code-block:: cpp
|
225 |
+
|
226 |
+
// Register a callback function that is invoked when the BaseClass object is collected
|
227 |
+
py::cpp_function cleanup_callback(
|
228 |
+
[](py::handle weakref) {
|
229 |
+
// perform cleanup here -- this function is called with the GIL held
|
230 |
+
|
231 |
+
weakref.dec_ref(); // release weak reference
|
232 |
+
}
|
233 |
+
);
|
234 |
+
|
235 |
+
// Create a weak reference with a cleanup callback and initially leak it
|
236 |
+
(void) py::weakref(m.attr("BaseClass"), cleanup_callback).release();
|
237 |
+
|
238 |
+
.. note::
|
239 |
+
|
240 |
+
PyPy does not garbage collect objects when the interpreter exits. An alternative
|
241 |
+
approach (which also works on CPython) is to use the :py:mod:`atexit` module [#f7]_,
|
242 |
+
for example:
|
243 |
+
|
244 |
+
.. code-block:: cpp
|
245 |
+
|
246 |
+
auto atexit = py::module_::import("atexit");
|
247 |
+
atexit.attr("register")(py::cpp_function([]() {
|
248 |
+
// perform cleanup here -- this function is called with the GIL held
|
249 |
+
}));
|
250 |
+
|
251 |
+
.. [#f7] https://docs.python.org/3/library/atexit.html
|
252 |
+
|
253 |
+
|
254 |
+
Generating documentation using Sphinx
|
255 |
+
=====================================
|
256 |
+
|
257 |
+
Sphinx [#f4]_ has the ability to inspect the signatures and documentation
|
258 |
+
strings in pybind11-based extension modules to automatically generate beautiful
|
259 |
+
documentation in a variety formats. The python_example repository [#f5]_ contains a
|
260 |
+
simple example repository which uses this approach.
|
261 |
+
|
262 |
+
There are two potential gotchas when using this approach: first, make sure that
|
263 |
+
the resulting strings do not contain any :kbd:`TAB` characters, which break the
|
264 |
+
docstring parsing routines. You may want to use C++11 raw string literals,
|
265 |
+
which are convenient for multi-line comments. Conveniently, any excess
|
266 |
+
indentation will be automatically be removed by Sphinx. However, for this to
|
267 |
+
work, it is important that all lines are indented consistently, i.e.:
|
268 |
+
|
269 |
+
.. code-block:: cpp
|
270 |
+
|
271 |
+
// ok
|
272 |
+
m.def("foo", &foo, R"mydelimiter(
|
273 |
+
The foo function
|
274 |
+
|
275 |
+
Parameters
|
276 |
+
----------
|
277 |
+
)mydelimiter");
|
278 |
+
|
279 |
+
// *not ok*
|
280 |
+
m.def("foo", &foo, R"mydelimiter(The foo function
|
281 |
+
|
282 |
+
Parameters
|
283 |
+
----------
|
284 |
+
)mydelimiter");
|
285 |
+
|
286 |
+
By default, pybind11 automatically generates and prepends a signature to the docstring of a function
|
287 |
+
registered with ``module_::def()`` and ``class_::def()``. Sometimes this
|
288 |
+
behavior is not desirable, because you want to provide your own signature or remove
|
289 |
+
the docstring completely to exclude the function from the Sphinx documentation.
|
290 |
+
The class ``options`` allows you to selectively suppress auto-generated signatures:
|
291 |
+
|
292 |
+
.. code-block:: cpp
|
293 |
+
|
294 |
+
PYBIND11_MODULE(example, m) {
|
295 |
+
py::options options;
|
296 |
+
options.disable_function_signatures();
|
297 |
+
|
298 |
+
m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers");
|
299 |
+
}
|
300 |
+
|
301 |
+
Note that changes to the settings affect only function bindings created during the
|
302 |
+
lifetime of the ``options`` instance. When it goes out of scope at the end of the module's init function,
|
303 |
+
the default settings are restored to prevent unwanted side effects.
|
304 |
+
|
305 |
+
.. [#f4] http://www.sphinx-doc.org
|
306 |
+
.. [#f5] http://github.com/pybind/python_example
|
307 |
+
|
308 |
+
.. _avoiding-cpp-types-in-docstrings:
|
309 |
+
|
310 |
+
Avoiding C++ types in docstrings
|
311 |
+
================================
|
312 |
+
|
313 |
+
Docstrings are generated at the time of the declaration, e.g. when ``.def(...)`` is called.
|
314 |
+
At this point parameter and return types should be known to pybind11.
|
315 |
+
If a custom type is not exposed yet through a ``py::class_`` constructor or a custom type caster,
|
316 |
+
its C++ type name will be used instead to generate the signature in the docstring:
|
317 |
+
|
318 |
+
.. code-block:: text
|
319 |
+
|
320 |
+
| __init__(...)
|
321 |
+
| __init__(self: example.Foo, arg0: ns::Bar) -> None
|
322 |
+
^^^^^^^
|
323 |
+
|
324 |
+
|
325 |
+
This limitation can be circumvented by ensuring that C++ classes are registered with pybind11
|
326 |
+
before they are used as a parameter or return type of a function:
|
327 |
+
|
328 |
+
.. code-block:: cpp
|
329 |
+
|
330 |
+
PYBIND11_MODULE(example, m) {
|
331 |
+
|
332 |
+
auto pyFoo = py::class_<ns::Foo>(m, "Foo");
|
333 |
+
auto pyBar = py::class_<ns::Bar>(m, "Bar");
|
334 |
+
|
335 |
+
pyFoo.def(py::init<const ns::Bar&>());
|
336 |
+
pyBar.def(py::init<const ns::Foo&>());
|
337 |
+
}
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/index.rst
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Python C++ interface
|
2 |
+
####################
|
3 |
+
|
4 |
+
pybind11 exposes Python types and functions using thin C++ wrappers, which
|
5 |
+
makes it possible to conveniently call Python code from C++ without resorting
|
6 |
+
to Python's C API.
|
7 |
+
|
8 |
+
.. toctree::
|
9 |
+
:maxdepth: 2
|
10 |
+
|
11 |
+
object
|
12 |
+
numpy
|
13 |
+
utilities
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/numpy.rst
ADDED
@@ -0,0 +1,463 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.. _numpy:
|
2 |
+
|
3 |
+
NumPy
|
4 |
+
#####
|
5 |
+
|
6 |
+
Buffer protocol
|
7 |
+
===============
|
8 |
+
|
9 |
+
Python supports an extremely general and convenient approach for exchanging
|
10 |
+
data between plugin libraries. Types can expose a buffer view [#f2]_, which
|
11 |
+
provides fast direct access to the raw internal data representation. Suppose we
|
12 |
+
want to bind the following simplistic Matrix class:
|
13 |
+
|
14 |
+
.. code-block:: cpp
|
15 |
+
|
16 |
+
class Matrix {
|
17 |
+
public:
|
18 |
+
Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) {
|
19 |
+
m_data = new float[rows*cols];
|
20 |
+
}
|
21 |
+
float *data() { return m_data; }
|
22 |
+
size_t rows() const { return m_rows; }
|
23 |
+
size_t cols() const { return m_cols; }
|
24 |
+
private:
|
25 |
+
size_t m_rows, m_cols;
|
26 |
+
float *m_data;
|
27 |
+
};
|
28 |
+
|
29 |
+
The following binding code exposes the ``Matrix`` contents as a buffer object,
|
30 |
+
making it possible to cast Matrices into NumPy arrays. It is even possible to
|
31 |
+
completely avoid copy operations with Python expressions like
|
32 |
+
``np.array(matrix_instance, copy = False)``.
|
33 |
+
|
34 |
+
.. code-block:: cpp
|
35 |
+
|
36 |
+
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
37 |
+
.def_buffer([](Matrix &m) -> py::buffer_info {
|
38 |
+
return py::buffer_info(
|
39 |
+
m.data(), /* Pointer to buffer */
|
40 |
+
sizeof(float), /* Size of one scalar */
|
41 |
+
py::format_descriptor<float>::format(), /* Python struct-style format descriptor */
|
42 |
+
2, /* Number of dimensions */
|
43 |
+
{ m.rows(), m.cols() }, /* Buffer dimensions */
|
44 |
+
{ sizeof(float) * m.cols(), /* Strides (in bytes) for each index */
|
45 |
+
sizeof(float) }
|
46 |
+
);
|
47 |
+
});
|
48 |
+
|
49 |
+
Supporting the buffer protocol in a new type involves specifying the special
|
50 |
+
``py::buffer_protocol()`` tag in the ``py::class_`` constructor and calling the
|
51 |
+
``def_buffer()`` method with a lambda function that creates a
|
52 |
+
``py::buffer_info`` description record on demand describing a given matrix
|
53 |
+
instance. The contents of ``py::buffer_info`` mirror the Python buffer protocol
|
54 |
+
specification.
|
55 |
+
|
56 |
+
.. code-block:: cpp
|
57 |
+
|
58 |
+
struct buffer_info {
|
59 |
+
void *ptr;
|
60 |
+
py::ssize_t itemsize;
|
61 |
+
std::string format;
|
62 |
+
py::ssize_t ndim;
|
63 |
+
std::vector<py::ssize_t> shape;
|
64 |
+
std::vector<py::ssize_t> strides;
|
65 |
+
};
|
66 |
+
|
67 |
+
To create a C++ function that can take a Python buffer object as an argument,
|
68 |
+
simply use the type ``py::buffer`` as one of its arguments. Buffers can exist
|
69 |
+
in a great variety of configurations, hence some safety checks are usually
|
70 |
+
necessary in the function body. Below, you can see a basic example on how to
|
71 |
+
define a custom constructor for the Eigen double precision matrix
|
72 |
+
(``Eigen::MatrixXd``) type, which supports initialization from compatible
|
73 |
+
buffer objects (e.g. a NumPy matrix).
|
74 |
+
|
75 |
+
.. code-block:: cpp
|
76 |
+
|
77 |
+
/* Bind MatrixXd (or some other Eigen type) to Python */
|
78 |
+
typedef Eigen::MatrixXd Matrix;
|
79 |
+
|
80 |
+
typedef Matrix::Scalar Scalar;
|
81 |
+
constexpr bool rowMajor = Matrix::Flags & Eigen::RowMajorBit;
|
82 |
+
|
83 |
+
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
84 |
+
.def(py::init([](py::buffer b) {
|
85 |
+
typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;
|
86 |
+
|
87 |
+
/* Request a buffer descriptor from Python */
|
88 |
+
py::buffer_info info = b.request();
|
89 |
+
|
90 |
+
/* Some sanity checks ... */
|
91 |
+
if (info.format != py::format_descriptor<Scalar>::format())
|
92 |
+
throw std::runtime_error("Incompatible format: expected a double array!");
|
93 |
+
|
94 |
+
if (info.ndim != 2)
|
95 |
+
throw std::runtime_error("Incompatible buffer dimension!");
|
96 |
+
|
97 |
+
auto strides = Strides(
|
98 |
+
info.strides[rowMajor ? 0 : 1] / (py::ssize_t)sizeof(Scalar),
|
99 |
+
info.strides[rowMajor ? 1 : 0] / (py::ssize_t)sizeof(Scalar));
|
100 |
+
|
101 |
+
auto map = Eigen::Map<Matrix, 0, Strides>(
|
102 |
+
static_cast<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);
|
103 |
+
|
104 |
+
return Matrix(map);
|
105 |
+
}));
|
106 |
+
|
107 |
+
For reference, the ``def_buffer()`` call for this Eigen data type should look
|
108 |
+
as follows:
|
109 |
+
|
110 |
+
.. code-block:: cpp
|
111 |
+
|
112 |
+
.def_buffer([](Matrix &m) -> py::buffer_info {
|
113 |
+
return py::buffer_info(
|
114 |
+
m.data(), /* Pointer to buffer */
|
115 |
+
sizeof(Scalar), /* Size of one scalar */
|
116 |
+
py::format_descriptor<Scalar>::format(), /* Python struct-style format descriptor */
|
117 |
+
2, /* Number of dimensions */
|
118 |
+
{ m.rows(), m.cols() }, /* Buffer dimensions */
|
119 |
+
{ sizeof(Scalar) * (rowMajor ? m.cols() : 1),
|
120 |
+
sizeof(Scalar) * (rowMajor ? 1 : m.rows()) }
|
121 |
+
/* Strides (in bytes) for each index */
|
122 |
+
);
|
123 |
+
})
|
124 |
+
|
125 |
+
For a much easier approach of binding Eigen types (although with some
|
126 |
+
limitations), refer to the section on :doc:`/advanced/cast/eigen`.
|
127 |
+
|
128 |
+
.. seealso::
|
129 |
+
|
130 |
+
The file :file:`tests/test_buffers.cpp` contains a complete example
|
131 |
+
that demonstrates using the buffer protocol with pybind11 in more detail.
|
132 |
+
|
133 |
+
.. [#f2] http://docs.python.org/3/c-api/buffer.html
|
134 |
+
|
135 |
+
Arrays
|
136 |
+
======
|
137 |
+
|
138 |
+
By exchanging ``py::buffer`` with ``py::array`` in the above snippet, we can
|
139 |
+
restrict the function so that it only accepts NumPy arrays (rather than any
|
140 |
+
type of Python object satisfying the buffer protocol).
|
141 |
+
|
142 |
+
In many situations, we want to define a function which only accepts a NumPy
|
143 |
+
array of a certain data type. This is possible via the ``py::array_t<T>``
|
144 |
+
template. For instance, the following function requires the argument to be a
|
145 |
+
NumPy array containing double precision values.
|
146 |
+
|
147 |
+
.. code-block:: cpp
|
148 |
+
|
149 |
+
void f(py::array_t<double> array);
|
150 |
+
|
151 |
+
When it is invoked with a different type (e.g. an integer or a list of
|
152 |
+
integers), the binding code will attempt to cast the input into a NumPy array
|
153 |
+
of the requested type. This feature requires the :file:`pybind11/numpy.h`
|
154 |
+
header to be included. Note that :file:`pybind11/numpy.h` does not depend on
|
155 |
+
the NumPy headers, and thus can be used without declaring a build-time
|
156 |
+
dependency on NumPy; NumPy>=1.7.0 is a runtime dependency.
|
157 |
+
|
158 |
+
Data in NumPy arrays is not guaranteed to packed in a dense manner;
|
159 |
+
furthermore, entries can be separated by arbitrary column and row strides.
|
160 |
+
Sometimes, it can be useful to require a function to only accept dense arrays
|
161 |
+
using either the C (row-major) or Fortran (column-major) ordering. This can be
|
162 |
+
accomplished via a second template argument with values ``py::array::c_style``
|
163 |
+
or ``py::array::f_style``.
|
164 |
+
|
165 |
+
.. code-block:: cpp
|
166 |
+
|
167 |
+
void f(py::array_t<double, py::array::c_style | py::array::forcecast> array);
|
168 |
+
|
169 |
+
The ``py::array::forcecast`` argument is the default value of the second
|
170 |
+
template parameter, and it ensures that non-conforming arguments are converted
|
171 |
+
into an array satisfying the specified requirements instead of trying the next
|
172 |
+
function overload.
|
173 |
+
|
174 |
+
There are several methods on arrays; the methods listed below under references
|
175 |
+
work, as well as the following functions based on the NumPy API:
|
176 |
+
|
177 |
+
- ``.dtype()`` returns the type of the contained values.
|
178 |
+
|
179 |
+
- ``.strides()`` returns a pointer to the strides of the array (optionally pass
|
180 |
+
an integer axis to get a number).
|
181 |
+
|
182 |
+
- ``.flags()`` returns the flag settings. ``.writable()`` and ``.owndata()``
|
183 |
+
are directly available.
|
184 |
+
|
185 |
+
- ``.offset_at()`` returns the offset (optionally pass indices).
|
186 |
+
|
187 |
+
- ``.squeeze()`` returns a view with length-1 axes removed.
|
188 |
+
|
189 |
+
- ``.view(dtype)`` returns a view of the array with a different dtype.
|
190 |
+
|
191 |
+
- ``.reshape({i, j, ...})`` returns a view of the array with a different shape.
|
192 |
+
``.resize({...})`` is also available.
|
193 |
+
|
194 |
+
- ``.index_at(i, j, ...)`` gets the count from the beginning to a given index.
|
195 |
+
|
196 |
+
|
197 |
+
There are also several methods for getting references (described below).
|
198 |
+
|
199 |
+
Structured types
|
200 |
+
================
|
201 |
+
|
202 |
+
In order for ``py::array_t`` to work with structured (record) types, we first
|
203 |
+
need to register the memory layout of the type. This can be done via
|
204 |
+
``PYBIND11_NUMPY_DTYPE`` macro, called in the plugin definition code, which
|
205 |
+
expects the type followed by field names:
|
206 |
+
|
207 |
+
.. code-block:: cpp
|
208 |
+
|
209 |
+
struct A {
|
210 |
+
int x;
|
211 |
+
double y;
|
212 |
+
};
|
213 |
+
|
214 |
+
struct B {
|
215 |
+
int z;
|
216 |
+
A a;
|
217 |
+
};
|
218 |
+
|
219 |
+
// ...
|
220 |
+
PYBIND11_MODULE(test, m) {
|
221 |
+
// ...
|
222 |
+
|
223 |
+
PYBIND11_NUMPY_DTYPE(A, x, y);
|
224 |
+
PYBIND11_NUMPY_DTYPE(B, z, a);
|
225 |
+
/* now both A and B can be used as template arguments to py::array_t */
|
226 |
+
}
|
227 |
+
|
228 |
+
The structure should consist of fundamental arithmetic types, ``std::complex``,
|
229 |
+
previously registered substructures, and arrays of any of the above. Both C++
|
230 |
+
arrays and ``std::array`` are supported. While there is a static assertion to
|
231 |
+
prevent many types of unsupported structures, it is still the user's
|
232 |
+
responsibility to use only "plain" structures that can be safely manipulated as
|
233 |
+
raw memory without violating invariants.
|
234 |
+
|
235 |
+
Vectorizing functions
|
236 |
+
=====================
|
237 |
+
|
238 |
+
Suppose we want to bind a function with the following signature to Python so
|
239 |
+
that it can process arbitrary NumPy array arguments (vectors, matrices, general
|
240 |
+
N-D arrays) in addition to its normal arguments:
|
241 |
+
|
242 |
+
.. code-block:: cpp
|
243 |
+
|
244 |
+
double my_func(int x, float y, double z);
|
245 |
+
|
246 |
+
After including the ``pybind11/numpy.h`` header, this is extremely simple:
|
247 |
+
|
248 |
+
.. code-block:: cpp
|
249 |
+
|
250 |
+
m.def("vectorized_func", py::vectorize(my_func));
|
251 |
+
|
252 |
+
Invoking the function like below causes 4 calls to be made to ``my_func`` with
|
253 |
+
each of the array elements. The significant advantage of this compared to
|
254 |
+
solutions like ``numpy.vectorize()`` is that the loop over the elements runs
|
255 |
+
entirely on the C++ side and can be crunched down into a tight, optimized loop
|
256 |
+
by the compiler. The result is returned as a NumPy array of type
|
257 |
+
``numpy.dtype.float64``.
|
258 |
+
|
259 |
+
.. code-block:: pycon
|
260 |
+
|
261 |
+
>>> x = np.array([[1, 3], [5, 7]])
|
262 |
+
>>> y = np.array([[2, 4], [6, 8]])
|
263 |
+
>>> z = 3
|
264 |
+
>>> result = vectorized_func(x, y, z)
|
265 |
+
|
266 |
+
The scalar argument ``z`` is transparently replicated 4 times. The input
|
267 |
+
arrays ``x`` and ``y`` are automatically converted into the right types (they
|
268 |
+
are of type ``numpy.dtype.int64`` but need to be ``numpy.dtype.int32`` and
|
269 |
+
``numpy.dtype.float32``, respectively).
|
270 |
+
|
271 |
+
.. note::
|
272 |
+
|
273 |
+
Only arithmetic, complex, and POD types passed by value or by ``const &``
|
274 |
+
reference are vectorized; all other arguments are passed through as-is.
|
275 |
+
Functions taking rvalue reference arguments cannot be vectorized.
|
276 |
+
|
277 |
+
In cases where the computation is too complicated to be reduced to
|
278 |
+
``vectorize``, it will be necessary to create and access the buffer contents
|
279 |
+
manually. The following snippet contains a complete example that shows how this
|
280 |
+
works (the code is somewhat contrived, since it could have been done more
|
281 |
+
simply using ``vectorize``).
|
282 |
+
|
283 |
+
.. code-block:: cpp
|
284 |
+
|
285 |
+
#include <pybind11/pybind11.h>
|
286 |
+
#include <pybind11/numpy.h>
|
287 |
+
|
288 |
+
namespace py = pybind11;
|
289 |
+
|
290 |
+
py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
|
291 |
+
py::buffer_info buf1 = input1.request(), buf2 = input2.request();
|
292 |
+
|
293 |
+
if (buf1.ndim != 1 || buf2.ndim != 1)
|
294 |
+
throw std::runtime_error("Number of dimensions must be one");
|
295 |
+
|
296 |
+
if (buf1.size != buf2.size)
|
297 |
+
throw std::runtime_error("Input shapes must match");
|
298 |
+
|
299 |
+
/* No pointer is passed, so NumPy will allocate the buffer */
|
300 |
+
auto result = py::array_t<double>(buf1.size);
|
301 |
+
|
302 |
+
py::buffer_info buf3 = result.request();
|
303 |
+
|
304 |
+
double *ptr1 = static_cast<double *>(buf1.ptr);
|
305 |
+
double *ptr2 = static_cast<double *>(buf2.ptr);
|
306 |
+
double *ptr3 = static_cast<double *>(buf3.ptr);
|
307 |
+
|
308 |
+
for (size_t idx = 0; idx < buf1.shape[0]; idx++)
|
309 |
+
ptr3[idx] = ptr1[idx] + ptr2[idx];
|
310 |
+
|
311 |
+
return result;
|
312 |
+
}
|
313 |
+
|
314 |
+
PYBIND11_MODULE(test, m) {
|
315 |
+
m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
|
316 |
+
}
|
317 |
+
|
318 |
+
.. seealso::
|
319 |
+
|
320 |
+
The file :file:`tests/test_numpy_vectorize.cpp` contains a complete
|
321 |
+
example that demonstrates using :func:`vectorize` in more detail.
|
322 |
+
|
323 |
+
Direct access
|
324 |
+
=============
|
325 |
+
|
326 |
+
For performance reasons, particularly when dealing with very large arrays, it
|
327 |
+
is often desirable to directly access array elements without internal checking
|
328 |
+
of dimensions and bounds on every access when indices are known to be already
|
329 |
+
valid. To avoid such checks, the ``array`` class and ``array_t<T>`` template
|
330 |
+
class offer an unchecked proxy object that can be used for this unchecked
|
331 |
+
access through the ``unchecked<N>`` and ``mutable_unchecked<N>`` methods,
|
332 |
+
where ``N`` gives the required dimensionality of the array:
|
333 |
+
|
334 |
+
.. code-block:: cpp
|
335 |
+
|
336 |
+
m.def("sum_3d", [](py::array_t<double> x) {
|
337 |
+
auto r = x.unchecked<3>(); // x must have ndim = 3; can be non-writeable
|
338 |
+
double sum = 0;
|
339 |
+
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
340 |
+
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
341 |
+
for (py::ssize_t k = 0; k < r.shape(2); k++)
|
342 |
+
sum += r(i, j, k);
|
343 |
+
return sum;
|
344 |
+
});
|
345 |
+
m.def("increment_3d", [](py::array_t<double> x) {
|
346 |
+
auto r = x.mutable_unchecked<3>(); // Will throw if ndim != 3 or flags.writeable is false
|
347 |
+
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
348 |
+
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
349 |
+
for (py::ssize_t k = 0; k < r.shape(2); k++)
|
350 |
+
r(i, j, k) += 1.0;
|
351 |
+
}, py::arg().noconvert());
|
352 |
+
|
353 |
+
To obtain the proxy from an ``array`` object, you must specify both the data
|
354 |
+
type and number of dimensions as template arguments, such as ``auto r =
|
355 |
+
myarray.mutable_unchecked<float, 2>()``.
|
356 |
+
|
357 |
+
If the number of dimensions is not known at compile time, you can omit the
|
358 |
+
dimensions template parameter (i.e. calling ``arr_t.unchecked()`` or
|
359 |
+
``arr.unchecked<T>()``. This will give you a proxy object that works in the
|
360 |
+
same way, but results in less optimizable code and thus a small efficiency
|
361 |
+
loss in tight loops.
|
362 |
+
|
363 |
+
Note that the returned proxy object directly references the array's data, and
|
364 |
+
only reads its shape, strides, and writeable flag when constructed. You must
|
365 |
+
take care to ensure that the referenced array is not destroyed or reshaped for
|
366 |
+
the duration of the returned object, typically by limiting the scope of the
|
367 |
+
returned instance.
|
368 |
+
|
369 |
+
The returned proxy object supports some of the same methods as ``py::array`` so
|
370 |
+
that it can be used as a drop-in replacement for some existing, index-checked
|
371 |
+
uses of ``py::array``:
|
372 |
+
|
373 |
+
- ``.ndim()`` returns the number of dimensions
|
374 |
+
|
375 |
+
- ``.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
|
376 |
+
the ``const T`` or ``T`` data, respectively, at the given indices. The
|
377 |
+
latter is only available to proxies obtained via ``a.mutable_unchecked()``.
|
378 |
+
|
379 |
+
- ``.itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
|
380 |
+
|
381 |
+
- ``.ndim()`` returns the number of dimensions.
|
382 |
+
|
383 |
+
- ``.shape(n)`` returns the size of dimension ``n``
|
384 |
+
|
385 |
+
- ``.size()`` returns the total number of elements (i.e. the product of the shapes).
|
386 |
+
|
387 |
+
- ``.nbytes()`` returns the number of bytes used by the referenced elements
|
388 |
+
(i.e. ``itemsize()`` times ``size()``).
|
389 |
+
|
390 |
+
.. seealso::
|
391 |
+
|
392 |
+
The file :file:`tests/test_numpy_array.cpp` contains additional examples
|
393 |
+
demonstrating the use of this feature.
|
394 |
+
|
395 |
+
Ellipsis
|
396 |
+
========
|
397 |
+
|
398 |
+
Python 3 provides a convenient ``...`` ellipsis notation that is often used to
|
399 |
+
slice multidimensional arrays. For instance, the following snippet extracts the
|
400 |
+
middle dimensions of a tensor with the first and last index set to zero.
|
401 |
+
In Python 2, the syntactic sugar ``...`` is not available, but the singleton
|
402 |
+
``Ellipsis`` (of type ``ellipsis``) can still be used directly.
|
403 |
+
|
404 |
+
.. code-block:: python
|
405 |
+
|
406 |
+
a = ... # a NumPy array
|
407 |
+
b = a[0, ..., 0]
|
408 |
+
|
409 |
+
The function ``py::ellipsis()`` function can be used to perform the same
|
410 |
+
operation on the C++ side:
|
411 |
+
|
412 |
+
.. code-block:: cpp
|
413 |
+
|
414 |
+
py::array a = /* A NumPy array */;
|
415 |
+
py::array b = a[py::make_tuple(0, py::ellipsis(), 0)];
|
416 |
+
|
417 |
+
.. versionchanged:: 2.6
|
418 |
+
``py::ellipsis()`` is now also available in Python 2.
|
419 |
+
|
420 |
+
Memory view
|
421 |
+
===========
|
422 |
+
|
423 |
+
For a case when we simply want to provide a direct accessor to C/C++ buffer
|
424 |
+
without a concrete class object, we can return a ``memoryview`` object. Suppose
|
425 |
+
we wish to expose a ``memoryview`` for 2x4 uint8_t array, we can do the
|
426 |
+
following:
|
427 |
+
|
428 |
+
.. code-block:: cpp
|
429 |
+
|
430 |
+
const uint8_t buffer[] = {
|
431 |
+
0, 1, 2, 3,
|
432 |
+
4, 5, 6, 7
|
433 |
+
};
|
434 |
+
m.def("get_memoryview2d", []() {
|
435 |
+
return py::memoryview::from_buffer(
|
436 |
+
buffer, // buffer pointer
|
437 |
+
{ 2, 4 }, // shape (rows, cols)
|
438 |
+
{ sizeof(uint8_t) * 4, sizeof(uint8_t) } // strides in bytes
|
439 |
+
);
|
440 |
+
})
|
441 |
+
|
442 |
+
This approach is meant for providing a ``memoryview`` for a C/C++ buffer not
|
443 |
+
managed by Python. The user is responsible for managing the lifetime of the
|
444 |
+
buffer. Using a ``memoryview`` created in this way after deleting the buffer in
|
445 |
+
C++ side results in undefined behavior.
|
446 |
+
|
447 |
+
We can also use ``memoryview::from_memory`` for a simple 1D contiguous buffer:
|
448 |
+
|
449 |
+
.. code-block:: cpp
|
450 |
+
|
451 |
+
m.def("get_memoryview1d", []() {
|
452 |
+
return py::memoryview::from_memory(
|
453 |
+
buffer, // buffer pointer
|
454 |
+
sizeof(uint8_t) * 8 // buffer size
|
455 |
+
);
|
456 |
+
})
|
457 |
+
|
458 |
+
.. note::
|
459 |
+
|
460 |
+
``memoryview::from_memory`` is not available in Python 2.
|
461 |
+
|
462 |
+
.. versionchanged:: 2.6
|
463 |
+
``memoryview::from_memory`` added.
|
third-party/DPVO/DPRetrieval/pybind11/docs/advanced/pycpp/object.rst
ADDED
@@ -0,0 +1,286 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Python types
|
2 |
+
############
|
3 |
+
|
4 |
+
.. _wrappers:
|
5 |
+
|
6 |
+
Available wrappers
|
7 |
+
==================
|
8 |
+
|
9 |
+
All major Python types are available as thin C++ wrapper classes. These
|
10 |
+
can also be used as function parameters -- see :ref:`python_objects_as_args`.
|
11 |
+
|
12 |
+
Available types include :class:`handle`, :class:`object`, :class:`bool_`,
|
13 |
+
:class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`,
|
14 |
+
:class:`list`, :class:`dict`, :class:`slice`, :class:`none`, :class:`capsule`,
|
15 |
+
:class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`,
|
16 |
+
:class:`array`, and :class:`array_t`.
|
17 |
+
|
18 |
+
.. warning::
|
19 |
+
|
20 |
+
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
|
21 |
+
your C++ API.
|
22 |
+
|
23 |
+
.. _instantiating_compound_types:
|
24 |
+
|
25 |
+
Instantiating compound Python types from C++
|
26 |
+
============================================
|
27 |
+
|
28 |
+
Dictionaries can be initialized in the :class:`dict` constructor:
|
29 |
+
|
30 |
+
.. code-block:: cpp
|
31 |
+
|
32 |
+
using namespace pybind11::literals; // to bring in the `_a` literal
|
33 |
+
py::dict d("spam"_a=py::none(), "eggs"_a=42);
|
34 |
+
|
35 |
+
A tuple of python objects can be instantiated using :func:`py::make_tuple`:
|
36 |
+
|
37 |
+
.. code-block:: cpp
|
38 |
+
|
39 |
+
py::tuple tup = py::make_tuple(42, py::none(), "spam");
|
40 |
+
|
41 |
+
Each element is converted to a supported Python type.
|
42 |
+
|
43 |
+
A `simple namespace`_ can be instantiated using
|
44 |
+
|
45 |
+
.. code-block:: cpp
|
46 |
+
|
47 |
+
using namespace pybind11::literals; // to bring in the `_a` literal
|
48 |
+
py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace");
|
49 |
+
py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42);
|
50 |
+
|
51 |
+
Attributes on a namespace can be modified with the :func:`py::delattr`,
|
52 |
+
:func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can
|
53 |
+
be useful as lightweight stand-ins for class instances.
|
54 |
+
|
55 |
+
.. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace
|
56 |
+
|
57 |
+
.. _casting_back_and_forth:
|
58 |
+
|
59 |
+
Casting back and forth
|
60 |
+
======================
|
61 |
+
|
62 |
+
In this kind of mixed code, it is often necessary to convert arbitrary C++
|
63 |
+
types to Python, which can be done using :func:`py::cast`:
|
64 |
+
|
65 |
+
.. code-block:: cpp
|
66 |
+
|
67 |
+
MyClass *cls = ...;
|
68 |
+
py::object obj = py::cast(cls);
|
69 |
+
|
70 |
+
The reverse direction uses the following syntax:
|
71 |
+
|
72 |
+
.. code-block:: cpp
|
73 |
+
|
74 |
+
py::object obj = ...;
|
75 |
+
MyClass *cls = obj.cast<MyClass *>();
|
76 |
+
|
77 |
+
When conversion fails, both directions throw the exception :class:`cast_error`.
|
78 |
+
|
79 |
+
.. _python_libs:
|
80 |
+
|
81 |
+
Accessing Python libraries from C++
|
82 |
+
===================================
|
83 |
+
|
84 |
+
It is also possible to import objects defined in the Python standard
|
85 |
+
library or available in the current Python environment (``sys.path``) and work
|
86 |
+
with these in C++.
|
87 |
+
|
88 |
+
This example obtains a reference to the Python ``Decimal`` class.
|
89 |
+
|
90 |
+
.. code-block:: cpp
|
91 |
+
|
92 |
+
// Equivalent to "from decimal import Decimal"
|
93 |
+
py::object Decimal = py::module_::import("decimal").attr("Decimal");
|
94 |
+
|
95 |
+
.. code-block:: cpp
|
96 |
+
|
97 |
+
// Try to import scipy
|
98 |
+
py::object scipy = py::module_::import("scipy");
|
99 |
+
return scipy.attr("__version__");
|
100 |
+
|
101 |
+
|
102 |
+
.. _calling_python_functions:
|
103 |
+
|
104 |
+
Calling Python functions
|
105 |
+
========================
|
106 |
+
|
107 |
+
It is also possible to call Python classes, functions and methods
|
108 |
+
via ``operator()``.
|
109 |
+
|
110 |
+
.. code-block:: cpp
|
111 |
+
|
112 |
+
// Construct a Python object of class Decimal
|
113 |
+
py::object pi = Decimal("3.14159");
|
114 |
+
|
115 |
+
.. code-block:: cpp
|
116 |
+
|
117 |
+
// Use Python to make our directories
|
118 |
+
py::object os = py::module_::import("os");
|
119 |
+
py::object makedirs = os.attr("makedirs");
|
120 |
+
makedirs("/tmp/path/to/somewhere");
|
121 |
+
|
122 |
+
One can convert the result obtained from Python to a pure C++ version
|
123 |
+
if a ``py::class_`` or type conversion is defined.
|
124 |
+
|
125 |
+
.. code-block:: cpp
|
126 |
+
|
127 |
+
py::function f = <...>;
|
128 |
+
py::object result_py = f(1234, "hello", some_instance);
|
129 |
+
MyClass &result = result_py.cast<MyClass>();
|
130 |
+
|
131 |
+
.. _calling_python_methods:
|
132 |
+
|
133 |
+
Calling Python methods
|
134 |
+
========================
|
135 |
+
|
136 |
+
To call an object's method, one can again use ``.attr`` to obtain access to the
|
137 |
+
Python method.
|
138 |
+
|
139 |
+
.. code-block:: cpp
|
140 |
+
|
141 |
+
// Calculate e^π in decimal
|
142 |
+
py::object exp_pi = pi.attr("exp")();
|
143 |
+
py::print(py::str(exp_pi));
|
144 |
+
|
145 |
+
In the example above ``pi.attr("exp")`` is a *bound method*: it will always call
|
146 |
+
the method for that same instance of the class. Alternately one can create an
|
147 |
+
*unbound method* via the Python class (instead of instance) and pass the ``self``
|
148 |
+
object explicitly, followed by other arguments.
|
149 |
+
|
150 |
+
.. code-block:: cpp
|
151 |
+
|
152 |
+
py::object decimal_exp = Decimal.attr("exp");
|
153 |
+
|
154 |
+
// Compute the e^n for n=0..4
|
155 |
+
for (int n = 0; n < 5; n++) {
|
156 |
+
py::print(decimal_exp(Decimal(n));
|
157 |
+
}
|
158 |
+
|
159 |
+
Keyword arguments
|
160 |
+
=================
|
161 |
+
|
162 |
+
Keyword arguments are also supported. In Python, there is the usual call syntax:
|
163 |
+
|
164 |
+
.. code-block:: python
|
165 |
+
|
166 |
+
def f(number, say, to):
|
167 |
+
... # function code
|
168 |
+
|
169 |
+
|
170 |
+
f(1234, say="hello", to=some_instance) # keyword call in Python
|
171 |
+
|
172 |
+
In C++, the same call can be made using:
|
173 |
+
|
174 |
+
.. code-block:: cpp
|
175 |
+
|
176 |
+
using namespace pybind11::literals; // to bring in the `_a` literal
|
177 |
+
f(1234, "say"_a="hello", "to"_a=some_instance); // keyword call in C++
|
178 |
+
|
179 |
+
Unpacking arguments
|
180 |
+
===================
|
181 |
+
|
182 |
+
Unpacking of ``*args`` and ``**kwargs`` is also possible and can be mixed with
|
183 |
+
other arguments:
|
184 |
+
|
185 |
+
.. code-block:: cpp
|
186 |
+
|
187 |
+
// * unpacking
|
188 |
+
py::tuple args = py::make_tuple(1234, "hello", some_instance);
|
189 |
+
f(*args);
|
190 |
+
|
191 |
+
// ** unpacking
|
192 |
+
py::dict kwargs = py::dict("number"_a=1234, "say"_a="hello", "to"_a=some_instance);
|
193 |
+
f(**kwargs);
|
194 |
+
|
195 |
+
// mixed keywords, * and ** unpacking
|
196 |
+
py::tuple args = py::make_tuple(1234);
|
197 |
+
py::dict kwargs = py::dict("to"_a=some_instance);
|
198 |
+
f(*args, "say"_a="hello", **kwargs);
|
199 |
+
|
200 |
+
Generalized unpacking according to PEP448_ is also supported:
|
201 |
+
|
202 |
+
.. code-block:: cpp
|
203 |
+
|
204 |
+
py::dict kwargs1 = py::dict("number"_a=1234);
|
205 |
+
py::dict kwargs2 = py::dict("to"_a=some_instance);
|
206 |
+
f(**kwargs1, "say"_a="hello", **kwargs2);
|
207 |
+
|
208 |
+
.. seealso::
|
209 |
+
|
210 |
+
The file :file:`tests/test_pytypes.cpp` contains a complete
|
211 |
+
example that demonstrates passing native Python types in more detail. The
|
212 |
+
file :file:`tests/test_callbacks.cpp` presents a few examples of calling
|
213 |
+
Python functions from C++, including keywords arguments and unpacking.
|
214 |
+
|
215 |
+
.. _PEP448: https://www.python.org/dev/peps/pep-0448/
|
216 |
+
|
217 |
+
.. _implicit_casting:
|
218 |
+
|
219 |
+
Implicit casting
|
220 |
+
================
|
221 |
+
|
222 |
+
When using the C++ interface for Python types, or calling Python functions,
|
223 |
+
objects of type :class:`object` are returned. It is possible to invoke implicit
|
224 |
+
conversions to subclasses like :class:`dict`. The same holds for the proxy objects
|
225 |
+
returned by ``operator[]`` or ``obj.attr()``.
|
226 |
+
Casting to subtypes improves code readability and allows values to be passed to
|
227 |
+
C++ functions that require a specific subtype rather than a generic :class:`object`.
|
228 |
+
|
229 |
+
.. code-block:: cpp
|
230 |
+
|
231 |
+
#include <pybind11/numpy.h>
|
232 |
+
using namespace pybind11::literals;
|
233 |
+
|
234 |
+
py::module_ os = py::module_::import("os");
|
235 |
+
py::module_ path = py::module_::import("os.path"); // like 'import os.path as path'
|
236 |
+
py::module_ np = py::module_::import("numpy"); // like 'import numpy as np'
|
237 |
+
|
238 |
+
py::str curdir_abs = path.attr("abspath")(path.attr("curdir"));
|
239 |
+
py::print(py::str("Current directory: ") + curdir_abs);
|
240 |
+
py::dict environ = os.attr("environ");
|
241 |
+
py::print(environ["HOME"]);
|
242 |
+
py::array_t<float> arr = np.attr("ones")(3, "dtype"_a="float32");
|
243 |
+
py::print(py::repr(arr + py::int_(1)));
|
244 |
+
|
245 |
+
These implicit conversions are available for subclasses of :class:`object`; there
|
246 |
+
is no need to call ``obj.cast()`` explicitly as for custom classes, see
|
247 |
+
:ref:`casting_back_and_forth`.
|
248 |
+
|
249 |
+
.. note::
|
250 |
+
If a trivial conversion via move constructor is not possible, both implicit and
|
251 |
+
explicit casting (calling ``obj.cast()``) will attempt a "rich" conversion.
|
252 |
+
For instance, ``py::list env = os.attr("environ");`` will succeed and is
|
253 |
+
equivalent to the Python code ``env = list(os.environ)`` that produces a
|
254 |
+
list of the dict keys.
|
255 |
+
|
256 |
+
.. TODO: Adapt text once PR #2349 has landed
|
257 |
+
|
258 |
+
Handling exceptions
|
259 |
+
===================
|
260 |
+
|
261 |
+
Python exceptions from wrapper classes will be thrown as a ``py::error_already_set``.
|
262 |
+
See :ref:`Handling exceptions from Python in C++
|
263 |
+
<handling_python_exceptions_cpp>` for more information on handling exceptions
|
264 |
+
raised when calling C++ wrapper classes.
|
265 |
+
|
266 |
+
.. _pytypes_gotchas:
|
267 |
+
|
268 |
+
Gotchas
|
269 |
+
=======
|
270 |
+
|
271 |
+
Default-Constructed Wrappers
|
272 |
+
----------------------------
|
273 |
+
|
274 |
+
When a wrapper type is default-constructed, it is **not** a valid Python object (i.e. it is not ``py::none()``). It is simply the same as
|
275 |
+
``PyObject*`` null pointer. To check for this, use
|
276 |
+
``static_cast<bool>(my_wrapper)``.
|
277 |
+
|
278 |
+
Assigning py::none() to wrappers
|
279 |
+
--------------------------------
|
280 |
+
|
281 |
+
You may be tempted to use types like ``py::str`` and ``py::dict`` in C++
|
282 |
+
signatures (either pure C++, or in bound signatures), and assign them default
|
283 |
+
values of ``py::none()``. However, in a best case scenario, it will fail fast
|
284 |
+
because ``None`` is not convertible to that type (e.g. ``py::dict``), or in a
|
285 |
+
worse case scenario, it will silently work but corrupt the types you want to
|
286 |
+
work with (e.g. ``py::str(py::none())`` will yield ``"None"`` in Python).
|
third-party/DPVO/calib/barn.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
1161.545689 1161.545689 960.000000 540.000000 -0.025158 0.0 0.0 0.0
|
third-party/DPVO/calib/eth.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
726.21081542969 726.21081542969 359.2048034668 202.47247314453
|
third-party/DPVO/calib/euroc.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
458.654 457.296 367.215 248.375 -0.28340811 0.07395907 0.00019359 1.76187114e-05
|
third-party/DPVO/calib/iphone.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
1660.0 1660.0 960.000000 540.000000 0.07 -0.08 0 0
|
third-party/DPVO/calib/kitti.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
718.8 718.8 607 185
|
third-party/DPVO/calib/monovo.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
256.0 256.0 320.0 240.0
|
third-party/DPVO/calib/tartan.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
320.0 320.0 320.0 240.0
|
third-party/DPVO/calib/tum3.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
535.4 539.2 320.1 247.6
|
third-party/DPVO/calib/viper.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
2315.52 2315.52 940 540
|
third-party/DPVO/config/default.yaml
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
### DPVO Config File ###
|
2 |
+
|
3 |
+
# VO config (increase for better accuracy)
|
4 |
+
PATCHES_PER_FRAME: 96
|
5 |
+
REMOVAL_WINDOW: 22
|
6 |
+
OPTIMIZATION_WINDOW: 10
|
7 |
+
PATCH_LIFETIME: 13
|
8 |
+
|
9 |
+
# threshold for keyframe removal
|
10 |
+
KEYFRAME_THRESH: 15.0
|
11 |
+
|
12 |
+
# camera motion model
|
13 |
+
MOTION_MODEL: 'DAMPED_LINEAR'
|
14 |
+
MOTION_DAMPING: 0.5
|
15 |
+
|
16 |
+
# maybe use mixed precision for inference
|
17 |
+
MIXED_PRECISION: True
|
18 |
+
|
19 |
+
CENTROID_SEL_STRAT: 'RANDOM'
|
third-party/DPVO/config/fast.yaml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
### DPVO Config File ###
|
3 |
+
|
4 |
+
# VO config (increase for better accuracy)
|
5 |
+
PATCHES_PER_FRAME: 48
|
6 |
+
REMOVAL_WINDOW: 16
|
7 |
+
OPTIMIZATION_WINDOW: 7
|
8 |
+
PATCH_LIFETIME: 11
|
9 |
+
|
10 |
+
# threshold for keyframe removal
|
11 |
+
KEYFRAME_THRESH: 15.0
|
12 |
+
|
13 |
+
# camera motion model
|
14 |
+
MOTION_MODEL: 'DAMPED_LINEAR'
|
15 |
+
MOTION_DAMPING: 0.5
|
16 |
+
|
17 |
+
# maybe use mixed precision for inference
|
18 |
+
MIXED_PRECISION: True
|
19 |
+
|
20 |
+
CENTROID_SEL_STRAT: 'RANDOM'
|
third-party/DPVO/datasets/euroc_groundtruth/MH_01_easy.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/MH_02_easy.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/MH_03_medium.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/MH_04_difficult.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/MH_05_difficult.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V1_01_easy.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V1_02_medium.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V1_03_difficult.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V2_01_easy.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V2_02_medium.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/datasets/euroc_groundtruth/V2_03_difficult.txt
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/demo.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from multiprocessing import Process, Queue
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
import cv2
|
6 |
+
import numpy as np
|
7 |
+
import torch
|
8 |
+
from evo.core.trajectory import PoseTrajectory3D
|
9 |
+
from evo.tools import file_interface
|
10 |
+
|
11 |
+
from dpvo.config import cfg
|
12 |
+
from dpvo.dpvo import DPVO
|
13 |
+
from dpvo.plot_utils import plot_trajectory, save_output_for_COLMAP, save_ply
|
14 |
+
from dpvo.stream import image_stream, video_stream
|
15 |
+
from dpvo.utils import Timer
|
16 |
+
|
17 |
+
SKIP = 0
|
18 |
+
|
19 |
+
def show_image(image, t=0):
|
20 |
+
image = image.permute(1, 2, 0).cpu().numpy()
|
21 |
+
cv2.imshow('image', image / 255.0)
|
22 |
+
cv2.waitKey(t)
|
23 |
+
|
24 |
+
@torch.no_grad()
|
25 |
+
def run(cfg, network, imagedir, calib, stride=1, skip=0, viz=False, timeit=False):
|
26 |
+
|
27 |
+
slam = None
|
28 |
+
queue = Queue(maxsize=8)
|
29 |
+
|
30 |
+
if os.path.isdir(imagedir):
|
31 |
+
reader = Process(target=image_stream, args=(queue, imagedir, calib, stride, skip))
|
32 |
+
else:
|
33 |
+
reader = Process(target=video_stream, args=(queue, imagedir, calib, stride, skip))
|
34 |
+
|
35 |
+
reader.start()
|
36 |
+
|
37 |
+
while 1:
|
38 |
+
(t, image, intrinsics) = queue.get()
|
39 |
+
if t < 0: break
|
40 |
+
|
41 |
+
image = torch.from_numpy(image).permute(2,0,1).cuda()
|
42 |
+
intrinsics = torch.from_numpy(intrinsics).cuda()
|
43 |
+
|
44 |
+
if slam is None:
|
45 |
+
_, H, W = image.shape
|
46 |
+
slam = DPVO(cfg, network, ht=H, wd=W, viz=viz)
|
47 |
+
|
48 |
+
with Timer("SLAM", enabled=timeit):
|
49 |
+
slam(t, image, intrinsics)
|
50 |
+
|
51 |
+
reader.join()
|
52 |
+
|
53 |
+
points = slam.pg.points_.cpu().numpy()[:slam.m]
|
54 |
+
colors = slam.pg.colors_.view(-1, 3).cpu().numpy()[:slam.m]
|
55 |
+
|
56 |
+
return slam.terminate(), (points, colors, (*intrinsics, H, W))
|
57 |
+
|
58 |
+
|
59 |
+
if __name__ == '__main__':
|
60 |
+
import argparse
|
61 |
+
parser = argparse.ArgumentParser()
|
62 |
+
parser.add_argument('--network', type=str, default='dpvo.pth')
|
63 |
+
parser.add_argument('--imagedir', type=str)
|
64 |
+
parser.add_argument('--calib', type=str)
|
65 |
+
parser.add_argument('--name', type=str, help='name your run', default='result')
|
66 |
+
parser.add_argument('--stride', type=int, default=2)
|
67 |
+
parser.add_argument('--skip', type=int, default=0)
|
68 |
+
parser.add_argument('--config', default="config/default.yaml")
|
69 |
+
parser.add_argument('--timeit', action='store_true')
|
70 |
+
parser.add_argument('--viz', action="store_true")
|
71 |
+
parser.add_argument('--plot', action="store_true")
|
72 |
+
parser.add_argument('--opts', nargs='+', default=[])
|
73 |
+
parser.add_argument('--save_ply', action="store_true")
|
74 |
+
parser.add_argument('--save_colmap', action="store_true")
|
75 |
+
parser.add_argument('--save_trajectory', action="store_true")
|
76 |
+
args = parser.parse_args()
|
77 |
+
|
78 |
+
cfg.merge_from_file(args.config)
|
79 |
+
cfg.merge_from_list(args.opts)
|
80 |
+
|
81 |
+
print("Running with config...")
|
82 |
+
print(cfg)
|
83 |
+
|
84 |
+
(poses, tstamps), (points, colors, calib) = run(cfg, args.network, args.imagedir, args.calib, args.stride, args.skip, args.viz, args.timeit)
|
85 |
+
trajectory = PoseTrajectory3D(positions_xyz=poses[:,:3], orientations_quat_wxyz=poses[:, [6, 3, 4, 5]], timestamps=tstamps)
|
86 |
+
|
87 |
+
if args.save_ply:
|
88 |
+
save_ply(args.name, points, colors)
|
89 |
+
|
90 |
+
if args.save_colmap:
|
91 |
+
save_output_for_COLMAP(args.name, trajectory, points, colors, *calib)
|
92 |
+
|
93 |
+
if args.save_trajectory:
|
94 |
+
Path("saved_trajectories").mkdir(exist_ok=True)
|
95 |
+
file_interface.write_tum_trajectory_file(f"saved_trajectories/{args.name}.txt", trajectory)
|
96 |
+
|
97 |
+
if args.plot:
|
98 |
+
Path("trajectory_plots").mkdir(exist_ok=True)
|
99 |
+
plot_trajectory(trajectory, title=f"DPVO Trajectory Prediction for {args.name}", filename=f"trajectory_plots/{args.name}.pdf")
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
|
third-party/DPVO/dist/dpvo-0.0.0-py3.9-win-amd64.egg
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4259b336d7d70d1ccf0113122351ee34a5196418961aebb42a7cb9f7cc0ca0ca
|
3 |
+
size 1405854
|