mirror of
https://github.com/pybind/pybind11.git
synced 2025-02-22 16:39:29 +00:00
Merge branch 'master' into sh_merge_master
This commit is contained in:
commit
35b26794ec
40
.github/workflows/ci.yml
vendored
40
.github/workflows/ci.yml
vendored
@ -70,7 +70,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python ${{ matrix.python }}
|
- name: Setup Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -206,7 +206,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python ${{ matrix.python-version }} (deadsnakes)
|
- name: Setup Python ${{ matrix.python-version }} (deadsnakes)
|
||||||
uses: deadsnakes/action@v3.0.1
|
uses: deadsnakes/action@v3.0.1
|
||||||
@ -311,7 +311,7 @@ jobs:
|
|||||||
container: "silkeh/clang:${{ matrix.clang }}${{ matrix.container_suffix }}"
|
container: "silkeh/clang:${{ matrix.clang }}${{ matrix.container_suffix }}"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Add wget and python3
|
- name: Add wget and python3
|
||||||
run: apt-get update && apt-get install -y python3-dev python3-numpy python3-pytest libeigen3-dev
|
run: apt-get update && apt-get install -y python3-dev python3-numpy python3-pytest libeigen3-dev
|
||||||
@ -345,7 +345,7 @@ jobs:
|
|||||||
container: nvidia/cuda:12.2.0-devel-ubuntu22.04
|
container: nvidia/cuda:12.2.0-devel-ubuntu22.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
# tzdata will try to ask for the timezone, so set the DEBIAN_FRONTEND
|
# tzdata will try to ask for the timezone, so set the DEBIAN_FRONTEND
|
||||||
- name: Install 🐍 3
|
- name: Install 🐍 3
|
||||||
@ -369,7 +369,7 @@ jobs:
|
|||||||
# container: centos:8
|
# container: centos:8
|
||||||
#
|
#
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@v3
|
# - uses: actions/checkout@v4
|
||||||
#
|
#
|
||||||
# - name: Add Python 3 and a few requirements
|
# - name: Add Python 3 and a few requirements
|
||||||
# run: yum update -y && yum install -y git python3-devel python3-numpy python3-pytest make environment-modules
|
# run: yum update -y && yum install -y git python3-devel python3-numpy python3-pytest make environment-modules
|
||||||
@ -414,7 +414,7 @@ jobs:
|
|||||||
# tzdata will try to ask for the timezone, so set the DEBIAN_FRONTEND
|
# tzdata will try to ask for the timezone, so set the DEBIAN_FRONTEND
|
||||||
DEBIAN_FRONTEND: 'noninteractive'
|
DEBIAN_FRONTEND: 'noninteractive'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Add NVHPC Repo
|
- name: Add NVHPC Repo
|
||||||
run: |
|
run: |
|
||||||
@ -476,7 +476,7 @@ jobs:
|
|||||||
container: "gcc:${{ matrix.gcc }}"
|
container: "gcc:${{ matrix.gcc }}"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Add Python 3
|
- name: Add Python 3
|
||||||
run: apt-get update; apt-get install -y python3-dev python3-numpy python3-pytest python3-pip libeigen3-dev
|
run: apt-get update; apt-get install -y python3-dev python3-numpy python3-pytest python3-pip libeigen3-dev
|
||||||
@ -536,7 +536,7 @@ jobs:
|
|||||||
name: "🐍 3 • ICC latest • x64"
|
name: "🐍 3 • ICC latest • x64"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Add apt repo
|
- name: Add apt repo
|
||||||
run: |
|
run: |
|
||||||
@ -640,7 +640,13 @@ jobs:
|
|||||||
container: "${{ matrix.container }}"
|
container: "${{ matrix.container }}"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- name: Latest actions/checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
if: matrix.container != 'centos:7'
|
||||||
|
|
||||||
|
- name: Pin actions/checkout as required for centos:7
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
if: matrix.container == 'centos:7'
|
||||||
|
|
||||||
- name: Add Python 3 (RHEL 7)
|
- name: Add Python 3 (RHEL 7)
|
||||||
if: matrix.container == 'centos:7'
|
if: matrix.container == 'centos:7'
|
||||||
@ -688,7 +694,7 @@ jobs:
|
|||||||
container: i386/debian:buster
|
container: i386/debian:buster
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1 # Required to run inside docker
|
- uses: actions/checkout@v1 # v1 is required to run inside docker
|
||||||
|
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
run: |
|
run: |
|
||||||
@ -731,7 +737,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
@ -783,7 +789,7 @@ jobs:
|
|||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python ${{ matrix.python }}
|
- name: Setup Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -836,7 +842,7 @@ jobs:
|
|||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python ${{ matrix.python }}
|
- name: Setup Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -884,7 +890,7 @@ jobs:
|
|||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python ${{ matrix.python }}
|
- name: Setup Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -962,7 +968,7 @@ jobs:
|
|||||||
mingw-w64-${{matrix.env}}-boost
|
mingw-w64-${{matrix.env}}-boost
|
||||||
mingw-w64-${{matrix.env}}-catch
|
mingw-w64-${{matrix.env}}-catch
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Configure C++11
|
- name: Configure C++11
|
||||||
# LTO leads to many undefined reference like
|
# LTO leads to many undefined reference like
|
||||||
@ -1033,7 +1039,7 @@ jobs:
|
|||||||
run: env
|
run: env
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Clang
|
- name: Set up Clang
|
||||||
uses: egor-tensin/setup-clang@v1
|
uses: egor-tensin/setup-clang@v1
|
||||||
@ -1102,7 +1108,7 @@ jobs:
|
|||||||
run: env
|
run: env
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Show Clang++ version before brew install llvm
|
- name: Show Clang++ version before brew install llvm
|
||||||
run: clang++ --version
|
run: clang++ --version
|
||||||
|
2
.github/workflows/configure.yml
vendored
2
.github/workflows/configure.yml
vendored
@ -50,7 +50,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python 3.7
|
- name: Setup Python 3.7
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
4
.github/workflows/format.yml
vendored
4
.github/workflows/format.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
name: Format
|
name: Format
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@ -44,7 +44,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: silkeh/clang:15-bullseye
|
container: silkeh/clang:15-bullseye
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install requirements
|
- name: Install requirements
|
||||||
run: apt-get update && apt-get install -y git python3-dev python3-pytest
|
run: apt-get update && apt-get install -y git python3-dev python3-pytest
|
||||||
|
4
.github/workflows/pip.yml
vendored
4
.github/workflows/pip.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup 🐍 3.6
|
- name: Setup 🐍 3.6
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
@ -51,7 +51,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup 🐍 3.8
|
- name: Setup 🐍 3.8
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
2
.github/workflows/upstream.yml
vendored
2
.github/workflows/upstream.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
if: "contains(github.event.pull_request.labels.*.name, 'python dev')"
|
if: "contains(github.event.pull_request.labels.*.name, 'python dev')"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Python 3.12
|
- name: Setup Python 3.12
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
|
@ -31,21 +31,21 @@ repos:
|
|||||||
types_or: [c++, c, cuda]
|
types_or: [c++, c, cuda]
|
||||||
|
|
||||||
# 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-pre-commit-mirror
|
||||||
rev: "23.7.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.281
|
rev: v0.0.287
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: ["--fix", "--show-fixes"]
|
args: ["--fix", "--show-fixes"]
|
||||||
|
|
||||||
# Check static types with mypy
|
# Check static types with mypy
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: "v1.4.1"
|
rev: "v1.5.1"
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args: []
|
args: []
|
||||||
@ -85,7 +85,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.15.0"
|
rev: "1.16.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: blacken-docs
|
- id: blacken-docs
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
@ -93,7 +93,7 @@ repos:
|
|||||||
|
|
||||||
# Changes tabs to spaces
|
# Changes tabs to spaces
|
||||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||||
rev: "v1.5.1"
|
rev: "v1.5.4"
|
||||||
hooks:
|
hooks:
|
||||||
- id: remove-tabs
|
- id: remove-tabs
|
||||||
exclude: (^docs/.*|\.patch)?$
|
exclude: (^docs/.*|\.patch)?$
|
||||||
@ -149,7 +149,7 @@ repos:
|
|||||||
|
|
||||||
# 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.0a6"
|
rev: "v3.0.0a7"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pylint
|
- id: pylint
|
||||||
files: ^pybind11
|
files: ^pybind11
|
||||||
|
@ -1,3 +1,20 @@
|
|||||||
|
# https://blog.readthedocs.com/migrate-configuration-v2/
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
apt_packages:
|
||||||
|
- librsvg2-bin
|
||||||
|
tools:
|
||||||
|
python: "3.11"
|
||||||
|
|
||||||
|
sphinx:
|
||||||
|
configuration: docs/conf.py
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3
|
install:
|
||||||
requirements_file: docs/requirements.txt
|
- requirements: docs/requirements.txt
|
||||||
|
|
||||||
|
formats:
|
||||||
|
- pdf
|
||||||
|
@ -16,7 +16,7 @@ lifetime of objects managed by them. This can lead to issues when creating
|
|||||||
bindings for functions that return a non-trivial type. Just by looking at the
|
bindings for functions that return a non-trivial type. Just by looking at the
|
||||||
type information, it is not clear whether Python should take charge of the
|
type information, it is not clear whether Python should take charge of the
|
||||||
returned value and eventually free its resources, or if this is handled on the
|
returned value and eventually free its resources, or if this is handled on the
|
||||||
C++ side. For this reason, pybind11 provides a several *return value policy*
|
C++ side. For this reason, pybind11 provides several *return value policy*
|
||||||
annotations that can be passed to the :func:`module_::def` and
|
annotations that can be passed to the :func:`module_::def` and
|
||||||
:func:`class_::def` functions. The default policy is
|
:func:`class_::def` functions. The default policy is
|
||||||
:enum:`return_value_policy::automatic`.
|
:enum:`return_value_policy::automatic`.
|
||||||
|
@ -70,7 +70,7 @@ def generate_dummy_code_boost(nclasses=10):
|
|||||||
|
|
||||||
for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]:
|
for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]:
|
||||||
print("{")
|
print("{")
|
||||||
for i in range(0, 10):
|
for i in range(10):
|
||||||
nclasses = 2**i
|
nclasses = 2**i
|
||||||
with open("test.cpp", "w") as f:
|
with open("test.cpp", "w") as f:
|
||||||
f.write(codegen(nclasses))
|
f.write(codegen(nclasses))
|
||||||
|
@ -936,6 +936,10 @@ struct handle_type_name<float_> {
|
|||||||
static constexpr auto name = const_name("float");
|
static constexpr auto name = const_name("float");
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
|
struct handle_type_name<function> {
|
||||||
|
static constexpr auto name = const_name("Callable");
|
||||||
|
};
|
||||||
|
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");
|
||||||
};
|
};
|
||||||
|
@ -35,8 +35,9 @@
|
|||||||
/// further ABI-incompatible changes may be made before the ABI is officially
|
/// further ABI-incompatible changes may be made before the ABI is officially
|
||||||
/// changed to the new version.
|
/// changed to the new version.
|
||||||
#ifndef PYBIND11_INTERNALS_VERSION
|
#ifndef PYBIND11_INTERNALS_VERSION
|
||||||
# if PY_VERSION_HEX >= 0x030C0000
|
# if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
|
||||||
// Version bump for Python 3.12+, before first 3.12 beta release.
|
// Version bump for Python 3.12+, before first 3.12 beta release.
|
||||||
|
// Version bump for MSVC piggy-backed on PR #4779. See comments there.
|
||||||
# define PYBIND11_INTERNALS_VERSION 5
|
# define PYBIND11_INTERNALS_VERSION 5
|
||||||
# else
|
# else
|
||||||
# define PYBIND11_INTERNALS_VERSION 4
|
# define PYBIND11_INTERNALS_VERSION 4
|
||||||
@ -292,9 +293,12 @@ struct type_info {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
|
/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
|
||||||
|
/// On MSVC, changes in _MSC_VER may indicate ABI incompatibility (#2898).
|
||||||
#ifndef PYBIND11_BUILD_ABI
|
#ifndef PYBIND11_BUILD_ABI
|
||||||
# if defined(__GXX_ABI_VERSION)
|
# if defined(__GXX_ABI_VERSION)
|
||||||
# define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
|
# define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
|
||||||
|
# elif defined(_MSC_VER)
|
||||||
|
# define PYBIND11_BUILD_ABI "_mscver" PYBIND11_TOSTRING(_MSC_VER)
|
||||||
# else
|
# else
|
||||||
# define PYBIND11_BUILD_ABI ""
|
# define PYBIND11_BUILD_ABI ""
|
||||||
# endif
|
# endif
|
||||||
|
@ -53,6 +53,45 @@ PYBIND11_WARNING_DISABLE_MSVC(4127)
|
|||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
|
inline std::string replace_newlines_and_squash(const char *text) {
|
||||||
|
const char *whitespaces = " \t\n\r\f\v";
|
||||||
|
std::string result(text);
|
||||||
|
bool previous_is_whitespace = false;
|
||||||
|
|
||||||
|
// Do not modify string representations
|
||||||
|
char first_char = result[0];
|
||||||
|
char last_char = result[result.size() - 1];
|
||||||
|
if (first_char == last_char && first_char == '\'') {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
// Replace characters in whitespaces array with spaces and squash consecutive spaces
|
||||||
|
while (*text != '\0') {
|
||||||
|
if (std::strchr(whitespaces, *text)) {
|
||||||
|
if (!previous_is_whitespace) {
|
||||||
|
result += ' ';
|
||||||
|
previous_is_whitespace = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += *text;
|
||||||
|
previous_is_whitespace = false;
|
||||||
|
}
|
||||||
|
++text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip leading and trailing whitespaces
|
||||||
|
const size_t str_begin = result.find_first_not_of(whitespaces);
|
||||||
|
if (str_begin == std::string::npos) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t str_end = result.find_last_not_of(whitespaces);
|
||||||
|
const size_t str_range = str_end - str_begin + 1;
|
||||||
|
|
||||||
|
return result.substr(str_begin, str_range);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply all the extensions translators from a list
|
// Apply all the extensions translators from a list
|
||||||
// Return true if one of the translators completed without raising an exception
|
// Return true if one of the translators completed without raising an exception
|
||||||
// itself. Return of false indicates that if there are other translators
|
// itself. Return of false indicates that if there are other translators
|
||||||
@ -425,7 +464,7 @@ protected:
|
|||||||
// Write default value if available.
|
// Write default value if available.
|
||||||
if (!is_starred && arg_index < rec->args.size() && rec->args[arg_index].descr) {
|
if (!is_starred && arg_index < rec->args.size() && rec->args[arg_index].descr) {
|
||||||
signature += " = ";
|
signature += " = ";
|
||||||
signature += rec->args[arg_index].descr;
|
signature += detail::replace_newlines_and_squash(rec->args[arg_index].descr);
|
||||||
}
|
}
|
||||||
// Separator for positional-only arguments (placed after the
|
// Separator for positional-only arguments (placed after the
|
||||||
// argument, rather than before like *
|
// argument, rather than before like *
|
||||||
@ -681,7 +720,7 @@ protected:
|
|||||||
/* Iterator over the list of potentially admissible overloads */
|
/* Iterator over the list of potentially admissible overloads */
|
||||||
const function_record *overloads = reinterpret_cast<function_record *>(
|
const function_record *overloads = reinterpret_cast<function_record *>(
|
||||||
PyCapsule_GetPointer(self, get_function_record_capsule_name())),
|
PyCapsule_GetPointer(self, get_function_record_capsule_name())),
|
||||||
*it = overloads;
|
*current_overload = overloads;
|
||||||
assert(overloads != nullptr);
|
assert(overloads != nullptr);
|
||||||
|
|
||||||
/* Need to know how many arguments + keyword arguments there are to pick the right
|
/* Need to know how many arguments + keyword arguments there are to pick the right
|
||||||
@ -719,9 +758,10 @@ protected:
|
|||||||
std::vector<function_call> second_pass;
|
std::vector<function_call> second_pass;
|
||||||
|
|
||||||
// However, if there are no overloads, we can just skip the no-convert pass entirely
|
// However, if there are no overloads, we can just skip the no-convert pass entirely
|
||||||
const bool overloaded = it != nullptr && it->next != nullptr;
|
const bool overloaded
|
||||||
|
= current_overload != nullptr && current_overload->next != nullptr;
|
||||||
|
|
||||||
for (; it != nullptr; it = it->next) {
|
for (; current_overload != nullptr; current_overload = current_overload->next) {
|
||||||
|
|
||||||
/* For each overload:
|
/* For each overload:
|
||||||
1. Copy all positional arguments we were given, also checking to make sure that
|
1. Copy all positional arguments we were given, also checking to make sure that
|
||||||
@ -742,7 +782,7 @@ protected:
|
|||||||
a result other than PYBIND11_TRY_NEXT_OVERLOAD.
|
a result other than PYBIND11_TRY_NEXT_OVERLOAD.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const function_record &func = *it;
|
const function_record &func = *current_overload;
|
||||||
size_t num_args = func.nargs; // Number of positional arguments that we need
|
size_t num_args = func.nargs; // Number of positional arguments that we need
|
||||||
if (func.has_args) {
|
if (func.has_args) {
|
||||||
--num_args; // (but don't count py::args
|
--num_args; // (but don't count py::args
|
||||||
@ -980,10 +1020,10 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
|
if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {
|
||||||
// The error reporting logic below expects 'it' to be valid, as it would be
|
// The error reporting logic below expects 'current_overload' to be valid,
|
||||||
// if we'd encountered this failure in the first-pass loop.
|
// as it would be if we'd encountered this failure in the first-pass loop.
|
||||||
if (!result) {
|
if (!result) {
|
||||||
it = &call.func;
|
current_overload = &call.func;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1130,7 +1170,8 @@ protected:
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
std::string msg = "Unable to convert function return value to a "
|
std::string msg = "Unable to convert function return value to a "
|
||||||
"Python type! The signature was\n\t";
|
"Python type! The signature was\n\t";
|
||||||
msg += it->signature;
|
assert(current_overload != nullptr);
|
||||||
|
msg += current_overload->signature;
|
||||||
append_note_if_missing_header_is_suspected(msg);
|
append_note_if_missing_header_is_suspected(msg);
|
||||||
// Attach additional error info to the exception if supported
|
// Attach additional error info to the exception if supported
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
@ -2235,7 +2276,7 @@ struct enum_base {
|
|||||||
object type_name = type::handle_of(arg).attr("__name__");
|
object type_name = type::handle_of(arg).attr("__name__");
|
||||||
return pybind11::str("{}.{}").format(std::move(type_name), enum_name(arg));
|
return pybind11::str("{}.{}").format(std::move(type_name), enum_name(arg));
|
||||||
},
|
},
|
||||||
name("name"),
|
name("__str__"),
|
||||||
is_method(m_base));
|
is_method(m_base));
|
||||||
|
|
||||||
if (options::show_enum_members_docstring()) {
|
if (options::show_enum_members_docstring()) {
|
||||||
@ -2653,7 +2694,7 @@ iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
|
|||||||
Policy);
|
Policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cast(state{first, last, true});
|
return cast(state{std::forward<Iterator>(first), std::forward<Sentinel>(last), true});
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
@ -2670,7 +2711,9 @@ iterator make_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|||||||
Iterator,
|
Iterator,
|
||||||
Sentinel,
|
Sentinel,
|
||||||
ValueType,
|
ValueType,
|
||||||
Extra...>(first, last, std::forward<Extra>(extra)...);
|
Extra...>(std::forward<Iterator>(first),
|
||||||
|
std::forward<Sentinel>(last),
|
||||||
|
std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
|
/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
|
||||||
@ -2686,7 +2729,9 @@ iterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|||||||
Iterator,
|
Iterator,
|
||||||
Sentinel,
|
Sentinel,
|
||||||
KeyType,
|
KeyType,
|
||||||
Extra...>(first, last, std::forward<Extra>(extra)...);
|
Extra...>(std::forward<Iterator>(first),
|
||||||
|
std::forward<Sentinel>(last),
|
||||||
|
std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
|
/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
|
||||||
@ -2702,7 +2747,9 @@ iterator make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {
|
|||||||
Iterator,
|
Iterator,
|
||||||
Sentinel,
|
Sentinel,
|
||||||
ValueType,
|
ValueType,
|
||||||
Extra...>(first, last, std::forward<Extra>(extra)...);
|
Extra...>(std::forward<Iterator>(first),
|
||||||
|
std::forward<Sentinel>(last),
|
||||||
|
std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes an iterator over values of an stl container or other container supporting
|
/// Makes an iterator over values of an stl container or other container supporting
|
||||||
|
@ -94,5 +94,5 @@ line-length = 120
|
|||||||
isort.known-first-party = ["env", "pybind11_cross_module_tests", "pybind11_tests"]
|
isort.known-first-party = ["env", "pybind11_cross_module_tests", "pybind11_tests"]
|
||||||
|
|
||||||
[tool.ruff.per-file-ignores]
|
[tool.ruff.per-file-ignores]
|
||||||
"tests/**" = ["EM", "N"]
|
"tests/**" = ["EM", "N", "E721"]
|
||||||
"tests/test_call_policies.py" = ["PLC1901"]
|
"tests/test_call_policies.py" = ["PLC1901"]
|
||||||
|
@ -216,3 +216,10 @@ def test_custom_func():
|
|||||||
def test_custom_func2():
|
def test_custom_func2():
|
||||||
assert m.custom_function2(3) == 27
|
assert m.custom_function2(3) == 27
|
||||||
assert m.roundtrip(m.custom_function2)(3) == 27
|
assert m.roundtrip(m.custom_function2)(3) == 27
|
||||||
|
|
||||||
|
|
||||||
|
def test_callback_docstring():
|
||||||
|
assert (
|
||||||
|
m.test_tuple_unpacking.__doc__.strip()
|
||||||
|
== "test_tuple_unpacking(arg0: Callable) -> object"
|
||||||
|
)
|
||||||
|
@ -330,6 +330,23 @@ TEST_SUBMODULE(eigen_matrix, m) {
|
|||||||
m.def("dense_c", [mat]() -> DenseMatrixC { return DenseMatrixC(mat); });
|
m.def("dense_c", [mat]() -> DenseMatrixC { return DenseMatrixC(mat); });
|
||||||
m.def("dense_copy_r", [](const DenseMatrixR &m) -> DenseMatrixR { return m; });
|
m.def("dense_copy_r", [](const DenseMatrixR &m) -> DenseMatrixR { return m; });
|
||||||
m.def("dense_copy_c", [](const DenseMatrixC &m) -> DenseMatrixC { return m; });
|
m.def("dense_copy_c", [](const DenseMatrixC &m) -> DenseMatrixC { return m; });
|
||||||
|
// test_defaults
|
||||||
|
bool have_numpy = true;
|
||||||
|
try {
|
||||||
|
py::module_::import("numpy");
|
||||||
|
} catch (const py::error_already_set &) {
|
||||||
|
have_numpy = false;
|
||||||
|
}
|
||||||
|
if (have_numpy) {
|
||||||
|
py::module_::import("numpy");
|
||||||
|
Eigen::Matrix<double, 3, 3> defaultMatrix = Eigen::Matrix3d::Identity();
|
||||||
|
m.def(
|
||||||
|
"defaults_mat", [](const Eigen::Matrix3d &) {}, py::arg("mat") = defaultMatrix);
|
||||||
|
|
||||||
|
Eigen::VectorXd defaultVector = Eigen::VectorXd::Ones(32);
|
||||||
|
m.def(
|
||||||
|
"defaults_vec", [](const Eigen::VectorXd &) {}, py::arg("vec") = defaultMatrix);
|
||||||
|
}
|
||||||
// test_sparse, test_sparse_signature
|
// test_sparse, test_sparse_signature
|
||||||
m.def("sparse_r", [mat]() -> SparseMatrixR {
|
m.def("sparse_r", [mat]() -> SparseMatrixR {
|
||||||
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
|
// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
|
||||||
|
@ -716,6 +716,11 @@ def test_dense_signature(doc):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_defaults(doc):
|
||||||
|
assert "\n" not in str(doc(m.defaults_mat))
|
||||||
|
assert "\n" not in str(doc(m.defaults_vec))
|
||||||
|
|
||||||
|
|
||||||
def test_named_arguments():
|
def test_named_arguments():
|
||||||
a = np.array([[1.0, 2], [3, 4], [5, 6]])
|
a = np.array([[1.0, 2], [3, 4], [5, 6]])
|
||||||
b = np.ones((2, 1))
|
b = np.ones((2, 1))
|
||||||
|
@ -264,3 +264,8 @@ def test_docstring_signatures():
|
|||||||
for attr in enum_type.__dict__.values():
|
for attr in enum_type.__dict__.values():
|
||||||
# Issue #2623/PR #2637: Add argument names to enum_ methods
|
# Issue #2623/PR #2637: Add argument names to enum_ methods
|
||||||
assert "arg0" not in (attr.__doc__ or "")
|
assert "arg0" not in (attr.__doc__ or "")
|
||||||
|
|
||||||
|
|
||||||
|
def test_str_signature():
|
||||||
|
for enum_type in [m.ScopedEnum, m.UnscopedEnum]:
|
||||||
|
assert enum_type.__str__.__doc__.startswith("__str__")
|
||||||
|
@ -42,6 +42,50 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
|
|||||||
m.def("kw_func_udl", kw_func, "x"_a, "y"_a = 300);
|
m.def("kw_func_udl", kw_func, "x"_a, "y"_a = 300);
|
||||||
m.def("kw_func_udl_z", kw_func, "x"_a, "y"_a = 0);
|
m.def("kw_func_udl_z", kw_func, "x"_a, "y"_a = 0);
|
||||||
|
|
||||||
|
// test line breaks in default argument representation
|
||||||
|
struct CustomRepr {
|
||||||
|
std::string repr_string;
|
||||||
|
|
||||||
|
explicit CustomRepr(const std::string &repr) : repr_string(repr) {}
|
||||||
|
|
||||||
|
std::string __repr__() const { return repr_string; }
|
||||||
|
};
|
||||||
|
|
||||||
|
py::class_<CustomRepr>(m, "CustomRepr")
|
||||||
|
.def(py::init<const std::string &>())
|
||||||
|
.def("__repr__", &CustomRepr::__repr__);
|
||||||
|
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func0",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr(" array([[A, B], [C, D]]) "));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func1",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr(" array([[A, B],\n[C, D]]) "));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func2",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr("\v\n array([[A, B], [C, D]])"));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func3",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr("array([[A, B], [C, D]]) \f\n"));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func4",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr("array([[A, B],\n\f\n[C, D]])"));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func5",
|
||||||
|
[](const CustomRepr &) {},
|
||||||
|
py::arg("custom") = CustomRepr("array([[A, B],\r [C, D]])"));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func6", [](const CustomRepr &) {}, py::arg("custom") = CustomRepr(" \v\t "));
|
||||||
|
m.def(
|
||||||
|
"kw_lb_func7",
|
||||||
|
[](const std::string &) {},
|
||||||
|
py::arg("str_arg") = "First line.\n Second line.");
|
||||||
|
|
||||||
// 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 {
|
||||||
PYBIND11_WARNING_PUSH
|
PYBIND11_WARNING_PUSH
|
||||||
|
@ -23,6 +23,38 @@ def test_function_signatures(doc):
|
|||||||
doc(m.KWClass.foo1)
|
doc(m.KWClass.foo1)
|
||||||
== "foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None"
|
== "foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None"
|
||||||
)
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func0)
|
||||||
|
== "kw_lb_func0(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func1)
|
||||||
|
== "kw_lb_func1(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func2)
|
||||||
|
== "kw_lb_func2(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func3)
|
||||||
|
== "kw_lb_func3(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func4)
|
||||||
|
== "kw_lb_func4(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func5)
|
||||||
|
== "kw_lb_func5(custom: m.kwargs_and_defaults.CustomRepr = array([[A, B], [C, D]])) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func6)
|
||||||
|
== "kw_lb_func6(custom: m.kwargs_and_defaults.CustomRepr = ) -> None"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
doc(m.kw_lb_func7)
|
||||||
|
== "kw_lb_func7(str_arg: str = 'First line.\\n Second line.') -> None"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_named_arguments():
|
def test_named_arguments():
|
||||||
|
@ -28,6 +28,13 @@ class NonZeroIterator {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NonZeroIterator(const T *ptr) : ptr_(ptr) {}
|
explicit NonZeroIterator(const T *ptr) : ptr_(ptr) {}
|
||||||
|
|
||||||
|
// Make the iterator non-copyable and movable
|
||||||
|
NonZeroIterator(const NonZeroIterator &) = delete;
|
||||||
|
NonZeroIterator(NonZeroIterator &&) noexcept = default;
|
||||||
|
NonZeroIterator &operator=(const NonZeroIterator &) = delete;
|
||||||
|
NonZeroIterator &operator=(NonZeroIterator &&) noexcept = default;
|
||||||
|
|
||||||
const T &operator*() const { return *ptr_; }
|
const T &operator*() const { return *ptr_; }
|
||||||
NonZeroIterator &operator++() {
|
NonZeroIterator &operator++() {
|
||||||
++ptr_;
|
++ptr_;
|
||||||
@ -78,6 +85,7 @@ private:
|
|||||||
int value_;
|
int value_;
|
||||||
};
|
};
|
||||||
using NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;
|
using NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;
|
||||||
|
|
||||||
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);
|
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);
|
||||||
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);
|
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);
|
||||||
|
|
||||||
@ -375,6 +383,17 @@ TEST_SUBMODULE(sequences_and_iterators, m) {
|
|||||||
private:
|
private:
|
||||||
std::vector<std::pair<int, int>> data_;
|
std::vector<std::pair<int, int>> data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
// #4383 : Make sure `py::make_*iterator` functions work with move-only iterators
|
||||||
|
using iterator_t = NonZeroIterator<std::pair<int, int>>;
|
||||||
|
|
||||||
|
static_assert(std::is_move_assignable<iterator_t>::value, "");
|
||||||
|
static_assert(std::is_move_constructible<iterator_t>::value, "");
|
||||||
|
static_assert(!std::is_copy_assignable<iterator_t>::value, "");
|
||||||
|
static_assert(!std::is_copy_constructible<iterator_t>::value, "");
|
||||||
|
}
|
||||||
|
|
||||||
py::class_<IntPairs>(m, "IntPairs")
|
py::class_<IntPairs>(m, "IntPairs")
|
||||||
.def(py::init<std::vector<std::pair<int, int>>>())
|
.def(py::init<std::vector<std::pair<int, int>>>())
|
||||||
.def(
|
.def(
|
||||||
|
@ -209,7 +209,7 @@ def test_map_string_double_const():
|
|||||||
def test_noncopyable_containers():
|
def test_noncopyable_containers():
|
||||||
# std::vector
|
# std::vector
|
||||||
vnc = m.get_vnc(5)
|
vnc = m.get_vnc(5)
|
||||||
for i in range(0, 5):
|
for i in range(5):
|
||||||
assert vnc[i].value == i + 1
|
assert vnc[i].value == i + 1
|
||||||
|
|
||||||
for i, j in enumerate(vnc, start=1):
|
for i, j in enumerate(vnc, start=1):
|
||||||
@ -217,7 +217,7 @@ def test_noncopyable_containers():
|
|||||||
|
|
||||||
# std::deque
|
# std::deque
|
||||||
dnc = m.get_dnc(5)
|
dnc = m.get_dnc(5)
|
||||||
for i in range(0, 5):
|
for i in range(5):
|
||||||
assert dnc[i].value == i + 1
|
assert dnc[i].value == i + 1
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
@ -252,7 +252,7 @@ def test_noncopyable_containers():
|
|||||||
# nested std::map<std::vector>
|
# nested std::map<std::vector>
|
||||||
nvnc = m.get_nvnc(5)
|
nvnc = m.get_nvnc(5)
|
||||||
for i in range(1, 6):
|
for i in range(1, 6):
|
||||||
for j in range(0, 5):
|
for j in range(5):
|
||||||
assert nvnc[i][j].value == j + 1
|
assert nvnc[i][j].value == j + 1
|
||||||
|
|
||||||
# Note: maps do not have .values()
|
# Note: maps do not have .values()
|
||||||
|
Loading…
Reference in New Issue
Block a user