mirror of
https://github.com/pybind/pybind11.git
synced 2025-01-19 09:25:51 +00:00
Merge branch 'master' into sh_merge_master
This commit is contained in:
commit
7953d19a7c
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -135,7 +135,7 @@ The valid options are:
|
|||||||
* Use `-G` and the name of a generator to use something different. `cmake
|
* Use `-G` and the name of a generator to use something different. `cmake
|
||||||
--help` lists the generators available.
|
--help` lists the generators available.
|
||||||
- On Unix, setting `CMAKE_GENERATER=Ninja` in your environment will give
|
- On Unix, setting `CMAKE_GENERATER=Ninja` in your environment will give
|
||||||
you automatic mulithreading on all your CMake projects!
|
you automatic multithreading on all your CMake projects!
|
||||||
* Open the `CMakeLists.txt` with QtCreator to generate for that IDE.
|
* Open the `CMakeLists.txt` with QtCreator to generate for that IDE.
|
||||||
* You can use `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to generate the `.json` file
|
* You can use `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to generate the `.json` file
|
||||||
that some tools expect.
|
that some tools expect.
|
||||||
|
@ -32,13 +32,13 @@ repos:
|
|||||||
|
|
||||||
# Black, the code formatter, natively supports pre-commit
|
# Black, the code formatter, natively supports pre-commit
|
||||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
rev: "23.7.0" # Keep in sync with blacken-docs
|
rev: "23.9.1" # Keep in sync with blacken-docs
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
# Ruff, the Python auto-correcting linter written in Rust
|
# Ruff, the Python auto-correcting linter written in Rust
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.0.287
|
rev: v0.0.292
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: ["--fix", "--show-fixes"]
|
args: ["--fix", "--show-fixes"]
|
||||||
@ -126,7 +126,7 @@ repos:
|
|||||||
# Use tools/codespell_ignore_lines_from_errors.py
|
# Use tools/codespell_ignore_lines_from_errors.py
|
||||||
# to rebuild .codespell-ignore-lines
|
# to rebuild .codespell-ignore-lines
|
||||||
- repo: https://github.com/codespell-project/codespell
|
- repo: https://github.com/codespell-project/codespell
|
||||||
rev: "v2.2.5"
|
rev: "v2.2.6"
|
||||||
hooks:
|
hooks:
|
||||||
- id: codespell
|
- id: codespell
|
||||||
exclude: ".supp$"
|
exclude: ".supp$"
|
||||||
@ -134,7 +134,7 @@ repos:
|
|||||||
|
|
||||||
# Check for common shell mistakes
|
# Check for common shell mistakes
|
||||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||||
rev: "v0.9.0.5"
|
rev: "v0.9.0.6"
|
||||||
hooks:
|
hooks:
|
||||||
- id: shellcheck
|
- id: shellcheck
|
||||||
|
|
||||||
@ -144,12 +144,12 @@ repos:
|
|||||||
- id: disallow-caps
|
- id: disallow-caps
|
||||||
name: Disallow improper capitalization
|
name: Disallow improper capitalization
|
||||||
language: pygrep
|
language: pygrep
|
||||||
entry: PyBind|Numpy|Cmake|CCache|PyTest
|
entry: PyBind|\bNumpy\b|Cmake|CCache|PyTest
|
||||||
exclude: ^\.pre-commit-config.yaml$
|
exclude: ^\.pre-commit-config.yaml$
|
||||||
|
|
||||||
# PyLint has native support - not always usable, but works for us
|
# PyLint has native support - not always usable, but works for us
|
||||||
- repo: https://github.com/PyCQA/pylint
|
- repo: https://github.com/PyCQA/pylint
|
||||||
rev: "v3.0.0a7"
|
rev: "v3.0.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pylint
|
- id: pylint
|
||||||
files: ^pybind11
|
files: ^pybind11
|
||||||
|
@ -5,6 +5,11 @@
|
|||||||
# All rights reserved. Use of this source code is governed by a
|
# All rights reserved. Use of this source code is governed by a
|
||||||
# BSD-style license that can be found in the LICENSE file.
|
# BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
# Propagate this policy (FindPythonInterp removal) so it can be detected later
|
||||||
|
if(NOT CMAKE_VERSION VERSION_LESS "3.27")
|
||||||
|
cmake_policy(GET CMP0148 _pybind11_cmp0148)
|
||||||
|
endif()
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
# The `cmake_minimum_required(VERSION 3.5...3.26)` syntax does not work with
|
# The `cmake_minimum_required(VERSION 3.5...3.26)` syntax does not work with
|
||||||
@ -16,6 +21,11 @@ else()
|
|||||||
cmake_policy(VERSION 3.26)
|
cmake_policy(VERSION 3.26)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(_pybind11_cmp0148)
|
||||||
|
cmake_policy(SET CMP0148 ${_pybind11_cmp0148})
|
||||||
|
unset(_pybind11_cmp0148)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Avoid infinite recursion if tests include this as a subdirectory
|
# Avoid infinite recursion if tests include this as a subdirectory
|
||||||
if(DEFINED PYBIND11_MASTER_PROJECT)
|
if(DEFINED PYBIND11_MASTER_PROJECT)
|
||||||
return()
|
return()
|
||||||
|
@ -695,7 +695,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto name
|
static constexpr auto name
|
||||||
= const_name("Tuple[") + concat(make_caster<Ts>::name...) + const_name("]");
|
= const_name("tuple[") + concat(make_caster<Ts>::name...) + const_name("]");
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using cast_op_type = type;
|
using cast_op_type = type;
|
||||||
@ -920,6 +920,10 @@ struct handle_type_name<bytes> {
|
|||||||
static constexpr auto name = const_name(PYBIND11_BYTES_NAME);
|
static constexpr auto name = const_name(PYBIND11_BYTES_NAME);
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
|
struct handle_type_name<buffer> {
|
||||||
|
static constexpr auto name = const_name("Buffer");
|
||||||
|
};
|
||||||
|
template <>
|
||||||
struct handle_type_name<int_> {
|
struct handle_type_name<int_> {
|
||||||
static constexpr auto name = const_name("int");
|
static constexpr auto name = const_name("int");
|
||||||
};
|
};
|
||||||
@ -940,10 +944,18 @@ struct handle_type_name<function> {
|
|||||||
static constexpr auto name = const_name("Callable");
|
static constexpr auto name = const_name("Callable");
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
|
struct handle_type_name<handle> {
|
||||||
|
static constexpr auto name = handle_type_name<object>::name;
|
||||||
|
};
|
||||||
|
template <>
|
||||||
struct handle_type_name<none> {
|
struct handle_type_name<none> {
|
||||||
static constexpr auto name = const_name("None");
|
static constexpr auto name = const_name("None");
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
|
struct handle_type_name<sequence> {
|
||||||
|
static constexpr auto name = const_name("Sequence");
|
||||||
|
};
|
||||||
|
template <>
|
||||||
struct handle_type_name<args> {
|
struct handle_type_name<args> {
|
||||||
static constexpr auto name = const_name("*args");
|
static constexpr auto name = const_name("*args");
|
||||||
};
|
};
|
||||||
|
@ -66,7 +66,7 @@ constexpr bool is_alias(void *) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
|
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
|
||||||
// back to brace aggregate initiailization so that for aggregate initialization can be used with
|
// back to brace aggregate initialization so that for aggregate initialization can be used with
|
||||||
// py::init, e.g. `py::init<int, int>` to initialize a `struct T { int a; int b; }`. For
|
// py::init, e.g. `py::init<int, int>` to initialize a `struct T { int a; int b; }`. For
|
||||||
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
|
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
|
||||||
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
|
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
|
||||||
|
@ -462,6 +462,7 @@ inline object get_python_state_dict() {
|
|||||||
#endif
|
#endif
|
||||||
if (!state_dict) {
|
if (!state_dict) {
|
||||||
raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
|
raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
|
||||||
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return state_dict;
|
return state_dict;
|
||||||
}
|
}
|
||||||
@ -474,6 +475,7 @@ inline internals **get_internals_pp_from_capsule(handle obj) {
|
|||||||
void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), /*name=*/nullptr);
|
void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), /*name=*/nullptr);
|
||||||
if (raw_ptr == nullptr) {
|
if (raw_ptr == nullptr) {
|
||||||
raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
|
raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
|
||||||
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return static_cast<internals **>(raw_ptr);
|
return static_cast<internals **>(raw_ptr);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,20 @@ inline numpy_internals &get_numpy_internals() {
|
|||||||
return *ptr;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PYBIND11_NOINLINE module_ import_numpy_core_submodule(const char *submodule_name) {
|
||||||
|
module_ numpy = module_::import("numpy");
|
||||||
|
str version_string = numpy.attr("__version__");
|
||||||
|
|
||||||
|
module_ numpy_lib = module_::import("numpy.lib");
|
||||||
|
object numpy_version = numpy_lib.attr("NumpyVersion")(version_string);
|
||||||
|
int major_version = numpy_version.attr("major").cast<int>();
|
||||||
|
|
||||||
|
/* `numpy.core` was renamed to `numpy._core` in NumPy 2.0 as it officially
|
||||||
|
became a private module. */
|
||||||
|
std::string numpy_core_path = major_version >= 2 ? "numpy._core" : "numpy.core";
|
||||||
|
return module_::import((numpy_core_path + "." + submodule_name).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct same_size {
|
struct same_size {
|
||||||
template <typename U>
|
template <typename U>
|
||||||
@ -263,9 +277,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static npy_api lookup() {
|
static npy_api lookup() {
|
||||||
module_ m = module_::import("numpy.core.multiarray");
|
module_ m = detail::import_numpy_core_submodule("multiarray");
|
||||||
auto c = m.attr("_ARRAY_API");
|
auto c = m.attr("_ARRAY_API");
|
||||||
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);
|
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);
|
||||||
|
if (api_ptr == nullptr) {
|
||||||
|
raise_from(PyExc_SystemError, "FAILURE obtaining numpy _ARRAY_API pointer.");
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
npy_api api;
|
npy_api api;
|
||||||
#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
|
#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
|
||||||
DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);
|
DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);
|
||||||
@ -626,11 +644,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static object _dtype_from_pep3118() {
|
static object _dtype_from_pep3118() {
|
||||||
static PyObject *obj = module_::import("numpy.core._internal")
|
module_ m = detail::import_numpy_core_submodule("_internal");
|
||||||
.attr("_dtype_from_pep3118")
|
static PyObject *obj = m.attr("_dtype_from_pep3118").cast<object>().release().ptr();
|
||||||
.cast<object>()
|
|
||||||
.release()
|
|
||||||
.ptr();
|
|
||||||
return reinterpret_borrow<object>(obj);
|
return reinterpret_borrow<object>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,11 +58,13 @@ inline std::string replace_newlines_and_squash(const char *text) {
|
|||||||
std::string result(text);
|
std::string result(text);
|
||||||
bool previous_is_whitespace = false;
|
bool previous_is_whitespace = false;
|
||||||
|
|
||||||
// Do not modify string representations
|
if (result.size() >= 2) {
|
||||||
char first_char = result[0];
|
// Do not modify string representations
|
||||||
char last_char = result[result.size() - 1];
|
char first_char = result[0];
|
||||||
if (first_char == last_char && first_char == '\'') {
|
char last_char = result[result.size() - 1];
|
||||||
return result;
|
if (first_char == last_char && first_char == '\'') {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
@ -1141,7 +1143,7 @@ protected:
|
|||||||
}
|
}
|
||||||
msg += "kwargs: ";
|
msg += "kwargs: ";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto kwarg : kwargs) {
|
for (const auto &kwarg : kwargs) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,7 +100,7 @@ public:
|
|||||||
return s.release();
|
return s.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]"));
|
PYBIND11_TYPE_CASTER(type, const_name("set[") + key_conv::name + const_name("]"));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Type, typename Key, typename Value>
|
template <typename Type, typename Key, typename Value>
|
||||||
@ -157,7 +157,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(Type,
|
PYBIND11_TYPE_CASTER(Type,
|
||||||
const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name
|
const_name("dict[") + key_conv::name + const_name(", ") + value_conv::name
|
||||||
+ const_name("]"));
|
+ const_name("]"));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ public:
|
|||||||
return l.release();
|
return l.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(Type, const_name("List[") + value_conv::name + const_name("]"));
|
PYBIND11_TYPE_CASTER(Type, const_name("list[") + value_conv::name + const_name("]"));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Type, typename Alloc>
|
template <typename Type, typename Alloc>
|
||||||
@ -274,7 +274,7 @@ public:
|
|||||||
|
|
||||||
PYBIND11_TYPE_CASTER(ArrayType,
|
PYBIND11_TYPE_CASTER(ArrayType,
|
||||||
const_name<Resizable>(const_name(""), const_name("Annotated["))
|
const_name<Resizable>(const_name(""), const_name("Annotated["))
|
||||||
+ const_name("List[") + value_conv::name + const_name("]")
|
+ const_name("list[") + value_conv::name + const_name("]")
|
||||||
+ const_name<Resizable>(const_name(""),
|
+ const_name<Resizable>(const_name(""),
|
||||||
const_name(", FixedSize(")
|
const_name(", FixedSize(")
|
||||||
+ const_name<Size>() + const_name(")]")));
|
+ const_name<Size>() + const_name(")]")));
|
||||||
|
@ -45,6 +45,16 @@ class Set : public set {
|
|||||||
using set::set;
|
using set::set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Iterable : public iterable {
|
||||||
|
using iterable::iterable;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Iterator : public iterator {
|
||||||
|
using iterator::iterator;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Signature>
|
template <typename Signature>
|
||||||
class Callable;
|
class Callable;
|
||||||
|
|
||||||
@ -85,6 +95,16 @@ struct handle_type_name<typing::Set<T>> {
|
|||||||
static constexpr auto name = const_name("set[") + make_caster<T>::name + const_name("]");
|
static constexpr auto name = const_name("set[") + make_caster<T>::name + const_name("]");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct handle_type_name<typing::Iterable<T>> {
|
||||||
|
static constexpr auto name = const_name("Iterable[") + make_caster<T>::name + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct handle_type_name<typing::Iterator<T>> {
|
||||||
|
static constexpr auto name = const_name("Iterator[") + make_caster<T>::name + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Return, typename... Args>
|
template <typename Return, typename... Args>
|
||||||
struct handle_type_name<typing::Callable<Return(Args...)>> {
|
struct handle_type_name<typing::Callable<Return(Args...)>> {
|
||||||
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
||||||
|
@ -219,3 +219,10 @@ def test_ctypes_from_buffer():
|
|||||||
assert cinfo.shape == pyinfo.shape
|
assert cinfo.shape == pyinfo.shape
|
||||||
assert cinfo.strides == pyinfo.strides
|
assert cinfo.strides == pyinfo.strides
|
||||||
assert not cinfo.readonly
|
assert not cinfo.readonly
|
||||||
|
|
||||||
|
|
||||||
|
def test_buffer_docstring():
|
||||||
|
assert (
|
||||||
|
m.get_buffer_info.__doc__.strip()
|
||||||
|
== "get_buffer_info(arg0: Buffer) -> pybind11_tests.buffers.buffer_info"
|
||||||
|
)
|
||||||
|
@ -352,7 +352,7 @@ def test_tuple(doc):
|
|||||||
assert (
|
assert (
|
||||||
doc(m.pair_passthrough)
|
doc(m.pair_passthrough)
|
||||||
== """
|
== """
|
||||||
pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
|
pair_passthrough(arg0: tuple[bool, str]) -> tuple[str, bool]
|
||||||
|
|
||||||
Return a pair in reversed order
|
Return a pair in reversed order
|
||||||
"""
|
"""
|
||||||
@ -360,7 +360,7 @@ def test_tuple(doc):
|
|||||||
assert (
|
assert (
|
||||||
doc(m.tuple_passthrough)
|
doc(m.tuple_passthrough)
|
||||||
== """
|
== """
|
||||||
tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
|
tuple_passthrough(arg0: tuple[bool, str, int]) -> tuple[int, str, bool]
|
||||||
|
|
||||||
Return a triple in reversed order
|
Return a triple in reversed order
|
||||||
"""
|
"""
|
||||||
|
@ -77,7 +77,7 @@ def test_init_factory_signature(msg):
|
|||||||
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)
|
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)
|
||||||
2. m.factory_constructors.TestFactory1(arg0: str)
|
2. m.factory_constructors.TestFactory1(arg0: str)
|
||||||
3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)
|
3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)
|
||||||
4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle)
|
4. m.factory_constructors.TestFactory1(arg0: object, arg1: int, arg2: object)
|
||||||
|
|
||||||
Invoked with: 'invalid', 'constructor', 'arguments'
|
Invoked with: 'invalid', 'constructor', 'arguments'
|
||||||
"""
|
"""
|
||||||
@ -95,7 +95,7 @@ def test_init_factory_signature(msg):
|
|||||||
|
|
||||||
3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
|
3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
|
||||||
|
|
||||||
4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
|
4. __init__(self: m.factory_constructors.TestFactory1, arg0: object, arg1: int, arg2: object) -> None
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -85,6 +85,8 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
|
|||||||
"kw_lb_func7",
|
"kw_lb_func7",
|
||||||
[](const std::string &) {},
|
[](const std::string &) {},
|
||||||
py::arg("str_arg") = "First line.\n Second line.");
|
py::arg("str_arg") = "First line.\n Second line.");
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func8", [](const CustomRepr &) {}, py::arg("custom") = CustomRepr(""));
|
||||||
|
|
||||||
// test_args_and_kwargs
|
// test_args_and_kwargs
|
||||||
m.def("args_function", [](py::args args) -> py::tuple {
|
m.def("args_function", [](py::args args) -> py::tuple {
|
||||||
|
@ -8,7 +8,7 @@ def test_function_signatures(doc):
|
|||||||
assert doc(m.kw_func1) == "kw_func1(x: int, y: int) -> str"
|
assert doc(m.kw_func1) == "kw_func1(x: int, y: int) -> str"
|
||||||
assert doc(m.kw_func2) == "kw_func2(x: int = 100, y: int = 200) -> str"
|
assert doc(m.kw_func2) == "kw_func2(x: int = 100, y: int = 200) -> str"
|
||||||
assert doc(m.kw_func3) == "kw_func3(data: str = 'Hello world!') -> None"
|
assert doc(m.kw_func3) == "kw_func3(data: str = 'Hello world!') -> None"
|
||||||
assert doc(m.kw_func4) == "kw_func4(myList: List[int] = [13, 17]) -> str"
|
assert doc(m.kw_func4) == "kw_func4(myList: list[int] = [13, 17]) -> str"
|
||||||
assert doc(m.kw_func_udl) == "kw_func_udl(x: int, y: int = 300) -> str"
|
assert doc(m.kw_func_udl) == "kw_func_udl(x: int, y: int = 300) -> str"
|
||||||
assert doc(m.kw_func_udl_z) == "kw_func_udl_z(x: int, y: int = 0) -> str"
|
assert doc(m.kw_func_udl_z) == "kw_func_udl_z(x: int, y: int = 0) -> str"
|
||||||
assert doc(m.args_function) == "args_function(*args) -> tuple"
|
assert doc(m.args_function) == "args_function(*args) -> tuple"
|
||||||
@ -55,6 +55,10 @@ def test_function_signatures(doc):
|
|||||||
doc(m.kw_lb_func7)
|
doc(m.kw_lb_func7)
|
||||||
== "kw_lb_func7(str_arg: str = 'First line.\\n Second line.') -> None"
|
== "kw_lb_func7(str_arg: str = 'First line.\\n Second line.') -> None"
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func8)
|
||||||
|
== "kw_lb_func8(custom: m.kwargs_and_defaults.CustomRepr = ) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_named_arguments():
|
def test_named_arguments():
|
||||||
|
@ -298,7 +298,7 @@ def test_constructors():
|
|||||||
results = m.converting_constructors([1, 2, 3])
|
results = m.converting_constructors([1, 2, 3])
|
||||||
for a in results.values():
|
for a in results.values():
|
||||||
np.testing.assert_array_equal(a, [1, 2, 3])
|
np.testing.assert_array_equal(a, [1, 2, 3])
|
||||||
assert results["array"].dtype == np.int_
|
assert results["array"].dtype == np.dtype(int)
|
||||||
assert results["array_t<int32>"].dtype == np.int32
|
assert results["array_t<int32>"].dtype == np.int32
|
||||||
assert results["array_t<double>"].dtype == np.float64
|
assert results["array_t<double>"].dtype == np.float64
|
||||||
|
|
||||||
|
@ -828,6 +828,8 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
m.def("annotate_dict_str_int", [](const py::typing::Dict<py::str, int> &) {});
|
m.def("annotate_dict_str_int", [](const py::typing::Dict<py::str, int> &) {});
|
||||||
m.def("annotate_list_int", [](const py::typing::List<int> &) {});
|
m.def("annotate_list_int", [](const py::typing::List<int> &) {});
|
||||||
m.def("annotate_set_str", [](const py::typing::Set<std::string> &) {});
|
m.def("annotate_set_str", [](const py::typing::Set<std::string> &) {});
|
||||||
|
m.def("annotate_iterable_str", [](const py::typing::Iterable<std::string> &) {});
|
||||||
|
m.def("annotate_iterator_int", [](const py::typing::Iterator<int> &) {});
|
||||||
m.def("annotate_fn",
|
m.def("annotate_fn",
|
||||||
[](const py::typing::Callable<int(py::typing::List<py::str>, py::str)> &) {});
|
[](const py::typing::Callable<int(py::typing::List<py::str>, py::str)> &) {});
|
||||||
}
|
}
|
||||||
|
@ -926,6 +926,20 @@ def test_set_annotations(doc):
|
|||||||
assert doc(m.annotate_set_str) == "annotate_set_str(arg0: set[str]) -> None"
|
assert doc(m.annotate_set_str) == "annotate_set_str(arg0: set[str]) -> None"
|
||||||
|
|
||||||
|
|
||||||
|
def test_iterable_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_iterable_str)
|
||||||
|
== "annotate_iterable_str(arg0: Iterable[str]) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_iterator_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_iterator_int)
|
||||||
|
== "annotate_iterator_int(arg0: Iterator[int]) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_fn_annotations(doc):
|
def test_fn_annotations(doc):
|
||||||
assert (
|
assert (
|
||||||
doc(m.annotate_fn)
|
doc(m.annotate_fn)
|
||||||
|
@ -171,6 +171,10 @@ def test_sequence_length():
|
|||||||
assert m.sequence_length("hello") == 5
|
assert m.sequence_length("hello") == 5
|
||||||
|
|
||||||
|
|
||||||
|
def test_sequence_doc():
|
||||||
|
assert m.sequence_length.__doc__.strip() == "sequence_length(arg0: Sequence) -> int"
|
||||||
|
|
||||||
|
|
||||||
def test_map_iterator():
|
def test_map_iterator():
|
||||||
sm = m.StringMap({"hi": "bye", "black": "white"})
|
sm = m.StringMap({"hi": "bye", "black": "white"})
|
||||||
assert sm["hi"] == "bye"
|
assert sm["hi"] == "bye"
|
||||||
|
@ -16,8 +16,8 @@ def test_vector(doc):
|
|||||||
assert m.load_bool_vector([True, False])
|
assert m.load_bool_vector([True, False])
|
||||||
assert m.load_bool_vector((True, False))
|
assert m.load_bool_vector((True, False))
|
||||||
|
|
||||||
assert doc(m.cast_vector) == "cast_vector() -> List[int]"
|
assert doc(m.cast_vector) == "cast_vector() -> list[int]"
|
||||||
assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"
|
assert doc(m.load_vector) == "load_vector(arg0: list[int]) -> bool"
|
||||||
|
|
||||||
# Test regression caused by 936: pointers to stl containers weren't castable
|
# Test regression caused by 936: pointers to stl containers weren't castable
|
||||||
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
assert m.cast_ptr_vector() == ["lvalue", "lvalue"]
|
||||||
@ -39,10 +39,10 @@ def test_array(doc):
|
|||||||
assert m.load_array(lst)
|
assert m.load_array(lst)
|
||||||
assert m.load_array(tuple(lst))
|
assert m.load_array(tuple(lst))
|
||||||
|
|
||||||
assert doc(m.cast_array) == "cast_array() -> Annotated[List[int], FixedSize(2)]"
|
assert doc(m.cast_array) == "cast_array() -> Annotated[list[int], FixedSize(2)]"
|
||||||
assert (
|
assert (
|
||||||
doc(m.load_array)
|
doc(m.load_array)
|
||||||
== "load_array(arg0: Annotated[List[int], FixedSize(2)]) -> bool"
|
== "load_array(arg0: Annotated[list[int], FixedSize(2)]) -> bool"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -53,8 +53,8 @@ def test_valarray(doc):
|
|||||||
assert m.load_valarray(lst)
|
assert m.load_valarray(lst)
|
||||||
assert m.load_valarray(tuple(lst))
|
assert m.load_valarray(tuple(lst))
|
||||||
|
|
||||||
assert doc(m.cast_valarray) == "cast_valarray() -> List[int]"
|
assert doc(m.cast_valarray) == "cast_valarray() -> list[int]"
|
||||||
assert doc(m.load_valarray) == "load_valarray(arg0: List[int]) -> bool"
|
assert doc(m.load_valarray) == "load_valarray(arg0: list[int]) -> bool"
|
||||||
|
|
||||||
|
|
||||||
def test_map(doc):
|
def test_map(doc):
|
||||||
@ -66,8 +66,8 @@ def test_map(doc):
|
|||||||
assert "key2" in d
|
assert "key2" in d
|
||||||
assert m.load_map(d)
|
assert m.load_map(d)
|
||||||
|
|
||||||
assert doc(m.cast_map) == "cast_map() -> Dict[str, str]"
|
assert doc(m.cast_map) == "cast_map() -> dict[str, str]"
|
||||||
assert doc(m.load_map) == "load_map(arg0: Dict[str, str]) -> bool"
|
assert doc(m.load_map) == "load_map(arg0: dict[str, str]) -> bool"
|
||||||
|
|
||||||
|
|
||||||
def test_set(doc):
|
def test_set(doc):
|
||||||
@ -78,8 +78,8 @@ def test_set(doc):
|
|||||||
assert m.load_set(s)
|
assert m.load_set(s)
|
||||||
assert m.load_set(frozenset(s))
|
assert m.load_set(frozenset(s))
|
||||||
|
|
||||||
assert doc(m.cast_set) == "cast_set() -> Set[str]"
|
assert doc(m.cast_set) == "cast_set() -> set[str]"
|
||||||
assert doc(m.load_set) == "load_set(arg0: Set[str]) -> bool"
|
assert doc(m.load_set) == "load_set(arg0: set[str]) -> bool"
|
||||||
|
|
||||||
|
|
||||||
def test_recursive_casting():
|
def test_recursive_casting():
|
||||||
@ -303,7 +303,7 @@ def test_stl_pass_by_pointer(msg):
|
|||||||
msg(excinfo.value)
|
msg(excinfo.value)
|
||||||
== """
|
== """
|
||||||
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
||||||
1. (v: List[int] = None) -> List[int]
|
1. (v: list[int] = None) -> list[int]
|
||||||
|
|
||||||
Invoked with:
|
Invoked with:
|
||||||
"""
|
"""
|
||||||
@ -315,7 +315,7 @@ def test_stl_pass_by_pointer(msg):
|
|||||||
msg(excinfo.value)
|
msg(excinfo.value)
|
||||||
== """
|
== """
|
||||||
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
|
||||||
1. (v: List[int] = None) -> List[int]
|
1. (v: list[int] = None) -> list[int]
|
||||||
|
|
||||||
Invoked with: None
|
Invoked with: None
|
||||||
"""
|
"""
|
||||||
|
@ -95,6 +95,22 @@ if(NOT PythonLibsNew_FIND_VERSION)
|
|||||||
set(PythonLibsNew_FIND_VERSION "3.6")
|
set(PythonLibsNew_FIND_VERSION "3.6")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_VERSION VERSION_LESS "3.27")
|
||||||
|
cmake_policy(GET CMP0148 _pybind11_cmp0148)
|
||||||
|
if(NOT _pybind11_cmp0148)
|
||||||
|
message(
|
||||||
|
AUTHOR_WARNING
|
||||||
|
"Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs "
|
||||||
|
"modules are removed. Run \"cmake --help-policy CMP0148\" for policy "
|
||||||
|
"details. Use the cmake_policy command to set the policy and suppress "
|
||||||
|
"this warning, or preferably upgrade to using FindPython, either by "
|
||||||
|
"calling it explicitly before pybind11, or by setting "
|
||||||
|
"PYBIND11_FINDPYTHON ON before pybind11.")
|
||||||
|
endif()
|
||||||
|
cmake_policy(SET CMP0148 OLD)
|
||||||
|
unset(_pybind11_cmp0148)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}
|
find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}
|
||||||
${_pythonlibs_quiet})
|
${_pythonlibs_quiet})
|
||||||
|
|
||||||
@ -172,13 +188,20 @@ _pybind11_get_if_undef(_PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
|
|||||||
_pybind11_get_if_undef(_PYTHON_VALUES 1 PYTHON_PREFIX)
|
_pybind11_get_if_undef(_PYTHON_VALUES 1 PYTHON_PREFIX)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
|
_pybind11_get_if_undef(_PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
|
_pybind11_get_if_undef(_PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
|
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 5 PYTHON_IS_DEBUG)
|
_pybind11_get_if_undef(_PYTHON_VALUES 5 PYTHON_IS_DEBUG)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
|
_pybind11_get_if_undef(_PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
|
_pybind11_get_if_undef(_PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 8 PYTHON_LIBDIR)
|
_pybind11_get_if_undef(_PYTHON_VALUES 8 PYTHON_LIBDIR)
|
||||||
_pybind11_get_if_undef(_PYTHON_VALUES 9 PYTHON_MULTIARCH)
|
_pybind11_get_if_undef(_PYTHON_VALUES 9 PYTHON_MULTIARCH)
|
||||||
|
|
||||||
|
list(GET _PYTHON_VALUES 4 _PYTHON_MODULE_EXT_SUFFIX)
|
||||||
|
if(PYBIND11_PYTHONLIBS_OVERWRITE OR NOT DEFINED PYTHON_MODULE_DEBUG_POSTFIX)
|
||||||
|
get_filename_component(PYTHON_MODULE_DEBUG_POSTFIX "${_PYTHON_MODULE_EXT_SUFFIX}" NAME_WE)
|
||||||
|
endif()
|
||||||
|
if(PYBIND11_PYTHONLIBS_OVERWRITE OR NOT DEFINED PYTHON_MODULE_EXTENSION)
|
||||||
|
get_filename_component(PYTHON_MODULE_EXTENSION "${_PYTHON_MODULE_EXT_SUFFIX}" EXT)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Make sure the Python has the same pointer-size as the chosen compiler
|
# Make sure the Python has the same pointer-size as the chosen compiler
|
||||||
# Skip if CMAKE_SIZEOF_VOID_P is not defined
|
# Skip if CMAKE_SIZEOF_VOID_P is not defined
|
||||||
# This should be skipped for (non-Apple) cross-compiles (like EMSCRIPTEN)
|
# This should be skipped for (non-Apple) cross-compiles (like EMSCRIPTEN)
|
||||||
|
@ -95,25 +95,36 @@ endif()
|
|||||||
|
|
||||||
# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
|
# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
|
||||||
# required for PyPy3 (as of 7.3.1)
|
# required for PyPy3 (as of 7.3.1)
|
||||||
if(NOT DEFINED PYTHON_MODULE_EXTENSION)
|
if(NOT DEFINED PYTHON_MODULE_EXTENSION OR NOT DEFINED PYTHON_MODULE_DEBUG_POSTFIX)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND
|
COMMAND
|
||||||
"${${_Python}_EXECUTABLE}" "-c"
|
"${${_Python}_EXECUTABLE}" "-c"
|
||||||
"import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))"
|
"import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))"
|
||||||
OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION
|
OUTPUT_VARIABLE _PYTHON_MODULE_EXT_SUFFIX
|
||||||
ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR
|
ERROR_VARIABLE _PYTHON_MODULE_EXT_SUFFIX_ERR
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
if(_PYTHON_MODULE_EXTENSION STREQUAL "")
|
if(_PYTHON_MODULE_EXT_SUFFIX STREQUAL "")
|
||||||
message(
|
message(
|
||||||
FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
|
FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
|
||||||
"package is not installed. Full error message:\n${_PYTHON_MODULE_EXTENSION_ERR}")
|
"package is not installed. Full error message:\n${_PYTHON_MODULE_EXT_SUFFIX_ERR}"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# This needs to be available for the pybind11_extension function
|
# This needs to be available for the pybind11_extension function
|
||||||
set(PYTHON_MODULE_EXTENSION
|
if(NOT DEFINED PYTHON_MODULE_DEBUG_POSTFIX)
|
||||||
"${_PYTHON_MODULE_EXTENSION}"
|
get_filename_component(_PYTHON_MODULE_DEBUG_POSTFIX "${_PYTHON_MODULE_EXT_SUFFIX}" NAME_WE)
|
||||||
CACHE INTERNAL "")
|
set(PYTHON_MODULE_DEBUG_POSTFIX
|
||||||
|
"${_PYTHON_MODULE_DEBUG_POSTFIX}"
|
||||||
|
CACHE INTERNAL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED PYTHON_MODULE_EXTENSION)
|
||||||
|
get_filename_component(_PYTHON_MODULE_EXTENSION "${_PYTHON_MODULE_EXT_SUFFIX}" EXT)
|
||||||
|
set(PYTHON_MODULE_EXTENSION
|
||||||
|
"${_PYTHON_MODULE_EXTENSION}"
|
||||||
|
CACHE INTERNAL "")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Python debug libraries expose slightly different objects before 3.8
|
# Python debug libraries expose slightly different objects before 3.8
|
||||||
@ -253,6 +264,9 @@ endfunction()
|
|||||||
|
|
||||||
function(pybind11_extension name)
|
function(pybind11_extension name)
|
||||||
# The extension is precomputed
|
# The extension is precomputed
|
||||||
set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
set_target_properties(
|
||||||
|
${name}
|
||||||
|
PROPERTIES PREFIX ""
|
||||||
|
DEBUG_POSTFIX "${PYTHON_MODULE_DEBUG_POSTFIX}"
|
||||||
|
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
@ -65,6 +65,7 @@ _pybind11_promote_to_cache(PYTHON_INCLUDE_DIRS)
|
|||||||
_pybind11_promote_to_cache(PYTHON_LIBRARIES)
|
_pybind11_promote_to_cache(PYTHON_LIBRARIES)
|
||||||
_pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)
|
_pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)
|
||||||
_pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)
|
_pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)
|
||||||
|
_pybind11_promote_to_cache(PYTHON_MODULE_DEBUG_POSTFIX)
|
||||||
_pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)
|
_pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)
|
||||||
_pybind11_promote_to_cache(PYTHON_VERSION_MINOR)
|
_pybind11_promote_to_cache(PYTHON_VERSION_MINOR)
|
||||||
_pybind11_promote_to_cache(PYTHON_VERSION)
|
_pybind11_promote_to_cache(PYTHON_VERSION)
|
||||||
@ -148,8 +149,11 @@ endif()
|
|||||||
|
|
||||||
function(pybind11_extension name)
|
function(pybind11_extension name)
|
||||||
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
# The prefix and extension are provided by FindPythonLibsNew.cmake
|
||||||
set_target_properties(${name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
set_target_properties(
|
||||||
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
${name}
|
||||||
|
PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
|
||||||
|
DEBUG_POSTFIX "${PYTHON_MODULE_DEBUG_POSTFIX}"
|
||||||
|
SUFFIX "${PYTHON_MODULE_EXTENSION}")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Build a Python extension module:
|
# Build a Python extension module:
|
||||||
|
Loading…
Reference in New Issue
Block a user