mirror of
https://github.com/pybind/pybind11.git
synced 2024-12-01 17:37:15 +00:00
t pushMerge branch 'master' of https://github.com/pybind/pybind11 into lazy-error-string
This commit is contained in:
commit
98aff18132
@ -25,11 +25,12 @@ modernize-replace-random-shuffle,
|
|||||||
modernize-shrink-to-fit,
|
modernize-shrink-to-fit,
|
||||||
modernize-use-auto,
|
modernize-use-auto,
|
||||||
modernize-use-bool-literals,
|
modernize-use-bool-literals,
|
||||||
|
modernize-use-default-member-init,
|
||||||
modernize-use-equals-default,
|
modernize-use-equals-default,
|
||||||
modernize-use-equals-delete,
|
modernize-use-equals-delete,
|
||||||
modernize-use-default-member-init,
|
|
||||||
modernize-use-noexcept,
|
|
||||||
modernize-use-emplace,
|
modernize-use-emplace,
|
||||||
|
modernize-use-noexcept,
|
||||||
|
modernize-use-nullptr,
|
||||||
modernize-use-override,
|
modernize-use-override,
|
||||||
modernize-use-using,
|
modernize-use-using,
|
||||||
*performance*,
|
*performance*,
|
||||||
|
50
.github/workflows/ci.yml
vendored
50
.github/workflows/ci.yml
vendored
@ -32,6 +32,7 @@ jobs:
|
|||||||
- '3.10'
|
- '3.10'
|
||||||
- 'pypy-3.7'
|
- 'pypy-3.7'
|
||||||
- 'pypy-3.8'
|
- 'pypy-3.8'
|
||||||
|
- 'pypy-3.9'
|
||||||
|
|
||||||
# Items in here will either be added to the build matrix (if not
|
# Items in here will either be added to the build matrix (if not
|
||||||
# present), or add new keys to an existing matrix element if all the
|
# present), or add new keys to an existing matrix element if all the
|
||||||
@ -45,6 +46,10 @@ jobs:
|
|||||||
args: >
|
args: >
|
||||||
-DPYBIND11_FINDPYTHON=ON
|
-DPYBIND11_FINDPYTHON=ON
|
||||||
-DCMAKE_CXX_FLAGS="-D_=1"
|
-DCMAKE_CXX_FLAGS="-D_=1"
|
||||||
|
- runs-on: ubuntu-latest
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
args: >
|
||||||
|
-DPYBIND11_FINDPYTHON=ON
|
||||||
- runs-on: windows-2019
|
- runs-on: windows-2019
|
||||||
python: '3.6'
|
python: '3.6'
|
||||||
args: >
|
args: >
|
||||||
@ -668,7 +673,7 @@ jobs:
|
|||||||
|
|
||||||
|
|
||||||
# This verifies that the documentation is not horribly broken, and does a
|
# This verifies that the documentation is not horribly broken, and does a
|
||||||
# basic sanity check on the SDist.
|
# basic validation check on the SDist.
|
||||||
doxygen:
|
doxygen:
|
||||||
name: "Documentation build test"
|
name: "Documentation build test"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -756,55 +761,60 @@ jobs:
|
|||||||
- name: Python tests
|
- name: Python tests
|
||||||
run: cmake --build build -t pytest
|
run: cmake --build build -t pytest
|
||||||
|
|
||||||
win32-msvc2017:
|
win32-debug:
|
||||||
name: "🐍 ${{ matrix.python }} • MSVC 2017 • x64"
|
|
||||||
runs-on: windows-2016
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
python:
|
python:
|
||||||
- 3.6
|
- 3.8
|
||||||
- 3.7
|
- 3.9
|
||||||
std:
|
|
||||||
- 14
|
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- python: 3.7
|
- python: 3.9
|
||||||
std: 17
|
args: -DCMAKE_CXX_STANDARD=20
|
||||||
args: >
|
- python: 3.8
|
||||||
-DCMAKE_CXX_FLAGS="/permissive- /EHsc /GR"
|
args: -DCMAKE_CXX_STANDARD=17
|
||||||
|
|
||||||
|
name: "🐍 ${{ matrix.python }} • MSVC 2019 (Debug) • x86 ${{ matrix.args }}"
|
||||||
|
runs-on: windows-2019
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Setup 🐍 ${{ matrix.python }}
|
- name: Setup Python ${{ matrix.python }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python }}
|
python-version: ${{ matrix.python }}
|
||||||
|
architecture: x86
|
||||||
|
|
||||||
- name: Update CMake
|
- name: Update CMake
|
||||||
uses: jwlawson/actions-setup-cmake@v1.12
|
uses: jwlawson/actions-setup-cmake@v1.12
|
||||||
|
|
||||||
|
- name: Prepare MSVC
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1.10.0
|
||||||
|
with:
|
||||||
|
arch: x86
|
||||||
|
|
||||||
- name: Prepare env
|
- name: Prepare env
|
||||||
run: |
|
run: |
|
||||||
python -m pip install -r tests/requirements.txt
|
python -m pip install -r tests/requirements.txt
|
||||||
|
|
||||||
# First build - C++11 mode and inplace
|
# First build - C++11 mode and inplace
|
||||||
- name: Configure
|
- name: Configure ${{ matrix.args }}
|
||||||
run: >
|
run: >
|
||||||
cmake -S . -B build
|
cmake -S . -B build
|
||||||
-G "Visual Studio 15 2017" -A x64
|
-G "Visual Studio 16 2019" -A Win32
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug
|
||||||
-DPYBIND11_WERROR=ON
|
-DPYBIND11_WERROR=ON
|
||||||
-DDOWNLOAD_CATCH=ON
|
-DDOWNLOAD_CATCH=ON
|
||||||
-DDOWNLOAD_EIGEN=ON
|
-DDOWNLOAD_EIGEN=ON
|
||||||
-DCMAKE_CXX_STANDARD=${{ matrix.std }}
|
|
||||||
${{ matrix.args }}
|
${{ matrix.args }}
|
||||||
|
- name: Build C++11
|
||||||
|
run: cmake --build build --config Debug -j 2
|
||||||
|
|
||||||
- name: Build ${{ matrix.std }}
|
- name: Python tests
|
||||||
run: cmake --build build -j 2
|
run: cmake --build build --config Debug -t pytest
|
||||||
|
|
||||||
- name: Run all checks
|
|
||||||
run: cmake --build build -t check
|
|
||||||
|
|
||||||
windows-2022:
|
windows-2022:
|
||||||
strategy:
|
strategy:
|
||||||
|
10
.github/workflows/configure.yml
vendored
10
.github/workflows/configure.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
runs-on: [ubuntu-latest, macos-latest, windows-latest]
|
runs-on: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
arch: [x64]
|
arch: [x64]
|
||||||
cmake: ["3.21"]
|
cmake: ["3.23"]
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- runs-on: ubuntu-latest
|
- runs-on: ubuntu-latest
|
||||||
@ -29,12 +29,8 @@ jobs:
|
|||||||
arch: x64
|
arch: x64
|
||||||
cmake: 3.7
|
cmake: 3.7
|
||||||
|
|
||||||
- runs-on: windows-2016
|
- runs-on: windows-2019
|
||||||
arch: x86
|
arch: x64 # x86 compilers seem to be missing on 2019 image
|
||||||
cmake: 3.8
|
|
||||||
|
|
||||||
- runs-on: windows-2016
|
|
||||||
arch: x86
|
|
||||||
cmake: 3.18
|
cmake: 3.18
|
||||||
|
|
||||||
name: 🐍 3.7 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }}
|
name: 🐍 3.7 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
repos:
|
repos:
|
||||||
# Standard hooks
|
# Standard hooks
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: "v4.1.0"
|
rev: "v4.2.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-added-large-files
|
- id: check-added-large-files
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
@ -32,7 +32,7 @@ repos:
|
|||||||
|
|
||||||
# Upgrade old Python syntax
|
# Upgrade old Python syntax
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: "v2.31.0"
|
rev: "v2.32.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py36-plus]
|
args: [--py36-plus]
|
||||||
@ -45,7 +45,7 @@ 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: "22.1.0" # Keep in sync with blacken-docs
|
rev: "22.3.0" # Keep in sync with blacken-docs
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: blacken-docs
|
- id: blacken-docs
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- black==22.1.0 # keep in sync with black hook
|
- black==22.3.0 # keep in sync with black hook
|
||||||
|
|
||||||
# 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
|
||||||
@ -64,16 +64,17 @@ repos:
|
|||||||
- id: remove-tabs
|
- id: remove-tabs
|
||||||
|
|
||||||
- repo: https://github.com/sirosen/texthooks
|
- repo: https://github.com/sirosen/texthooks
|
||||||
rev: "0.2.2"
|
rev: "0.3.1"
|
||||||
hooks:
|
hooks:
|
||||||
- id: fix-ligatures
|
- id: fix-ligatures
|
||||||
- id: fix-smartquotes
|
- id: fix-smartquotes
|
||||||
|
|
||||||
# Autoremoves unused imports
|
# Autoremoves unused imports
|
||||||
- repo: https://github.com/hadialqattan/pycln
|
- repo: https://github.com/hadialqattan/pycln
|
||||||
rev: "v1.2.4"
|
rev: "v1.3.1"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pycln
|
- id: pycln
|
||||||
|
stages: [manual]
|
||||||
|
|
||||||
# Checking for common mistakes
|
# Checking for common mistakes
|
||||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||||
@ -106,7 +107,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: "v2.12.2"
|
rev: "v2.13.5"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pylint
|
- id: pylint
|
||||||
files: ^pybind11
|
files: ^pybind11
|
||||||
@ -122,16 +123,16 @@ repos:
|
|||||||
|
|
||||||
# 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: "v0.931"
|
rev: "v0.942"
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
args: [--show-error-codes]
|
args: []
|
||||||
exclude: ^(tests|docs)/
|
exclude: ^(tests|docs)/
|
||||||
additional_dependencies: [nox, rich]
|
additional_dependencies: [nox, rich]
|
||||||
|
|
||||||
# Checks the manifest for missing files (native support)
|
# Checks the manifest for missing files (native support)
|
||||||
- repo: https://github.com/mgedmin/check-manifest
|
- repo: https://github.com/mgedmin/check-manifest
|
||||||
rev: "0.47"
|
rev: "0.48"
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-manifest
|
- id: check-manifest
|
||||||
# This is a slow hook, so only run this if --hook-stage manual is passed
|
# This is a slow hook, so only run this if --hook-stage manual is passed
|
||||||
@ -163,7 +164,7 @@ repos:
|
|||||||
|
|
||||||
# Clang format the codebase automatically
|
# Clang format the codebase automatically
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: "v13.0.1"
|
rev: "v14.0.1"
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
types_or: [c++, c, cuda]
|
types_or: [c++, c, cuda]
|
||||||
|
@ -87,7 +87,7 @@ buffer objects (e.g. a NumPy matrix).
|
|||||||
/* Request a buffer descriptor from Python */
|
/* Request a buffer descriptor from Python */
|
||||||
py::buffer_info info = b.request();
|
py::buffer_info info = b.request();
|
||||||
|
|
||||||
/* Some sanity checks ... */
|
/* Some basic validation checks ... */
|
||||||
if (info.format != py::format_descriptor<Scalar>::format())
|
if (info.format != py::format_descriptor<Scalar>::format())
|
||||||
throw std::runtime_error("Incompatible format: expected a double array!");
|
throw std::runtime_error("Incompatible format: expected a double array!");
|
||||||
|
|
||||||
|
@ -6,10 +6,129 @@ Changelog
|
|||||||
Starting with version 1.8.0, pybind11 releases use a `semantic versioning
|
Starting with version 1.8.0, pybind11 releases use a `semantic versioning
|
||||||
<http://semver.org>`_ policy.
|
<http://semver.org>`_ policy.
|
||||||
|
|
||||||
|
Changes will be added here periodically from the "Suggested changelog entry"
|
||||||
|
block in pull request descriptions.
|
||||||
|
|
||||||
IN DEVELOPMENT
|
IN DEVELOPMENT
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Changes will be added here periodically.
|
Removed support for Python 2.7, Python 3.5, and MSVC 2015. Support for MSVC
|
||||||
|
2017 is limited due to availability of CI runners; we highly recommend MSVC
|
||||||
|
2019 or 2022 be used.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* ``type_caster<std::monostate>`` was added. ``std::monostate`` is a tag type
|
||||||
|
that allows ``std::variant`` to act as an optional, or allows default
|
||||||
|
construction of a ``std::variant`` holding a non-default constructible type.
|
||||||
|
`#3818 <https://github.com/pybind/pybind11/pull/3818>`_
|
||||||
|
|
||||||
|
* Support bytearray casting to string.
|
||||||
|
`#3707 <https://github.com/pybind/pybind11/pull/3707>`_
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
* Python 2 support was removed completely.
|
||||||
|
`#3688 <https://github.com/pybind/pybind11/pull/3688>`_
|
||||||
|
|
||||||
|
* The minimum version for MSVC is now 2017.
|
||||||
|
`#3722 <https://github.com/pybind/pybind11/pull/3722>`_
|
||||||
|
|
||||||
|
* Improve exception handling in python ``str`` bindings.
|
||||||
|
`#3826 <https://github.com/pybind/pybind11/pull/3826>`_
|
||||||
|
|
||||||
|
* The bindings for capsules now have more consistent exception handling.
|
||||||
|
`#3825 <https://github.com/pybind/pybind11/pull/3825>`_
|
||||||
|
|
||||||
|
* Fix exception handling when ``pybind11::weakref()`` fails.
|
||||||
|
`#3739 <https://github.com/pybind/pybind11/pull/3739>`_
|
||||||
|
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* ``PYBIND11_OBJECT_CVT`` and ``PYBIND11_OBJECT_CVT_DEFAULT`` macro can be used
|
||||||
|
to define classes in namespaces other than pybind11.
|
||||||
|
`#3797 <https://github.com/pybind/pybind11/pull/3797>`_
|
||||||
|
|
||||||
|
Build system improvements:
|
||||||
|
|
||||||
|
* Add MSVC builds in debug mode to CI.
|
||||||
|
`#3784 <https://github.com/pybind/pybind11/pull/3784>`_
|
||||||
|
|
||||||
|
* MSVC 2022 C++20 coverage was added to GitHub Actions, including Eigen.
|
||||||
|
`#3732 <https://github.com/pybind/pybind11/pull/3732>`_,
|
||||||
|
`#3741 <https://github.com/pybind/pybind11/pull/3741>`_
|
||||||
|
|
||||||
|
* Avoid ``setup.py <command>`` usage in internal tests.
|
||||||
|
`#3734 <https://github.com/pybind/pybind11/pull/3734>`_
|
||||||
|
|
||||||
|
|
||||||
|
Backend and tidying up:
|
||||||
|
|
||||||
|
* Remove idioms in code comments. Use inclusive language.
|
||||||
|
`#3809 <https://github.com/pybind/pybind11/pull/3809>`_
|
||||||
|
|
||||||
|
|
||||||
|
Version 2.9.2 (Mar 29, 2022)
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
* Enum now has an ``__index__`` method on Python <3.8 too.
|
||||||
|
`#3700 <https://github.com/pybind/pybind11/pull/3700>`_
|
||||||
|
|
||||||
|
* Local internals are now cleared after finalizing the interpreter.
|
||||||
|
`#3744 <https://github.com/pybind/pybind11/pull/3744>`_
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Better support for Python 3.11 alphas.
|
||||||
|
`#3694 <https://github.com/pybind/pybind11/pull/3694>`_
|
||||||
|
|
||||||
|
* ``PYBIND11_TYPE_CASTER`` now uses fully qualified symbols, so it can be used
|
||||||
|
outside of ``pybind11::detail``.
|
||||||
|
`#3758 <https://github.com/pybind/pybind11/pull/3758>`_
|
||||||
|
|
||||||
|
* Some fixes for PyPy 3.9.
|
||||||
|
`#3768 <https://github.com/pybind/pybind11/pull/3768>`_
|
||||||
|
|
||||||
|
* Fixed a potential memleak in PyPy in ``get_type_override``.
|
||||||
|
`#3774 <https://github.com/pybind/pybind11/pull/3774>`_
|
||||||
|
|
||||||
|
* Fix usage of ``VISIBILITY_INLINES_HIDDEN``.
|
||||||
|
`#3721 <https://github.com/pybind/pybind11/pull/3721>`_
|
||||||
|
|
||||||
|
|
||||||
|
Build system improvements:
|
||||||
|
|
||||||
|
* Uses ``sysconfig`` module to determine installation locations on Python >=
|
||||||
|
3.10, instead of ``distutils`` which has been deprecated.
|
||||||
|
`#3764 <https://github.com/pybind/pybind11/pull/3764>`_
|
||||||
|
|
||||||
|
* Support Catch 2.13.5+ (supporting GLIBC 2.34+).
|
||||||
|
`#3679 <https://github.com/pybind/pybind11/pull/3679>`_
|
||||||
|
|
||||||
|
* Fix test failures with numpy 1.22 by ignoring whitespace when comparing
|
||||||
|
``str()`` of dtypes.
|
||||||
|
`#3682 <https://github.com/pybind/pybind11/pull/3682>`_
|
||||||
|
|
||||||
|
|
||||||
|
Backend and tidying up:
|
||||||
|
|
||||||
|
* clang-tidy: added ``readability-qualified-auto``,
|
||||||
|
``readability-braces-around-statements``,
|
||||||
|
``cppcoreguidelines-prefer-member-initializer``,
|
||||||
|
``clang-analyzer-optin.performance.Padding``,
|
||||||
|
``cppcoreguidelines-pro-type-static-cast-downcast``, and
|
||||||
|
``readability-inconsistent-declaration-parameter-name``.
|
||||||
|
`#3702 <https://github.com/pybind/pybind11/pull/3702>`_,
|
||||||
|
`#3699 <https://github.com/pybind/pybind11/pull/3699>`_,
|
||||||
|
`#3716 <https://github.com/pybind/pybind11/pull/3716>`_,
|
||||||
|
`#3709 <https://github.com/pybind/pybind11/pull/3709>`_
|
||||||
|
|
||||||
|
* clang-format was added to the pre-commit actions, and the entire code base
|
||||||
|
automatically reformatted (after several iterations preparing for this leap).
|
||||||
|
`#3713 <https://github.com/pybind/pybind11/pull/3713>`_
|
||||||
|
|
||||||
|
|
||||||
Version 2.9.1 (Feb 2, 2022)
|
Version 2.9.1 (Feb 2, 2022)
|
||||||
|
@ -505,7 +505,10 @@ You can use these targets to build complex applications. For example, the
|
|||||||
target_link_libraries(example PRIVATE pybind11::module pybind11::lto pybind11::windows_extras)
|
target_link_libraries(example PRIVATE pybind11::module pybind11::lto pybind11::windows_extras)
|
||||||
|
|
||||||
pybind11_extension(example)
|
pybind11_extension(example)
|
||||||
pybind11_strip(example)
|
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||||
|
# Strip unnecessary sections of the binary on Linux/macOS
|
||||||
|
pybind11_strip(example)
|
||||||
|
endif()
|
||||||
|
|
||||||
set_target_properties(example PROPERTIES CXX_VISIBILITY_PRESET "hidden"
|
set_target_properties(example PROPERTIES CXX_VISIBILITY_PRESET "hidden"
|
||||||
CUDA_VISIBILITY_PRESET "hidden")
|
CUDA_VISIBILITY_PRESET "hidden")
|
||||||
|
@ -514,7 +514,7 @@ struct type_caster<std::basic_string_view<CharT, Traits>,
|
|||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
|
struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
|
||||||
using StringType = std::basic_string<CharT>;
|
using StringType = std::basic_string<CharT>;
|
||||||
using StringCaster = type_caster<StringType>;
|
using StringCaster = make_caster<StringType>;
|
||||||
StringCaster str_caster;
|
StringCaster str_caster;
|
||||||
bool none = false;
|
bool none = false;
|
||||||
CharT one_char = 0;
|
CharT one_char = 0;
|
||||||
@ -1155,15 +1155,18 @@ enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,
|
|||||||
// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
|
// static_assert, even though if it's in dead code, so we provide a "trampoline" to pybind11::cast
|
||||||
// that only does anything in cases where pybind11::cast is valid.
|
// that only does anything in cases where pybind11::cast is valid.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&o) {
|
|
||||||
return pybind11::cast<T>(std::move(o));
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&) {
|
enable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&) {
|
||||||
pybind11_fail("Internal error: cast_safe fallback invoked");
|
pybind11_fail("Internal error: cast_safe fallback invoked");
|
||||||
}
|
}
|
||||||
template <>
|
template <typename T>
|
||||||
inline void cast_safe<void>(object &&) {}
|
enable_if_t<std::is_same<void, intrinsic_t<T>>::value, void> cast_safe(object &&) {}
|
||||||
|
template <typename T>
|
||||||
|
enable_if_t<detail::none_of<cast_is_temporary_value_reference<T>,
|
||||||
|
std::is_same<void, intrinsic_t<T>>>::value,
|
||||||
|
T>
|
||||||
|
cast_safe(object &&o) {
|
||||||
|
return pybind11::cast<T>(std::move(o));
|
||||||
|
}
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
|
||||||
@ -1243,8 +1246,8 @@ struct arg_v : arg {
|
|||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
arg_v(arg &&base, T &&x, const char *descr = nullptr)
|
arg_v(arg &&base, T &&x, const char *descr = nullptr)
|
||||||
: arg(base), value(reinterpret_steal<object>(
|
: arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
|
||||||
detail::make_caster<T>::cast(x, return_value_policy::automatic, {}))),
|
std::forward<T>(x), return_value_policy::automatic, {}))),
|
||||||
descr(descr)
|
descr(descr)
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
,
|
,
|
||||||
@ -1491,7 +1494,7 @@ private:
|
|||||||
type_id<T>());
|
type_id<T>());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
args_list.append(o);
|
args_list.append(std::move(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
void process(list &args_list, detail::args_proxy ap) {
|
void process(list &args_list, detail::args_proxy ap) {
|
||||||
|
@ -992,6 +992,8 @@ constexpr const char
|
|||||||
struct error_scope {
|
struct error_scope {
|
||||||
PyObject *type, *value, *trace;
|
PyObject *type, *value, *trace;
|
||||||
error_scope() { PyErr_Fetch(&type, &value, &trace); }
|
error_scope() { PyErr_Fetch(&type, &value, &trace); }
|
||||||
|
error_scope(const error_scope &) = delete;
|
||||||
|
error_scope &operator=(const error_scope &) = delete;
|
||||||
~error_scope() { PyErr_Restore(type, value, trace); }
|
~error_scope() { PyErr_Restore(type, value, trace); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,8 +225,8 @@ PYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp,
|
|||||||
if (throw_if_missing) {
|
if (throw_if_missing) {
|
||||||
std::string tname = tp.name();
|
std::string tname = tp.name();
|
||||||
detail::clean_type_id(tname);
|
detail::clean_type_id(tname);
|
||||||
pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \"" + tname
|
pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \""
|
||||||
+ "\"");
|
+ std::move(tname) + '"');
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -668,7 +668,7 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
|
|||||||
Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
|
Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
|
||||||
StorageIndex>(shape[0].cast<Index>(),
|
StorageIndex>(shape[0].cast<Index>(),
|
||||||
shape[1].cast<Index>(),
|
shape[1].cast<Index>(),
|
||||||
nnz,
|
std::move(nnz),
|
||||||
outerIndices.mutable_data(),
|
outerIndices.mutable_data(),
|
||||||
innerIndices.mutable_data(),
|
innerIndices.mutable_data(),
|
||||||
values.mutable_data());
|
values.mutable_data());
|
||||||
@ -686,7 +686,8 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
|
|||||||
array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
|
array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());
|
||||||
array innerIndices(src.nonZeros(), src.innerIndexPtr());
|
array innerIndices(src.nonZeros(), src.innerIndexPtr());
|
||||||
|
|
||||||
return matrix_type(std::make_tuple(data, innerIndices, outerIndices),
|
return matrix_type(std::make_tuple(
|
||||||
|
std::move(data), std::move(innerIndices), std::move(outerIndices)),
|
||||||
std::make_pair(src.rows(), src.cols()))
|
std::make_pair(src.rows(), src.cols()))
|
||||||
.release();
|
.release();
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ template <eval_mode mode = eval_expr, size_t N>
|
|||||||
object eval(const char (&s)[N], object global = globals(), object local = object()) {
|
object eval(const char (&s)[N], object global = globals(), object local = object()) {
|
||||||
/* Support raw string literals by removing common leading whitespace */
|
/* Support raw string literals by removing common leading whitespace */
|
||||||
auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
|
auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
|
||||||
return eval<mode>(expr, global, local);
|
return eval<mode>(expr, std::move(global), std::move(local));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void exec(const str &expr, object global = globals(), object local = object()) {
|
inline void exec(const str &expr, object global = globals(), object local = object()) {
|
||||||
@ -91,7 +91,7 @@ inline void exec(const str &expr, object global = globals(), object local = obje
|
|||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
void exec(const char (&s)[N], object global = globals(), object local = object()) {
|
void exec(const char (&s)[N], object global = globals(), object local = object()) {
|
||||||
eval<eval_statements>(s, global, local);
|
eval<eval_statements>(s, std::move(global), std::move(local));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PYPY_VERSION)
|
#if defined(PYPY_VERSION)
|
||||||
|
@ -263,7 +263,7 @@ private:
|
|||||||
static npy_api lookup() {
|
static npy_api lookup() {
|
||||||
module_ m = module_::import("numpy.core.multiarray");
|
module_ m = module_::import("numpy.core.multiarray");
|
||||||
auto c = m.attr("_ARRAY_API");
|
auto c = m.attr("_ARRAY_API");
|
||||||
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
|
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);
|
||||||
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);
|
||||||
@ -540,18 +540,18 @@ public:
|
|||||||
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
|
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
|
||||||
|
|
||||||
explicit dtype(const buffer_info &info) {
|
explicit dtype(const buffer_info &info) {
|
||||||
dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format)));
|
dtype descr(_dtype_from_pep3118()(pybind11::str(info.format)));
|
||||||
// If info.itemsize == 0, use the value calculated from the format string
|
// If info.itemsize == 0, use the value calculated from the format string
|
||||||
m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())
|
m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())
|
||||||
.release()
|
.release()
|
||||||
.ptr();
|
.ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit dtype(const std::string &format) {
|
explicit dtype(const pybind11::str &format) : dtype(from_args(format)) {}
|
||||||
m_ptr = from_args(pybind11::str(format)).release().ptr();
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit dtype(const char *format) : dtype(std::string(format)) {}
|
explicit dtype(const std::string &format) : dtype(pybind11::str(format)) {}
|
||||||
|
|
||||||
|
explicit dtype(const char *format) : dtype(pybind11::str(format)) {}
|
||||||
|
|
||||||
dtype(list names, list formats, list offsets, ssize_t itemsize) {
|
dtype(list names, list formats, list offsets, ssize_t itemsize) {
|
||||||
dict args;
|
dict args;
|
||||||
@ -559,11 +559,18 @@ public:
|
|||||||
args["formats"] = std::move(formats);
|
args["formats"] = std::move(formats);
|
||||||
args["offsets"] = std::move(offsets);
|
args["offsets"] = std::move(offsets);
|
||||||
args["itemsize"] = pybind11::int_(itemsize);
|
args["itemsize"] = pybind11::int_(itemsize);
|
||||||
m_ptr = from_args(std::move(args)).release().ptr();
|
m_ptr = from_args(args).release().ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit dtype(int typenum)
|
||||||
|
: object(detail::npy_api::get().PyArray_DescrFromType_(typenum), stolen_t{}) {
|
||||||
|
if (m_ptr == nullptr) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is essentially the same as calling numpy.dtype(args) in Python.
|
/// This is essentially the same as calling numpy.dtype(args) in Python.
|
||||||
static dtype from_args(object args) {
|
static dtype from_args(const object &args) {
|
||||||
PyObject *ptr = nullptr;
|
PyObject *ptr = nullptr;
|
||||||
if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {
|
if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
@ -596,6 +603,23 @@ public:
|
|||||||
return detail::array_descriptor_proxy(m_ptr)->type;
|
return detail::array_descriptor_proxy(m_ptr)->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// type number of dtype.
|
||||||
|
ssize_t num() const {
|
||||||
|
// Note: The signature, `dtype::num` follows the naming of NumPy's public
|
||||||
|
// Python API (i.e., ``dtype.num``), rather than its internal
|
||||||
|
// C API (``PyArray_Descr::type_num``).
|
||||||
|
return detail::array_descriptor_proxy(m_ptr)->type_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Single character for byteorder
|
||||||
|
char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; }
|
||||||
|
|
||||||
|
/// Alignment of the data type
|
||||||
|
int alignment() const { return detail::array_descriptor_proxy(m_ptr)->alignment; }
|
||||||
|
|
||||||
|
/// Flags for the array descriptor
|
||||||
|
char flags() const { return detail::array_descriptor_proxy(m_ptr)->flags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static object _dtype_from_pep3118() {
|
static object _dtype_from_pep3118() {
|
||||||
static PyObject *obj = module_::import("numpy.core._internal")
|
static PyObject *obj = module_::import("numpy.core._internal")
|
||||||
@ -614,7 +638,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct field_descr {
|
struct field_descr {
|
||||||
PYBIND11_STR_TYPE name;
|
pybind11::str name;
|
||||||
object format;
|
object format;
|
||||||
pybind11::int_ offset;
|
pybind11::int_ offset;
|
||||||
};
|
};
|
||||||
@ -629,7 +653,7 @@ private:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
field_descriptors.push_back(
|
field_descriptors.push_back(
|
||||||
{(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset});
|
{(pybind11::str) name, format.strip_padding(format.itemsize()), offset});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(field_descriptors.begin(),
|
std::sort(field_descriptors.begin(),
|
||||||
@ -640,9 +664,9 @@ private:
|
|||||||
|
|
||||||
list names, formats, offsets;
|
list names, formats, offsets;
|
||||||
for (auto &descr : field_descriptors) {
|
for (auto &descr : field_descriptors) {
|
||||||
names.append(descr.name);
|
names.append(std::move(descr.name));
|
||||||
formats.append(descr.format);
|
formats.append(std::move(descr.format));
|
||||||
offsets.append(descr.offset);
|
offsets.append(std::move(descr.offset));
|
||||||
}
|
}
|
||||||
return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);
|
return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);
|
||||||
}
|
}
|
||||||
@ -940,7 +964,7 @@ protected:
|
|||||||
|
|
||||||
void fail_dim_check(ssize_t dim, const std::string &msg) const {
|
void fail_dim_check(ssize_t dim, const std::string &msg) const {
|
||||||
throw index_error(msg + ": " + std::to_string(dim) + " (ndim = " + std::to_string(ndim())
|
throw index_error(msg + ": " + std::to_string(dim) + " (ndim = " + std::to_string(ndim())
|
||||||
+ ")");
|
+ ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ix>
|
template <typename... Ix>
|
||||||
@ -1144,11 +1168,11 @@ struct format_descriptor<T, detail::enable_if_t<detail::is_pod_struct<T>::value>
|
|||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
struct format_descriptor<char[N]> {
|
struct format_descriptor<char[N]> {
|
||||||
static std::string format() { return std::to_string(N) + "s"; }
|
static std::string format() { return std::to_string(N) + 's'; }
|
||||||
};
|
};
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
struct format_descriptor<std::array<char, N>> {
|
struct format_descriptor<std::array<char, N>> {
|
||||||
static std::string format() { return std::to_string(N) + "s"; }
|
static std::string format() { return std::to_string(N) + 's'; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1288,7 +1312,8 @@ public:
|
|||||||
static pybind11::dtype dtype() {
|
static pybind11::dtype dtype() {
|
||||||
list shape;
|
list shape;
|
||||||
array_info<T>::append_extents(shape);
|
array_info<T>::append_extents(shape);
|
||||||
return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape));
|
return pybind11::dtype::from_args(
|
||||||
|
pybind11::make_tuple(base_descr::dtype(), std::move(shape)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1334,7 +1359,7 @@ PYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor>
|
|||||||
pybind11_fail(std::string("NumPy: unsupported field dtype: `") + field.name + "` @ "
|
pybind11_fail(std::string("NumPy: unsupported field dtype: `") + field.name + "` @ "
|
||||||
+ tinfo.name());
|
+ tinfo.name());
|
||||||
}
|
}
|
||||||
names.append(PYBIND11_STR_TYPE(field.name));
|
names.append(pybind11::str(field.name));
|
||||||
formats.append(field.descr);
|
formats.append(field.descr);
|
||||||
offsets.append(pybind11::int_(field.offset));
|
offsets.append(pybind11::int_(field.offset));
|
||||||
}
|
}
|
||||||
@ -1526,7 +1551,7 @@ public:
|
|||||||
void *data() const { return p_ptr; }
|
void *data() const { return p_ptr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *p_ptr{0};
|
char *p_ptr{nullptr};
|
||||||
container_type m_strides;
|
container_type m_strides;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -561,14 +561,14 @@ protected:
|
|||||||
for (auto *it = chain_start; it != nullptr; it = it->next) {
|
for (auto *it = chain_start; it != nullptr; it = it->next) {
|
||||||
if (options::show_function_signatures()) {
|
if (options::show_function_signatures()) {
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
signatures += "\n";
|
signatures += '\n';
|
||||||
}
|
}
|
||||||
if (chain) {
|
if (chain) {
|
||||||
signatures += std::to_string(++index) + ". ";
|
signatures += std::to_string(++index) + ". ";
|
||||||
}
|
}
|
||||||
signatures += rec->name;
|
signatures += rec->name;
|
||||||
signatures += it->signature;
|
signatures += it->signature;
|
||||||
signatures += "\n";
|
signatures += '\n';
|
||||||
}
|
}
|
||||||
if (it->doc && it->doc[0] != '\0' && options::show_user_defined_docstrings()) {
|
if (it->doc && it->doc[0] != '\0' && options::show_user_defined_docstrings()) {
|
||||||
// If we're appending another docstring, and aren't printing function signatures,
|
// If we're appending another docstring, and aren't printing function signatures,
|
||||||
@ -577,15 +577,15 @@ protected:
|
|||||||
if (first_user_def) {
|
if (first_user_def) {
|
||||||
first_user_def = false;
|
first_user_def = false;
|
||||||
} else {
|
} else {
|
||||||
signatures += "\n";
|
signatures += '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options::show_function_signatures()) {
|
if (options::show_function_signatures()) {
|
||||||
signatures += "\n";
|
signatures += '\n';
|
||||||
}
|
}
|
||||||
signatures += it->doc;
|
signatures += it->doc;
|
||||||
if (options::show_function_signatures()) {
|
if (options::show_function_signatures()) {
|
||||||
signatures += "\n";
|
signatures += '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1055,7 +1055,7 @@ protected:
|
|||||||
msg += it2->signature;
|
msg += it2->signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg += "\n";
|
msg += '\n';
|
||||||
}
|
}
|
||||||
msg += "\nInvoked with: ";
|
msg += "\nInvoked with: ";
|
||||||
auto args_ = reinterpret_borrow<tuple>(args_in);
|
auto args_ = reinterpret_borrow<tuple>(args_in);
|
||||||
@ -1817,7 +1817,8 @@ private:
|
|||||||
if (holder_ptr) {
|
if (holder_ptr) {
|
||||||
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
} else if (inst->owned || detail::always_construct_holder<holder_type>::value) {
|
} else if (PYBIND11_SILENCE_MSVC_C4127(detail::always_construct_holder<holder_type>::value)
|
||||||
|
|| inst->owned) {
|
||||||
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
|
||||||
v_h.set_holder_constructed();
|
v_h.set_holder_constructed();
|
||||||
}
|
}
|
||||||
@ -2402,7 +2403,8 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
|
|||||||
typename Type,
|
typename Type,
|
||||||
typename... Extra>
|
typename... Extra>
|
||||||
iterator make_iterator(Type &value, Extra &&...extra) {
|
iterator make_iterator(Type &value, Extra &&...extra) {
|
||||||
return make_iterator<Policy>(std::begin(value), std::end(value), extra...);
|
return make_iterator<Policy>(
|
||||||
|
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting
|
/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting
|
||||||
@ -2411,7 +2413,8 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
|
|||||||
typename Type,
|
typename Type,
|
||||||
typename... Extra>
|
typename... Extra>
|
||||||
iterator make_key_iterator(Type &value, Extra &&...extra) {
|
iterator make_key_iterator(Type &value, Extra &&...extra) {
|
||||||
return make_key_iterator<Policy>(std::begin(value), std::end(value), extra...);
|
return make_key_iterator<Policy>(
|
||||||
|
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes an iterator over the values (`.second`) of a stl map-like container supporting
|
/// Makes an iterator over the values (`.second`) of a stl map-like container supporting
|
||||||
@ -2420,7 +2423,8 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
|
|||||||
typename Type,
|
typename Type,
|
||||||
typename... Extra>
|
typename... Extra>
|
||||||
iterator make_value_iterator(Type &value, Extra &&...extra) {
|
iterator make_value_iterator(Type &value, Extra &&...extra) {
|
||||||
return make_value_iterator<Policy>(std::begin(value), std::end(value), extra...);
|
return make_value_iterator<Policy>(
|
||||||
|
std::begin(value), std::end(value), std::forward<Extra>(extra)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputType, typename OutputType>
|
template <typename InputType, typename OutputType>
|
||||||
@ -2485,7 +2489,7 @@ public:
|
|||||||
exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
||||||
std::string full_name
|
std::string full_name
|
||||||
= scope.attr("__name__").cast<std::string>() + std::string(".") + name;
|
= scope.attr("__name__").cast<std::string>() + std::string(".") + name;
|
||||||
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), NULL);
|
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), nullptr);
|
||||||
if (hasattr(scope, "__dict__") && scope.attr("__dict__").contains(name)) {
|
if (hasattr(scope, "__dict__") && scope.attr("__dict__").contains(name)) {
|
||||||
pybind11_fail("Error during initialization: multiple incompatible "
|
pybind11_fail("Error during initialization: multiple incompatible "
|
||||||
"definitions with name \""
|
"definitions with name \""
|
||||||
@ -2694,9 +2698,9 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char *
|
|||||||
d.ptr());
|
d.ptr());
|
||||||
if (result == nullptr)
|
if (result == nullptr)
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
|
Py_DECREF(result);
|
||||||
if (d["self"].is_none())
|
if (d["self"].is_none())
|
||||||
return function();
|
return function();
|
||||||
Py_DECREF(result);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return override;
|
return override;
|
||||||
|
@ -270,10 +270,7 @@ public:
|
|||||||
/// Copy constructor; always increases the reference count
|
/// Copy constructor; always increases the reference count
|
||||||
object(const object &o) : handle(o) { inc_ref(); }
|
object(const object &o) : handle(o) { inc_ref(); }
|
||||||
/// Move constructor; steals the object from ``other`` and preserves its reference count
|
/// Move constructor; steals the object from ``other`` and preserves its reference count
|
||||||
object(object &&other) noexcept {
|
object(object &&other) noexcept : handle(other) { other.m_ptr = nullptr; }
|
||||||
m_ptr = other.m_ptr;
|
|
||||||
other.m_ptr = nullptr;
|
|
||||||
}
|
|
||||||
/// Destructor; automatically calls `handle::dec_ref()`
|
/// Destructor; automatically calls `handle::dec_ref()`
|
||||||
~object() { dec_ref(); }
|
~object() { dec_ref(); }
|
||||||
|
|
||||||
@ -636,13 +633,13 @@ inline handle get_function(handle value) {
|
|||||||
inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
|
inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
|
||||||
PyObject *kv = nullptr, *rv = nullptr;
|
PyObject *kv = nullptr, *rv = nullptr;
|
||||||
kv = PyUnicode_FromString(key);
|
kv = PyUnicode_FromString(key);
|
||||||
if (kv == NULL) {
|
if (kv == nullptr) {
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = PyDict_GetItemWithError(v, kv);
|
rv = PyDict_GetItemWithError(v, kv);
|
||||||
Py_DECREF(kv);
|
Py_DECREF(kv);
|
||||||
if (rv == NULL && PyErr_Occurred()) {
|
if (rv == nullptr && PyErr_Occurred()) {
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
@ -650,7 +647,7 @@ inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
|
|||||||
|
|
||||||
inline PyObject *dict_getitem(PyObject *v, PyObject *key) {
|
inline PyObject *dict_getitem(PyObject *v, PyObject *key) {
|
||||||
PyObject *rv = PyDict_GetItemWithError(v, key);
|
PyObject *rv = PyDict_GetItemWithError(v, key);
|
||||||
if (rv == NULL && PyErr_Occurred()) {
|
if (rv == nullptr && PyErr_Occurred()) {
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
@ -1071,12 +1068,12 @@ public:
|
|||||||
Name(const object &o) \
|
Name(const object &o) \
|
||||||
: Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
|
: Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
|
||||||
if (!m_ptr) \
|
if (!m_ptr) \
|
||||||
throw error_already_set(); \
|
throw ::pybind11::error_already_set(); \
|
||||||
} \
|
} \
|
||||||
/* NOLINTNEXTLINE(google-explicit-constructor) */ \
|
/* NOLINTNEXTLINE(google-explicit-constructor) */ \
|
||||||
Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
|
Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
|
||||||
if (!m_ptr) \
|
if (!m_ptr) \
|
||||||
throw error_already_set(); \
|
throw ::pybind11::error_already_set(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun) \
|
#define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun) \
|
||||||
@ -1276,8 +1273,8 @@ public:
|
|||||||
}
|
}
|
||||||
char *buffer = nullptr;
|
char *buffer = nullptr;
|
||||||
ssize_t length = 0;
|
ssize_t length = 0;
|
||||||
if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) {
|
if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {
|
||||||
pybind11_fail("Unable to extract string contents! (invalid type)");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return std::string(buffer, (size_t) length);
|
return std::string(buffer, (size_t) length);
|
||||||
}
|
}
|
||||||
@ -1332,14 +1329,7 @@ public:
|
|||||||
explicit bytes(const pybind11::str &s);
|
explicit bytes(const pybind11::str &s);
|
||||||
|
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
operator std::string() const {
|
operator std::string() const { return string_op<std::string>(); }
|
||||||
char *buffer = nullptr;
|
|
||||||
ssize_t length = 0;
|
|
||||||
if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) {
|
|
||||||
pybind11_fail("Unable to extract bytes contents!");
|
|
||||||
}
|
|
||||||
return std::string(buffer, (size_t) length);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PYBIND11_HAS_STRING_VIEW
|
#ifdef PYBIND11_HAS_STRING_VIEW
|
||||||
// enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521).
|
// enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521).
|
||||||
@ -1351,15 +1341,18 @@ public:
|
|||||||
// valid so long as the `bytes` instance remains alive and so generally should not outlive the
|
// valid so long as the `bytes` instance remains alive and so generally should not outlive the
|
||||||
// lifetime of the `bytes` instance.
|
// lifetime of the `bytes` instance.
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
operator std::string_view() const {
|
operator std::string_view() const { return string_op<std::string_view>(); }
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
T string_op() const {
|
||||||
char *buffer = nullptr;
|
char *buffer = nullptr;
|
||||||
ssize_t length = 0;
|
ssize_t length = 0;
|
||||||
if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) {
|
if (PyBytes_AsStringAndSize(m_ptr, &buffer, &length) != 0) {
|
||||||
pybind11_fail("Unable to extract bytes contents!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
return {buffer, static_cast<size_t>(length)};
|
return {buffer, static_cast<size_t>(length)};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors
|
// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors
|
||||||
// are included in the doxygen group; close here and reopen after as a workaround
|
// are included in the doxygen group; close here and reopen after as a workaround
|
||||||
@ -1370,13 +1363,13 @@ inline bytes::bytes(const pybind11::str &s) {
|
|||||||
if (PyUnicode_Check(s.ptr())) {
|
if (PyUnicode_Check(s.ptr())) {
|
||||||
temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(s.ptr()));
|
temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(s.ptr()));
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
pybind11_fail("Unable to extract string contents! (encoding issue)");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char *buffer = nullptr;
|
char *buffer = nullptr;
|
||||||
ssize_t length = 0;
|
ssize_t length = 0;
|
||||||
if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) {
|
if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {
|
||||||
pybind11_fail("Unable to extract string contents! (invalid type)");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
auto obj = reinterpret_steal<object>(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length));
|
auto obj = reinterpret_steal<object>(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
@ -1388,8 +1381,8 @@ inline bytes::bytes(const pybind11::str &s) {
|
|||||||
inline str::str(const bytes &b) {
|
inline str::str(const bytes &b) {
|
||||||
char *buffer = nullptr;
|
char *buffer = nullptr;
|
||||||
ssize_t length = 0;
|
ssize_t length = 0;
|
||||||
if (PYBIND11_BYTES_AS_STRING_AND_SIZE(b.ptr(), &buffer, &length)) {
|
if (PyBytes_AsStringAndSize(b.ptr(), &buffer, &length) != 0) {
|
||||||
pybind11_fail("Unable to extract bytes contents!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
auto obj = reinterpret_steal<object>(PyUnicode_FromStringAndSize(buffer, length));
|
auto obj = reinterpret_steal<object>(PyUnicode_FromStringAndSize(buffer, length));
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
@ -1556,8 +1549,8 @@ private:
|
|||||||
class slice : public object {
|
class slice : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check)
|
PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check)
|
||||||
slice(handle start, handle stop, handle step) {
|
slice(handle start, handle stop, handle step)
|
||||||
m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr());
|
: object(PySlice_New(start.ptr(), stop.ptr(), step.ptr()), stolen_t{}) {
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate slice object!");
|
pybind11_fail("Could not allocate slice object!");
|
||||||
}
|
}
|
||||||
@ -1607,7 +1600,7 @@ public:
|
|||||||
void (*destructor)(PyObject *) = nullptr)
|
void (*destructor)(PyObject *) = nullptr)
|
||||||
: object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
|
: object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1615,34 +1608,44 @@ public:
|
|||||||
capsule(const void *value, void (*destruct)(PyObject *))
|
capsule(const void *value, void (*destruct)(PyObject *))
|
||||||
: object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {
|
: object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
capsule(const void *value, void (*destructor)(void *)) {
|
capsule(const void *value, void (*destructor)(void *)) {
|
||||||
m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
|
m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
|
||||||
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
|
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
|
||||||
void *ptr = PyCapsule_GetPointer(o, nullptr);
|
if (destructor == nullptr) {
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
|
pybind11_fail("Unable to get capsule context");
|
||||||
|
}
|
||||||
|
const char *name = get_name_in_error_scope(o);
|
||||||
|
void *ptr = PyCapsule_GetPointer(o, name);
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
destructor(ptr);
|
destructor(ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_ptr) {
|
if (!m_ptr || PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
|
||||||
|
|
||||||
if (PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {
|
|
||||||
pybind11_fail("Could not set capsule context!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit capsule(void (*destructor)()) {
|
explicit capsule(void (*destructor)()) {
|
||||||
m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
|
m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
|
||||||
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, nullptr));
|
const char *name = get_name_in_error_scope(o);
|
||||||
|
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, name));
|
||||||
|
if (destructor == nullptr) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
destructor();
|
destructor();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1657,8 +1660,7 @@ public:
|
|||||||
const auto *name = this->name();
|
const auto *name = this->name();
|
||||||
T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
|
T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
PyErr_Clear();
|
throw error_already_set();
|
||||||
pybind11_fail("Unable to extract capsule contents!");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1666,12 +1668,37 @@ public:
|
|||||||
/// Replaces a capsule's pointer *without* calling the destructor on the existing one.
|
/// Replaces a capsule's pointer *without* calling the destructor on the existing one.
|
||||||
void set_pointer(const void *value) {
|
void set_pointer(const void *value) {
|
||||||
if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {
|
if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {
|
||||||
PyErr_Clear();
|
throw error_already_set();
|
||||||
pybind11_fail("Could not set capsule pointer");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *name() const { return PyCapsule_GetName(m_ptr); }
|
const char *name() const {
|
||||||
|
const char *name = PyCapsule_GetName(m_ptr);
|
||||||
|
if ((name == nullptr) && PyErr_Occurred()) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replaces a capsule's name *without* calling the destructor on the existing one.
|
||||||
|
void set_name(const char *new_name) {
|
||||||
|
if (PyCapsule_SetName(m_ptr, new_name) != 0) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char *get_name_in_error_scope(PyObject *o) {
|
||||||
|
error_scope error_guard;
|
||||||
|
|
||||||
|
const char *name = PyCapsule_GetName(o);
|
||||||
|
if ((name == nullptr) && PyErr_Occurred()) {
|
||||||
|
// write out and consume error raised by call to PyCapsule_GetName
|
||||||
|
PyErr_WriteUnraisable(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class tuple : public object {
|
class tuple : public object {
|
||||||
@ -1920,8 +1947,8 @@ public:
|
|||||||
return memoryview::from_buffer(reinterpret_cast<void *>(ptr),
|
return memoryview::from_buffer(reinterpret_cast<void *>(ptr),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
format_descriptor<T>::value,
|
format_descriptor<T>::value,
|
||||||
shape,
|
std::move(shape),
|
||||||
strides,
|
std::move(strides),
|
||||||
readonly);
|
readonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1929,7 +1956,8 @@ public:
|
|||||||
static memoryview from_buffer(const T *ptr,
|
static memoryview from_buffer(const T *ptr,
|
||||||
detail::any_container<ssize_t> shape,
|
detail::any_container<ssize_t> shape,
|
||||||
detail::any_container<ssize_t> strides) {
|
detail::any_container<ssize_t> strides) {
|
||||||
return memoryview::from_buffer(const_cast<T *>(ptr), shape, strides, true);
|
return memoryview::from_buffer(
|
||||||
|
const_cast<T *>(ptr), std::move(shape), std::move(strides), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
|
@ -79,7 +79,7 @@ struct set_caster {
|
|||||||
for (auto &&value : src) {
|
for (auto &&value : src) {
|
||||||
auto value_ = reinterpret_steal<object>(
|
auto value_ = reinterpret_steal<object>(
|
||||||
key_conv::cast(forward_like<T>(value), policy, parent));
|
key_conv::cast(forward_like<T>(value), policy, parent));
|
||||||
if (!value_ || !s.add(value_)) {
|
if (!value_ || !s.add(std::move(value_))) {
|
||||||
return handle();
|
return handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,7 +372,7 @@ struct variant_caster<V<Ts...>> {
|
|||||||
bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
|
bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
|
||||||
auto caster = make_caster<U>();
|
auto caster = make_caster<U>();
|
||||||
if (caster.load(src, convert)) {
|
if (caster.load(src, convert)) {
|
||||||
value = cast_op<U>(caster);
|
value = cast_op<U>(std::move(caster));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return load_alternative(src, convert, type_list<Us...>{});
|
return load_alternative(src, convert, type_list<Us...>{});
|
||||||
@ -406,6 +406,9 @@ struct variant_caster<V<Ts...>> {
|
|||||||
#if defined(PYBIND11_HAS_VARIANT)
|
#if defined(PYBIND11_HAS_VARIANT)
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
|
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct type_caster<std::monostate> : public void_caster<std::monostate> {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
@ -13,21 +13,28 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef __has_include
|
#ifdef __has_include
|
||||||
# if defined(PYBIND11_CPP17) && __has_include(<filesystem>)
|
# if defined(PYBIND11_CPP17)
|
||||||
# include <filesystem>
|
# if __has_include(<filesystem>) && \
|
||||||
# define PYBIND11_HAS_FILESYSTEM 1
|
PY_VERSION_HEX >= 0x03060000
|
||||||
|
# include <filesystem>
|
||||||
|
# define PYBIND11_HAS_FILESYSTEM 1
|
||||||
|
# elif __has_include(<experimental/filesystem>)
|
||||||
|
# include <experimental/filesystem>
|
||||||
|
# define PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM 1
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)
|
#if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM) \
|
||||||
|
&& !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)
|
||||||
# error \
|
# error \
|
||||||
"#include <filesystem> is not available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)"
|
"Neither #include <filesystem> nor #include <experimental/filesystem is available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
#if defined(PYBIND11_HAS_FILESYSTEM)
|
#if defined(PYBIND11_HAS_FILESYSTEM) || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct path_caster {
|
struct path_caster {
|
||||||
|
|
||||||
@ -94,9 +101,16 @@ public:
|
|||||||
PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
|
PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||||
|
|
||||||
|
#if defined(PYBIND11_HAS_FILESYSTEM)
|
||||||
template <>
|
template <>
|
||||||
struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
|
struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
|
||||||
#endif // PYBIND11_HAS_FILESYSTEM
|
#elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
|
||||||
|
template <>
|
||||||
|
struct type_caster<std::experimental::filesystem::path>
|
||||||
|
: public path_caster<std::experimental::filesystem::path> {};
|
||||||
|
#endif
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
@ -232,7 +232,7 @@ void vector_modifiers(
|
|||||||
/// Slicing protocol
|
/// Slicing protocol
|
||||||
cl.def(
|
cl.def(
|
||||||
"__getitem__",
|
"__getitem__",
|
||||||
[](const Vector &v, slice slice) -> Vector * {
|
[](const Vector &v, const slice &slice) -> Vector * {
|
||||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||||
|
|
||||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||||
@ -253,7 +253,7 @@ void vector_modifiers(
|
|||||||
|
|
||||||
cl.def(
|
cl.def(
|
||||||
"__setitem__",
|
"__setitem__",
|
||||||
[](Vector &v, slice slice, const Vector &value) {
|
[](Vector &v, const slice &slice, const Vector &value) {
|
||||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
@ -281,7 +281,7 @@ void vector_modifiers(
|
|||||||
|
|
||||||
cl.def(
|
cl.def(
|
||||||
"__delitem__",
|
"__delitem__",
|
||||||
[](Vector &v, slice slice) {
|
[](Vector &v, const slice &slice) {
|
||||||
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
size_t start = 0, stop = 0, step = 0, slicelength = 0;
|
||||||
|
|
||||||
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
|
||||||
|
@ -24,8 +24,10 @@ profile = "black"
|
|||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
files = ["pybind11"]
|
files = ["pybind11"]
|
||||||
python_version = "3.6"
|
python_version = "3.6"
|
||||||
warn_unused_configs = true
|
|
||||||
strict = true
|
strict = true
|
||||||
|
show_error_codes = true
|
||||||
|
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = ["ghapi.*", "setuptools.*"]
|
module = ["ghapi.*", "setuptools.*"]
|
||||||
|
@ -25,8 +25,8 @@ void gil_acquire() { py::gil_scoped_acquire gil; }
|
|||||||
|
|
||||||
constexpr char kModuleName[] = "cross_module_gil_utils";
|
constexpr char kModuleName[] = "cross_module_gil_utils";
|
||||||
|
|
||||||
struct PyModuleDef moduledef
|
struct PyModuleDef moduledef = {
|
||||||
= {PyModuleDef_HEAD_INIT, kModuleName, NULL, 0, NULL, NULL, NULL, NULL, NULL};
|
PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ extern "C" PYBIND11_EXPORT PyObject *PyInit_cross_module_gil_utils() {
|
|||||||
|
|
||||||
PyObject *m = PyModule_Create(&moduledef);
|
PyObject *m = PyModule_Create(&moduledef);
|
||||||
|
|
||||||
if (m != NULL) {
|
if (m != nullptr) {
|
||||||
static_assert(sizeof(&gil_acquire) == sizeof(void *),
|
static_assert(sizeof(&gil_acquire) == sizeof(void *),
|
||||||
"Function pointer must have the same size as void*");
|
"Function pointer must have the same size as void*");
|
||||||
PyModule_AddObject(
|
PyModule_AddObject(
|
||||||
|
@ -289,8 +289,9 @@ py::list test_dtype_ctors() {
|
|||||||
dict["itemsize"] = py::int_(20);
|
dict["itemsize"] = py::int_(20);
|
||||||
list.append(py::dtype::from_args(dict));
|
list.append(py::dtype::from_args(dict));
|
||||||
list.append(py::dtype(names, formats, offsets, 20));
|
list.append(py::dtype(names, formats, offsets, 20));
|
||||||
list.append(py::dtype(py::buffer_info((void *) 0, sizeof(unsigned int), "I", 1)));
|
list.append(py::dtype(py::buffer_info((void *) nullptr, sizeof(unsigned int), "I", 1)));
|
||||||
list.append(py::dtype(py::buffer_info((void *) 0, 0, "T{i:a:f:b:}", 1)));
|
list.append(py::dtype(py::buffer_info((void *) nullptr, 0, "T{i:a:f:b:}", 1)));
|
||||||
|
list.append(py::dtype(py::detail::npy_api::NPY_DOUBLE_));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,6 +441,34 @@ TEST_SUBMODULE(numpy_dtypes, m) {
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
|
m.def("test_dtype_num", [dtype_names]() {
|
||||||
|
py::list list;
|
||||||
|
for (const auto &dt_name : dtype_names) {
|
||||||
|
list.append(py::dtype(dt_name).num());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
m.def("test_dtype_byteorder", [dtype_names]() {
|
||||||
|
py::list list;
|
||||||
|
for (const auto &dt_name : dtype_names) {
|
||||||
|
list.append(py::dtype(dt_name).byteorder());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
m.def("test_dtype_alignment", [dtype_names]() {
|
||||||
|
py::list list;
|
||||||
|
for (const auto &dt_name : dtype_names) {
|
||||||
|
list.append(py::dtype(dt_name).alignment());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
m.def("test_dtype_flags", [dtype_names]() {
|
||||||
|
py::list list;
|
||||||
|
for (const auto &dt_name : dtype_names) {
|
||||||
|
list.append(py::dtype(dt_name).flags());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
m.def("test_dtype_methods", []() {
|
m.def("test_dtype_methods", []() {
|
||||||
py::list list;
|
py::list list;
|
||||||
auto dt1 = py::dtype::of<int32_t>();
|
auto dt1 = py::dtype::of<int32_t>();
|
||||||
@ -581,5 +610,5 @@ TEST_SUBMODULE(numpy_dtypes, m) {
|
|||||||
[]() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });
|
[]() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });
|
||||||
|
|
||||||
// test_str_leak
|
// test_str_leak
|
||||||
m.def("dtype_wrapper", [](py::object d) { return py::dtype::from_args(std::move(d)); });
|
m.def("dtype_wrapper", [](const py::object &d) { return py::dtype::from_args(d); });
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@ def test_dtype(simple_dtype):
|
|||||||
d1,
|
d1,
|
||||||
np.dtype("uint32"),
|
np.dtype("uint32"),
|
||||||
d2,
|
d2,
|
||||||
|
np.dtype("d"),
|
||||||
]
|
]
|
||||||
|
|
||||||
assert m.test_dtype_methods() == [
|
assert m.test_dtype_methods() == [
|
||||||
@ -175,8 +176,13 @@ def test_dtype(simple_dtype):
|
|||||||
np.zeros(1, m.trailing_padding_dtype())
|
np.zeros(1, m.trailing_padding_dtype())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expected_chars = "bhilqBHILQefdgFDG?MmO"
|
||||||
assert m.test_dtype_kind() == list("iiiiiuuuuuffffcccbMmO")
|
assert m.test_dtype_kind() == list("iiiiiuuuuuffffcccbMmO")
|
||||||
assert m.test_dtype_char_() == list("bhilqBHILQefdgFDG?MmO")
|
assert m.test_dtype_char_() == list(expected_chars)
|
||||||
|
assert m.test_dtype_num() == [np.dtype(ch).num for ch in expected_chars]
|
||||||
|
assert m.test_dtype_byteorder() == [np.dtype(ch).byteorder for ch in expected_chars]
|
||||||
|
assert m.test_dtype_alignment() == [np.dtype(ch).alignment for ch in expected_chars]
|
||||||
|
assert m.test_dtype_flags() == [chr(np.dtype(ch).flags) for ch in expected_chars]
|
||||||
|
|
||||||
|
|
||||||
def test_recarray(simple_dtype, packed_dtype):
|
def test_recarray(simple_dtype, packed_dtype):
|
||||||
|
@ -11,6 +11,34 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
namespace external {
|
||||||
|
namespace detail {
|
||||||
|
bool check(PyObject *o) { return PyFloat_Check(o) != 0; }
|
||||||
|
|
||||||
|
PyObject *conv(PyObject *o) {
|
||||||
|
PyObject *ret = nullptr;
|
||||||
|
if (PyLong_Check(o)) {
|
||||||
|
double v = PyLong_AsDouble(o);
|
||||||
|
if (!(v == -1.0 && PyErr_Occurred())) {
|
||||||
|
ret = PyFloat_FromDouble(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Unexpected type");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *default_constructed() { return PyFloat_FromDouble(0.0); }
|
||||||
|
} // namespace detail
|
||||||
|
class float_ : public py::object {
|
||||||
|
PYBIND11_OBJECT_CVT(float_, py::object, external::detail::check, external::detail::conv)
|
||||||
|
|
||||||
|
float_() : py::object(external::detail::default_constructed(), stolen_t{}) {}
|
||||||
|
|
||||||
|
double get_value() const { return PyFloat_AsDouble(this->ptr()); }
|
||||||
|
};
|
||||||
|
} // namespace external
|
||||||
|
|
||||||
TEST_SUBMODULE(pytypes, m) {
|
TEST_SUBMODULE(pytypes, m) {
|
||||||
// test_bool
|
// test_bool
|
||||||
m.def("get_bool", [] { return py::bool_(false); });
|
m.def("get_bool", [] { return py::bool_(false); });
|
||||||
@ -131,6 +159,15 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
return py::capsule([]() { py::print("destructing capsule"); });
|
return py::capsule([]() { py::print("destructing capsule"); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def("return_renamed_capsule_with_destructor", []() {
|
||||||
|
py::print("creating capsule");
|
||||||
|
auto cap = py::capsule([]() { py::print("destructing capsule"); });
|
||||||
|
static const char *capsule_name = "test_name1";
|
||||||
|
py::print("renaming capsule");
|
||||||
|
cap.set_name(capsule_name);
|
||||||
|
return cap;
|
||||||
|
});
|
||||||
|
|
||||||
m.def("return_capsule_with_destructor_2", []() {
|
m.def("return_capsule_with_destructor_2", []() {
|
||||||
py::print("creating capsule");
|
py::print("creating capsule");
|
||||||
return py::capsule((void *) 1234, [](void *ptr) {
|
return py::capsule((void *) 1234, [](void *ptr) {
|
||||||
@ -138,6 +175,17 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def("return_renamed_capsule_with_destructor_2", []() {
|
||||||
|
py::print("creating capsule");
|
||||||
|
auto cap = py::capsule((void *) 1234, [](void *ptr) {
|
||||||
|
py::print("destructing capsule: {}"_s.format((size_t) ptr));
|
||||||
|
});
|
||||||
|
static const char *capsule_name = "test_name2";
|
||||||
|
py::print("renaming capsule");
|
||||||
|
cap.set_name(capsule_name);
|
||||||
|
return cap;
|
||||||
|
});
|
||||||
|
|
||||||
m.def("return_capsule_with_name_and_destructor", []() {
|
m.def("return_capsule_with_name_and_destructor", []() {
|
||||||
auto capsule = py::capsule((void *) 12345, "pointer type description", [](PyObject *ptr) {
|
auto capsule = py::capsule((void *) 12345, "pointer type description", [](PyObject *ptr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
@ -545,4 +593,9 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 0, s0);
|
py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 0, s0);
|
||||||
return o;
|
return o;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def("square_float_", [](const external::float_ &x) -> double {
|
||||||
|
double v = x.get_value();
|
||||||
|
return v * v;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,6 +195,19 @@ def test_capsule(capture):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
a = m.return_renamed_capsule_with_destructor()
|
||||||
|
del a
|
||||||
|
pytest.gc_collect()
|
||||||
|
assert (
|
||||||
|
capture.unordered
|
||||||
|
== """
|
||||||
|
creating capsule
|
||||||
|
renaming capsule
|
||||||
|
destructing capsule
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
with capture:
|
with capture:
|
||||||
a = m.return_capsule_with_destructor_2()
|
a = m.return_capsule_with_destructor_2()
|
||||||
del a
|
del a
|
||||||
@ -207,6 +220,19 @@ def test_capsule(capture):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
with capture:
|
||||||
|
a = m.return_renamed_capsule_with_destructor_2()
|
||||||
|
del a
|
||||||
|
pytest.gc_collect()
|
||||||
|
assert (
|
||||||
|
capture.unordered
|
||||||
|
== """
|
||||||
|
creating capsule
|
||||||
|
renaming capsule
|
||||||
|
destructing capsule: 1234
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
with capture:
|
with capture:
|
||||||
a = m.return_capsule_with_name_and_destructor()
|
a = m.return_capsule_with_name_and_destructor()
|
||||||
del a
|
del a
|
||||||
@ -634,3 +660,8 @@ def test_implementation_details():
|
|||||||
assert m.tuple_item_set_ssize_t() == ("emely", "edmond")
|
assert m.tuple_item_set_ssize_t() == ("emely", "edmond")
|
||||||
assert m.tuple_item_get_size_t(tup) == 93
|
assert m.tuple_item_get_size_t(tup) == 93
|
||||||
assert m.tuple_item_set_size_t() == ("candy", "cat")
|
assert m.tuple_item_set_size_t() == ("candy", "cat")
|
||||||
|
|
||||||
|
|
||||||
|
def test_external_float_():
|
||||||
|
r1 = m.square_float_(2.0)
|
||||||
|
assert r1 == 4.0
|
||||||
|
@ -37,9 +37,10 @@ struct type_caster<boost::none_t> : void_caster<boost::none_t> {};
|
|||||||
// Test with `std::variant` in C++17 mode, or with `boost::variant` in C++11/14
|
// Test with `std::variant` in C++17 mode, or with `boost::variant` in C++11/14
|
||||||
#if defined(PYBIND11_HAS_VARIANT)
|
#if defined(PYBIND11_HAS_VARIANT)
|
||||||
using std::variant;
|
using std::variant;
|
||||||
|
# define PYBIND11_TEST_VARIANT 1
|
||||||
#elif defined(PYBIND11_TEST_BOOST)
|
#elif defined(PYBIND11_TEST_BOOST)
|
||||||
# include <boost/variant.hpp>
|
# include <boost/variant.hpp>
|
||||||
# define PYBIND11_HAS_VARIANT 1
|
# define PYBIND11_TEST_VARIANT 1
|
||||||
using boost::variant;
|
using boost::variant;
|
||||||
|
|
||||||
namespace pybind11 {
|
namespace pybind11 {
|
||||||
@ -424,7 +425,7 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
m.def("parent_path", [](const std::filesystem::path &p) { return p.parent_path(); });
|
m.def("parent_path", [](const std::filesystem::path &p) { return p.parent_path(); });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYBIND11_HAS_VARIANT
|
#ifdef PYBIND11_TEST_VARIANT
|
||||||
static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,
|
static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,
|
||||||
"visitor::result_type is required by boost::variant in C++11 mode");
|
"visitor::result_type is required by boost::variant in C++11 mode");
|
||||||
|
|
||||||
@ -435,6 +436,9 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
result_type operator()(const std::string &) { return "std::string"; }
|
result_type operator()(const std::string &) { return "std::string"; }
|
||||||
result_type operator()(double) { return "double"; }
|
result_type operator()(double) { return "double"; }
|
||||||
result_type operator()(std::nullptr_t) { return "std::nullptr_t"; }
|
result_type operator()(std::nullptr_t) { return "std::nullptr_t"; }
|
||||||
|
# if defined(PYBIND11_HAS_VARIANT)
|
||||||
|
result_type operator()(std::monostate) { return "std::monostate"; }
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// test_variant
|
// test_variant
|
||||||
@ -448,6 +452,18 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
using V = variant<int, std::string>;
|
using V = variant<int, std::string>;
|
||||||
return py::make_tuple(V(5), V("Hello"));
|
return py::make_tuple(V(5), V("Hello"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
# if defined(PYBIND11_HAS_VARIANT)
|
||||||
|
// std::monostate tests.
|
||||||
|
m.def("load_monostate_variant",
|
||||||
|
[](const variant<std::monostate, int, std::string> &v) -> const char * {
|
||||||
|
return py::detail::visit_helper<variant>::call(visitor(), v);
|
||||||
|
});
|
||||||
|
m.def("cast_monostate_variant", []() {
|
||||||
|
using V = variant<std::monostate, int, std::string>;
|
||||||
|
return py::make_tuple(V{}, V(5), V("Hello"));
|
||||||
|
});
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// #528: templated constructor
|
// #528: templated constructor
|
||||||
|
@ -263,6 +263,22 @@ def test_variant(doc):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skipif(
|
||||||
|
not hasattr(m, "load_monostate_variant"), reason="no std::monostate"
|
||||||
|
)
|
||||||
|
def test_variant_monostate(doc):
|
||||||
|
assert m.load_monostate_variant(None) == "std::monostate"
|
||||||
|
assert m.load_monostate_variant(1) == "int"
|
||||||
|
assert m.load_monostate_variant("1") == "std::string"
|
||||||
|
|
||||||
|
assert m.cast_monostate_variant() == (None, 5, "Hello")
|
||||||
|
|
||||||
|
assert (
|
||||||
|
doc(m.load_monostate_variant)
|
||||||
|
== "load_monostate_variant(arg0: Union[None, int, str]) -> str"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_vec_of_reference_wrapper():
|
def test_vec_of_reference_wrapper():
|
||||||
"""#171: Can't return reference wrappers (or STL structures containing them)"""
|
"""#171: Can't return reference wrappers (or STL structures containing them)"""
|
||||||
assert (
|
assert (
|
||||||
|
Loading…
Reference in New Issue
Block a user