aboutsummaryrefslogtreecommitdiffstats
path: root/3rdparty/pybind11/tests/test_local_bindings.cpp
blob: c61e388833d1702fc8c470cf7196622213467dc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
    tests/test_local_bindings.cpp -- tests the py::module_local class feature which makes a class
                                     binding local to the module in which it is defined.

    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include "pybind11_tests.h"
#include "local_bindings.h"
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <numeric>

TEST_SUBMODULE(local_bindings, m) {
    // test_load_external
    m.def("load_external1", [](ExternalType1 &e) { return e.i; });
    m.def("load_external2", [](ExternalType2 &e) { return e.i; });

    // test_local_bindings
    // Register a class with py::module_local:
    bind_local<LocalType, -1>(m, "LocalType", py::module_local())
        .def("get3", [](LocalType &t) { return t.i + 3; })
        ;

    m.def("local_value", [](LocalType &l) { return l.i; });

    // test_nonlocal_failure
    // The main pybind11 test module is loaded first, so this registration will succeed (the second
    // one, in pybind11_cross_module_tests.cpp, is designed to fail):
    bind_local<NonLocalType, 0>(m, "NonLocalType")
        .def(py::init<int>())
        .def("get", [](LocalType &i) { return i.i; })
        ;

    // test_duplicate_local
    // py::module_local declarations should be visible across compilation units that get linked together;
    // this tries to register a duplicate local.  It depends on a definition in test_class.cpp and
    // should raise a runtime error from the duplicate definition attempt.  If test_class isn't
    // available it *also* throws a runtime error (with "test_class not enabled" as value).
    m.def("register_local_external", [m]() {
        auto main = py::module_::import("pybind11_tests");
        if (py::hasattr(main, "class_")) {
            bind_local<LocalExternal, 7>(m, "LocalExternal", py::module_local());
        }
        else throw std::runtime_error("test_class not enabled");
    });

    // test_stl_bind_local
    // stl_bind.h binders defaults to py::module_local if the types are local or converting:
    py::bind_vector<LocalVec>(m, "LocalVec");
    py::bind_map<LocalMap>(m, "LocalMap");
    // and global if the type (or one of the types, for the map) is global:
    py::bind_vector<NonLocalVec>(m, "NonLocalVec");
    py::bind_map<NonLocalMap>(m, "NonLocalMap");

    // test_stl_bind_global
    // They can, however, be overridden to global using `py::module_local(false)`:
    bind_local<NonLocal2, 10>(m, "NonLocal2");
    py::bind_vector<LocalVec2>(m, "LocalVec2", py::module_local());
    py::bind_map<NonLocalMap2>(m, "NonLocalMap2", py::module_local(false));

    // test_mixed_local_global
    // We try this both with the global type registered first and vice versa (the order shouldn't
    // matter).
    m.def("register_mixed_global", [m]() {
        bind_local<MixedGlobalLocal, 100>(m, "MixedGlobalLocal", py::module_local(false));
    });
    m.def("register_mixed_local", [m]() {
        bind_local<MixedLocalGlobal, 1000>(m, "MixedLocalGlobal", py::module_local());
    });
    m.def("get_mixed_gl", [](int i) { return MixedGlobalLocal(i); });
    m.def("get_mixed_lg", [](int i) { return MixedLocalGlobal(i); });

    // test_internal_locals_differ
    m.def("local_cpp_types_addr", []() { return (uintptr_t) &py::detail::registered_local_types_cpp(); });

    // test_stl_caster_vs_stl_bind
    m.def("load_vector_via_caster", [](std::vector<int> v) {
        return std::accumulate(v.begin(), v.end(), 0);
    });

    // test_cross_module_calls
    m.def("return_self", [](LocalVec *v) { return v; });
    m.def("return_copy", [](const LocalVec &v) { return LocalVec(v); });

    class Cat : public pets::Pet { public: Cat(std::string name) : Pet(name) {}; };
    py::class_<pets::Pet>(m, "Pet", py::module_local())
        .def("get_name", &pets::Pet::name);
    // Binding for local extending class:
    py::class_<Cat, pets::Pet>(m, "Cat")
        .def(py::init<std::string>());
    m.def("pet_name", [](pets::Pet &p) { return p.name(); });

    py::class_<MixGL>(m, "MixGL").def(py::init<int>());
    m.def("get_gl_value", [](MixGL &o) { return o.i + 10; });

    py::class_<MixGL2>(m, "MixGL2").def(py::init<int>());
}
security of every message encrypted with that key. Must be the same number of bytes as the ``block_size`` of the cipher with a given key. The nonce does not need to be kept secret and may be included alongside the ciphertext. .. class:: OFB(initialization_vector) OFB (Output Feedback) is a mode of operation for block ciphers. It transforms a block cipher into a stream cipher. :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). Must be the same number of bytes as the ``block_size`` of the cipher. Do not reuse an ``initialization_vector`` with a given ``key``. .. class:: CFB(initialization_vector) CFB (Cipher Feedback) is a mode of operation for block ciphers. It transforms a block cipher into a stream cipher. :param bytes initialization_vector: Must be random bytes. They do not need to be kept secret (they can be included in a transmitted message). Must be the same number of bytes as the ``block_size`` of the cipher. Do not reuse an ``initialization_vector`` with a given ``key``. Insecure Modes -------------- .. warning:: These modes are insecure. New applications should never make use of them, and existing applications should strongly consider migrating away. .. class:: ECB() ECB (Electronic Code Book) is the simplest mode of operation for block ciphers. Each block of data is encrypted in the same way. This means identical plaintext blocks will always result in identical ciphertext blocks, and thus result in information leakage .. _`described by Colin Percival`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html