mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-27 07:32:02 +00:00
Merge branch 'pybind:master' into master
This commit is contained in:
commit
e7086add6c
53
.github/workflows/ci.yml
vendored
53
.github/workflows/ci.yml
vendored
@ -404,54 +404,55 @@ jobs:
|
|||||||
# run: cmake --build build --target test_cmake_build
|
# run: cmake --build build --target test_cmake_build
|
||||||
|
|
||||||
|
|
||||||
# Testing on CentOS 7 + PGI compilers, which seems to require more workarounds
|
# Testing on Ubuntu + NVHPC (previous PGI) compilers, which seems to require more workarounds
|
||||||
centos-nvhpc7:
|
ubuntu-nvhpc7:
|
||||||
if: ${{ false }} # JOB DISABLED (NEEDS WORK): https://github.com/pybind/pybind11/issues/4690
|
runs-on: ubuntu-20.04
|
||||||
runs-on: ubuntu-latest
|
name: "🐍 3 • NVHPC 23.5 • C++17 • x64"
|
||||||
name: "🐍 3 • CentOS7 / PGI 22.9 • x64"
|
|
||||||
container: centos:7
|
|
||||||
|
|
||||||
|
env:
|
||||||
|
# tzdata will try to ask for the timezone, so set the DEBIAN_FRONTEND
|
||||||
|
DEBIAN_FRONTEND: 'noninteractive'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Add Python 3 and a few requirements
|
- name: Add NVHPC Repo
|
||||||
run: yum update -y && yum install -y epel-release && yum install -y git python3-devel make environment-modules cmake3 yum-utils
|
run: |
|
||||||
|
echo 'deb [trusted=yes] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | \
|
||||||
|
sudo tee /etc/apt/sources.list.d/nvhpc.list
|
||||||
|
|
||||||
- name: Install NVidia HPC SDK
|
- name: Install 🐍 3 & NVHPC
|
||||||
run: yum-config-manager --add-repo https://developer.download.nvidia.com/hpc-sdk/rhel/nvhpc.repo && yum -y install nvhpc-22.9
|
run: |
|
||||||
|
sudo apt-get update -y && \
|
||||||
|
sudo apt-get install -y cmake environment-modules git python3-dev python3-pip python3-numpy && \
|
||||||
|
sudo apt-get install -y --no-install-recommends nvhpc-23-5 && \
|
||||||
|
sudo rm -rf /var/lib/apt/lists/*
|
||||||
|
python3 -m pip install --upgrade pip
|
||||||
|
python3 -m pip install --upgrade pytest
|
||||||
|
|
||||||
# On CentOS 7, we have to filter a few tests (compiler internal error)
|
# On some systems, you many need further workarounds:
|
||||||
# and allow deeper template recursion (not needed on CentOS 8 with a newer
|
|
||||||
# standard library). On some systems, you many need further workarounds:
|
|
||||||
# https://github.com/pybind/pybind11/pull/2475
|
# https://github.com/pybind/pybind11/pull/2475
|
||||||
- name: Configure
|
- name: Configure
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
source /etc/profile.d/modules.sh
|
source /etc/profile.d/modules.sh
|
||||||
module load /opt/nvidia/hpc_sdk/modulefiles/nvhpc/22.9
|
module load /opt/nvidia/hpc_sdk/modulefiles/nvhpc/23.5
|
||||||
cmake3 -S . -B build -DDOWNLOAD_CATCH=ON \
|
cmake -S . -B build -DDOWNLOAD_CATCH=ON \
|
||||||
-DCMAKE_CXX_STANDARD=11 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
-DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
|
-DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
|
||||||
-DCMAKE_CXX_FLAGS="-Wc,--pending_instantiations=0" \
|
-DCMAKE_CXX_FLAGS="-Wc,--pending_instantiations=0" \
|
||||||
-DPYBIND11_TEST_FILTER="test_smart_ptr.cpp"
|
-DPYBIND11_TEST_FILTER="test_smart_ptr.cpp"
|
||||||
|
|
||||||
# Building before installing Pip should produce a warning but not an error
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake3 --build build -j 2 --verbose
|
run: cmake --build build -j 2 --verbose
|
||||||
|
|
||||||
- name: Install CMake with pip
|
|
||||||
run: |
|
|
||||||
python3 -m pip install --upgrade pip
|
|
||||||
python3 -m pip install pytest
|
|
||||||
|
|
||||||
- name: Python tests
|
- name: Python tests
|
||||||
run: cmake3 --build build --target pytest
|
run: cmake --build build --target pytest
|
||||||
|
|
||||||
- name: C++ tests
|
- name: C++ tests
|
||||||
run: cmake3 --build build --target cpptest
|
run: cmake --build build --target cpptest
|
||||||
|
|
||||||
- name: Interface test
|
- name: Interface test
|
||||||
run: cmake3 --build build --target test_cmake_build
|
run: cmake --build build --target test_cmake_build
|
||||||
|
|
||||||
|
|
||||||
# Testing on GCC using the GCC docker images (only recent images supported)
|
# Testing on GCC using the GCC docker images (only recent images supported)
|
||||||
|
@ -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
|
- repo: https://github.com/psf/black
|
||||||
rev: "23.3.0" # Keep in sync with blacken-docs
|
rev: "23.7.0" # 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.276
|
rev: v0.0.281
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: ["--fix", "--show-fixes"]
|
args: ["--fix", "--show-fixes"]
|
||||||
@ -84,7 +84,7 @@ repos:
|
|||||||
|
|
||||||
# Also code format the docs
|
# Also code format the docs
|
||||||
- repo: https://github.com/asottile/blacken-docs
|
- repo: https://github.com/asottile/blacken-docs
|
||||||
rev: "1.14.0"
|
rev: "1.15.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: blacken-docs
|
- id: blacken-docs
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
|
@ -141,7 +141,8 @@ set(PYBIND11_HEADERS
|
|||||||
include/pybind11/stl.h
|
include/pybind11/stl.h
|
||||||
include/pybind11/stl_bind.h
|
include/pybind11/stl_bind.h
|
||||||
include/pybind11/stl/filesystem.h
|
include/pybind11/stl/filesystem.h
|
||||||
include/pybind11/type_caster_pyobject_ptr.h)
|
include/pybind11/type_caster_pyobject_ptr.h
|
||||||
|
include/pybind11/typing.h)
|
||||||
|
|
||||||
# Compare with grep and warn if mismatched
|
# Compare with grep and warn if mismatched
|
||||||
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
|
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
|
||||||
|
@ -398,3 +398,32 @@ before they are used as a parameter or return type of a function:
|
|||||||
pyFoo.def(py::init<const ns::Bar&>());
|
pyFoo.def(py::init<const ns::Bar&>());
|
||||||
pyBar.def(py::init<const ns::Foo&>());
|
pyBar.def(py::init<const ns::Foo&>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Setting inner type hints in docstrings
|
||||||
|
======================================
|
||||||
|
|
||||||
|
When you use pybind11 wrappers for ``list``, ``dict``, and other generic python
|
||||||
|
types, the docstring will just display the generic type. You can convey the
|
||||||
|
inner types in the docstring by using a special 'typed' version of the generic
|
||||||
|
type.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
PYBIND11_MODULE(example, m) {
|
||||||
|
m.def("pass_list_of_str", [](py::typing::List<py::str> arg) {
|
||||||
|
// arg can be used just like py::list
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
The resulting docstring will be ``pass_list_of_str(arg0: list[str]) -> None``.
|
||||||
|
|
||||||
|
The following special types are available in ``pybind11/typing.h``:
|
||||||
|
|
||||||
|
* ``py::Tuple<Args...>``
|
||||||
|
* ``py::Dict<K, V>``
|
||||||
|
* ``py::List<V>``
|
||||||
|
* ``py::Set<V>``
|
||||||
|
* ``py::Callable<Signature>``
|
||||||
|
|
||||||
|
.. warning:: Just like in python, these are merely hints. They don't actually
|
||||||
|
enforce the types of their contents at runtime or compile time.
|
||||||
|
@ -143,7 +143,7 @@ Your ``pyproject.toml`` file will likely look something like this:
|
|||||||
.. code-block:: toml
|
.. code-block:: toml
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=42", "wheel", "pybind11~=2.6.1"]
|
requires = ["setuptools>=42", "pybind11>=2.6.1"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
97
include/pybind11/typing.h
Normal file
97
include/pybind11/typing.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
pybind11/typing.h: Convenience wrapper classes for basic Python types
|
||||||
|
with more explicit annotations.
|
||||||
|
|
||||||
|
Copyright (c) 2023 Dustin Spicuzza <dustin@virtualroadside.com>
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "detail/common.h"
|
||||||
|
#include "cast.h"
|
||||||
|
#include "pytypes.h"
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(typing)
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following types can be used to direct pybind11-generated docstrings
|
||||||
|
to have have more explicit types (e.g., `list[str]` instead of `list`).
|
||||||
|
Just use these in place of existing types.
|
||||||
|
|
||||||
|
There is no additional enforcement of types at runtime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
class Tuple : public tuple {
|
||||||
|
using tuple::tuple;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
class Dict : public dict {
|
||||||
|
using dict::dict;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class List : public list {
|
||||||
|
using list::list;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Set : public set {
|
||||||
|
using set::set;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Signature>
|
||||||
|
class Callable;
|
||||||
|
|
||||||
|
template <typename Return, typename... Args>
|
||||||
|
class Callable<Return(Args...)> : public function {
|
||||||
|
using function::function;
|
||||||
|
};
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_END(typing)
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct handle_type_name<typing::Tuple<Types...>> {
|
||||||
|
static constexpr auto name
|
||||||
|
= const_name("tuple[") + concat(make_caster<Types>::name...) + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct handle_type_name<typing::Tuple<>> {
|
||||||
|
// PEP 484 specifies this syntax for an empty tuple
|
||||||
|
static constexpr auto name = const_name("tuple[()]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
struct handle_type_name<typing::Dict<K, V>> {
|
||||||
|
static constexpr auto name = const_name("dict[") + make_caster<K>::name + const_name(", ")
|
||||||
|
+ make_caster<V>::name + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct handle_type_name<typing::List<T>> {
|
||||||
|
static constexpr auto name = const_name("list[") + make_caster<T>::name + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct handle_type_name<typing::Set<T>> {
|
||||||
|
static constexpr auto name = const_name("set[") + make_caster<T>::name + const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Return, typename... Args>
|
||||||
|
struct handle_type_name<typing::Callable<Return(Args...)>> {
|
||||||
|
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
|
||||||
|
static constexpr auto name = const_name("Callable[[") + concat(make_caster<Args>::name...)
|
||||||
|
+ const_name("], ") + make_caster<retval_type>::name
|
||||||
|
+ const_name("]");
|
||||||
|
};
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
@ -44,6 +44,7 @@ main_headers = {
|
|||||||
"include/pybind11/stl.h",
|
"include/pybind11/stl.h",
|
||||||
"include/pybind11/stl_bind.h",
|
"include/pybind11/stl_bind.h",
|
||||||
"include/pybind11/type_caster_pyobject_ptr.h",
|
"include/pybind11/type_caster_pyobject_ptr.h",
|
||||||
|
"include/pybind11/typing.h",
|
||||||
}
|
}
|
||||||
|
|
||||||
detail_headers = {
|
detail_headers = {
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
BSD-style license that can be found in the LICENSE file.
|
BSD-style license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <pybind11/typing.h>
|
||||||
|
|
||||||
#include "pybind11_tests.h"
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -820,4 +822,12 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
a >>= b;
|
a >>= b;
|
||||||
return a;
|
return a;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def("annotate_tuple_float_str", [](const py::typing::Tuple<py::float_, py::str> &) {});
|
||||||
|
m.def("annotate_tuple_empty", [](const py::typing::Tuple<> &) {});
|
||||||
|
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_set_str", [](const py::typing::Set<std::string> &) {});
|
||||||
|
m.def("annotate_fn",
|
||||||
|
[](const py::typing::Callable<int(py::typing::List<py::str>, py::str)> &) {});
|
||||||
}
|
}
|
||||||
|
@ -896,3 +896,38 @@ def test_inplace_lshift(a, b):
|
|||||||
def test_inplace_rshift(a, b):
|
def test_inplace_rshift(a, b):
|
||||||
expected = a >> b
|
expected = a >> b
|
||||||
assert m.inplace_rshift(a, b) == expected
|
assert m.inplace_rshift(a, b) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_tuple_nonempty_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_tuple_float_str)
|
||||||
|
== "annotate_tuple_float_str(arg0: tuple[float, str]) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_tuple_empty_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_tuple_empty) == "annotate_tuple_empty(arg0: tuple[()]) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_dict_str_int)
|
||||||
|
== "annotate_dict_str_int(arg0: dict[str, int]) -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_annotations(doc):
|
||||||
|
assert doc(m.annotate_list_int) == "annotate_list_int(arg0: list[int]) -> None"
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_annotations(doc):
|
||||||
|
assert doc(m.annotate_set_str) == "annotate_set_str(arg0: set[str]) -> None"
|
||||||
|
|
||||||
|
|
||||||
|
def test_fn_annotations(doc):
|
||||||
|
assert (
|
||||||
|
doc(m.annotate_fn)
|
||||||
|
== "annotate_fn(arg0: Callable[[list[str], str], int]) -> None"
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user