Commit Graph

2868 Commits

Author SHA1 Message Date
Ralf W. Grosse-Kunstleve
c557f9a3ad
[smart_holder] type_caster ODR guard (#4022)
* Insert type_caster_odr_guard<> (an empty struct to start with).

* Add odr_guard_registry() used in type_caster_odr_guard() default constructor.

* Add minimal_real_caster (from PR #3862) to test_async, test_buffers

* VERY MESSY SNAPSHOT of WIP, this was the starting point for cl/454658864, which has more changes on top.

* Restore original test_async, test_buffers from current smart_holder HEAD

* Copy from cl/454991845 snapshot Jun 14, 5:08 PM

* Cleanup of tests. Systematically insert `if (make_caster<T>::translation_unit_local) {`

* Small simplification of odr_guard_impl()

* WIP

* Add PYBIND11_SOURCE_FILE_LINE macro.

* Replace PYBIND11_TYPE_CASTER_UNIQUE_IDENTIFIER with PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE, baked into PYBIND11_TYPE_CASTER macro.

* Add more PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL; resolves "unused" warning when compiling test_custom_type_casters.cpp

* load_type fixes & follow-on cleanup

* Strip ./ from source_file_line

* Add new tests to CMakeLists.txt, disable PYBIND11_WERROR

* Replace C++17 syntax. Compiles with Debian clang 13 C++11 mode, but fails to link. Trying GitHub Actions anyway to see if there are any platforms that support https://en.cppreference.com/w/cpp/language/tu_local before C++20. Note that Debian clang 13 C++17 works locally.

* Show C++ version along with ODR VIOLATION DETECTED message.

* Add source_file_line_basename()

* Introduce PYBIND11_TYPE_CASTER_ODR_GUARD_ON (but not set automatically).

* Minor cleanup.

* Set PYBIND11_TYPE_CASTER_ODR_GUARD_ON automatically.

* Resolve clang-tidy error.

* Compatibility with old compilers.

* Fix off-by-one in source_file_line_basename()

* Report PYBIND11_INTERNALS_ID & C++ Version from pytest_configure()

* Restore use of PYBIND11_WERROR

* Move cpp_version_in_use() from cast.h to pybind11_tests.cpp

* define PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED true in test_odr_guard_1,2.cpp

* IWYU cleanup of detail/type_caster_odr_guard.h

* Replace `throw err;` to resolve clang-tidy error.

* Add new header filename to CMakeLists.txt, test_files.py

* Experiment: Try any C++17 compiler.

* Fix ifdef for pragma GCC diagnostic.

* type_caster_odr_guard_impl() cleanup

* Move type_caster_odr_guard to type_caster_odr_guard.h

* Rename test_odr_guard* to test_type_caster_odr_guard*

* Remove comments that are (now) more distracting than helpful.

* Mark tu_local_no_data_always_false operator bool as explicit (clang-tidy). See also: https://stackoverflow.com/questions/39995573/when-can-i-use-explicit-operator-bool-without-a-cast

* New PYBIND11_TYPE_CASTER_ODR_GUARD_STRICT option (current on by default).

* Add test_type_caster_odr_registry_values(), test_type_caster_odr_violation_detected_counter()

* Report UNEXPECTED: test_type_caster_odr_guard_2.cpp prevailed (but do not fail).

* Apply clang-tidy suggestion.

* Attempt to handle valgrind behavior.

* Another attempt to handle valgrind behavior.

* Yet another attempt to handle valgrind behavior.

* Trying a new direction: show compiler info & std for UNEXPECTED: type_caster_odr_violation_detected_count() == 0

* compiler_info MSVC fix. num_violations == 0 condition.

* assert pybind11_tests.compiler_info is not None

* Introduce `make_caster_intrinsic<T>`, to be able to undo the 2 changes from `load_type` to `load_type<T>`. This is to avoid breaking 2 `pybind11::detail::load_type()` calls found in the wild (Google global testing).

One of the breakages in the wild was: 0f0f600767/python/tensorstore/subscript_method.h (L61)

* Add test for stl.h / stl_bind.h mix.

Manually verified that the ODR guard detects the ODR violation:

```
C++ Info: Debian Clang 13.0.1 C++17 __pybind11_internals_v4_clang_libstdcpp_cxxabi1002_sh_def__
=========================================================== test session starts ============================================================
platform linux -- Python 3.9.12, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
...
================================================================= FAILURES =================================================================
_____________________________________________ test_type_caster_odr_violation_detected_counter ______________________________________________

    def test_type_caster_odr_violation_detected_counter():
        ...
        else:
>           assert num_violations == 1
E           assert 2 == 1
E             +2
E             -1

num_violations = 2

test_type_caster_odr_guard_1.py:51: AssertionError
========================================================= short test summary info ==========================================================
FAILED test_type_caster_odr_guard_1.py::test_type_caster_odr_violation_detected_counter - assert 2 == 1
======================================================= 1 failed, 5 passed in 0.08s ========================================================
```

* Eliminate need for `PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL` macro.

Copying code first developed by @amauryfa. I tried this at an earlier stage, but by itself this was insufficient. In the meantime I added in the TU-local mechanisms: trying again.

Passes local testing:
```
DISABLED std::system_error: ODR VIOLATION DETECTED: pybind11::detail::type_caster<mrc_ns::type_mrc>: SourceLocation1="/usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_odr_guard_1.cpp:18", SourceLocation2="/usr/local/google/home/rwgk/forked/pybind11/tests/test_type_caster_odr_guard_2.cpp:19"
C++ Info: Debian Clang 13.0.1 C++17 __pybind11_internals_v4_clang_libstdcpp_cxxabi1002_sh_def__
=========================================================== test session starts ============================================================
platform linux -- Python 3.9.12, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /usr/local/google/home/rwgk/forked/pybind11/tests, configfile: pytest.ini
collected 6 items

test_type_caster_odr_guard_1.py::test_type_mrc_to_python PASSED
test_type_caster_odr_guard_1.py::test_type_mrc_from_python PASSED
test_type_caster_odr_guard_1.py::test_type_caster_odr_registry_values PASSED
test_type_caster_odr_guard_1.py::test_type_caster_odr_violation_detected_counter PASSED
test_type_caster_odr_guard_2.py::test_type_mrc_to_python PASSED
test_type_caster_odr_guard_2.py::test_type_mrc_from_python PASSED

============================================================ 6 passed in 0.01s =============================================================
```

* tu_local_descr with src_loc experiment

* clang-tidy suggested fixes

* Use source_file_line_from_sloc in type_caster_odr_guard_registry

* Disable type_caster ODR guard for __INTEL_COMPILER (see comment). Also turn off printf.

* Add missing include (discovered via google-internal testing).

* Work `scr_loc` into `descr`

* Use `TypeCasterType::name.sloc` instead of `source_file_line.sloc`

Manual re-verification:

```
+++ b/tests/test_type_caster_odr_guard_2.cpp
-    // m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
+    m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
```

```
>           assert num_violations == 1
E           assert 2 == 1

num_violations = 2

test_type_caster_odr_guard_1.py:51: AssertionError
```

* Fix small oversight (src_loc::here() -> src_loc{nullptr, 0}).

* Remove PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL macro completely.

* Remove PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE macro completely. Some small extra cleanup.

* Minor tweaks looking at the PR with a fresh eye.

* src_loc comments

* Add new test_descr_src_loc & and fix descr.h `concat()` `src_loc` bug discovered while working on the test.

* Some more work on source code comments.

* Fully document the ODR violations in the ODR guard itself and introduce `PYBIND11_TYPE_CASTER_ODR_GUARD_ON_IF_AVAILABLE`

* Update comment (incl. mention of deadsnakes known to not work as intended).

* Use no-destructor idiom for type_caster_odr_guard_registry, as suggested by @laramiel

* Fix clang-tidy error: 'auto reg' can be declared as 'auto *reg' [readability-qualified-auto,-warnings-as-errors]

* WIP

* Revert "WIP" (tu_local_no_data_always_false_base experiment).

This reverts commit 31e8ac562f.

* Change `PYBIND11_TYPE_CASTER_ODR_GUARD_ON` to `PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD`, based on a suggestion by @rainwoodman

* Improved `#if` determining `PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD`, based on suggestion by @laramiel

* Make `descr::sloc` `const`, as suggested by @rainwoodman

* Rename macro to `PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_DEBUG`, as suggested by @laramiel

* Tweak comments some more (add "white hat hacker" analogy).

* Bring back `PYBIND11_CPP17` in determining `PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD`, to hopefully resolve most if not all of the many CI failures (89 failing, 32 successful: https://github.com/pybind/pybind11/runs/7430295771).

* Try another workaround for `__has_builtin`-related breakages (https://github.com/pybind/pybind11/runs/7430720321).

* Remove `defined(__has_builtin)` and subconditions.

* Update "known to not work" expectation in test and comment.

* `pytest.skip` `num_violations == 0` only `#ifdef __NO_INLINE__` (irrespective of the compiler)

* Systematically change all new `#ifdef` to `#if defined` (review suggestion).

* Bring back MSVC comment that got lost while experimenting.
2022-07-21 06:38:21 -07:00
Ralf W. Grosse-Kunstleve
0ec9e31bbf Merge branch 'master' into sh_merge_master 2022-07-12 18:37:15 -07:00
Ralf W. Grosse-Kunstleve
203cc26f5b
[smart_holder] Add test_namespace_visibility (#4050)
* Add test_namespace_visibility

To probe environment/toolchain/platform-specific behavior under the exact same conditions as normal tests.

(An earlier version of this code was used to inform PR #4043.)

* Disable flake8 in ubench/holder_comparison_*.py, to suppress new & useless diagnostics.

* Disable namespace_visibility_1s.cpp (tosee if that resolves the MSVC and CUDA `test_cross_module_exception_translator` failures).

* Turn off flake8 completely for ubench (the Strip unnecessary `# noqa`s action un-helpfully removed the added noqa).

* Disable test_namespace_visibility completely. Just keep the two .cpp files, only setting the module docstring and doing nothing else.

* Rename test_namespace_visibility.py to test_exc_namespace_visibility.py, so that it is imported by pytest before test_exceptions.py

* Add `set_property(SOURCE namespace_visibility_1s.cpp PROPERTY LANGUAGE CUDA)`

* Add reference to PR #4054

* Complete the documentation (comments in test_exc_namespace_visibility.py).

* Rename namespace_visibility.h to namespace_visibility.inl, as suggested by @charlesbeattie
2022-07-12 18:33:42 -07:00
Ralf W. Grosse-Kunstleve
023b3f32c8
Undo accidental one-line change under PR #3913 (#4060) 2022-07-12 12:02:20 -07:00
pre-commit-ci[bot]
790241bce2
[pre-commit.ci] pre-commit autoupdate (#4058)
updates:
- [github.com/asottile/pyupgrade: v2.34.0 → v2.37.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v2.37.1)
- [github.com/hadialqattan/pycln: v1.3.5 → v2.0.1](https://github.com/hadialqattan/pycln/compare/v1.3.5...v2.0.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-11 22:31:54 -04:00
Ralf W. Grosse-Kunstleve
bcd1800cf4 Turn off flake8 completely for ubench/
To suppress these new errors (apparently after a flake8 upgrade):

```
flake8...................................................................Failed
- hook id: flake8
- exit code: 1

ubench/holder_comparison.py:96:38: B023 Function definition does not bind loop variable 'nb1'.
                    assert int(round(nb1.sum())) == data_size
                                     ^
ubench/holder_comparison.py:96:53: B023 Function definition does not bind loop variable 'data_size'.
                    assert int(round(nb1.sum())) == data_size
                                                    ^
ubench/holder_comparison.py:99:25: B023 Function definition does not bind loop variable 'nb1'.
                        nb1.sum()
                        ^
ubench/holder_comparison.py:103:28: B023 Function definition does not bind loop variable 'nb1'.
                    assert nb1.add(nb2) == data_size
                           ^
ubench/holder_comparison.py:103:36: B023 Function definition does not bind loop variable 'nb2'.
                    assert nb1.add(nb2) == data_size
                                   ^
ubench/holder_comparison.py:103:44: B023 Function definition does not bind loop variable 'data_size'.
                    assert nb1.add(nb2) == data_size
                                           ^
ubench/holder_comparison.py:106:25: B023 Function definition does not bind loop variable 'nb1'.
                        nb1.add(nb2)
                        ^
ubench/holder_comparison.py:106:33: B023 Function definition does not bind loop variable 'nb2'.
                        nb1.add(nb2)
                                ^
ubench/holder_comparison_extract_sheet_data.py:21:16: B023 Function definition does not bind loop variable 'header_row'.
            if header_row:
               ^
ubench/holder_comparison_extract_sheet_data.py:22:20: B023 Function definition does not bind loop variable 'header'.
                if header is None:  # type: ignore[unreachable]
                   ^
ubench/holder_comparison_extract_sheet_data.py:23:36: B023 Function definition does not bind loop variable 'header_row'.
                    print(",".join(header_row))
                                   ^
ubench/holder_comparison_extract_sheet_data.py:25:28: B023 Function definition does not bind loop variable 'header'.
                    assert header == header_row
                           ^
ubench/holder_comparison_extract_sheet_data.py:25:38: B023 Function definition does not bind loop variable 'header_row'.
                    assert header == header_row
                                     ^
ubench/holder_comparison_extract_sheet_data.py:26:16: B023 Function definition does not bind loop variable 'data_row'.
            if data_row is not None:
               ^
ubench/holder_comparison_extract_sheet_data.py:27:32: B023 Function definition does not bind loop variable 'data_row'.
                print(",".join(data_row))  # type: ignore[unreachable]
                               ^
ubench/holder_comparison_extract_sheet_data.py:28:17: B023 Function definition does not bind loop variable 'data_row_buffer'.
                data_row_buffer.append(data_row)
                ^
ubench/holder_comparison_extract_sheet_data.py:28:40: B023 Function definition does not bind loop variable 'data_row'.
                data_row_buffer.append(data_row)
                                       ^
ubench/holder_comparison_extract_sheet_data.py:29:20: B023 Function definition does not bind loop variable 'header_row'.
            return header_row
                   ^
```
2022-07-09 21:50:36 -07:00
Ralf W. Grosse-Kunstleve
3bd20627d3 Tracking ci.yml changes from master. 2022-07-09 21:50:08 -07:00
Ralf W. Grosse-Kunstleve
27ce64fc43 Merge branch 'master' into sh_merge_master 2022-07-09 21:47:49 -07:00
Aaron Gokaslan
f9f00495a3
Properly visit self in >=3.9 traverse (#4051)
* Properly visit self in >=3.9 traverse

* Add comment about 3.9 behavior
2022-07-09 21:43:53 -07:00
Ralf W. Grosse-Kunstleve
432bc5cfb5
Add std::string clean_type_id(const char *typeid_name) overload (in namespace detail). (#4049)
Very minor refactoring to ease development and debugging.

Having to declare a local `std::string` has bugged me many times. Nice to get this little nuisance out of the way.

Extracted from PR #4022, where it is used like this:

```
    std::fprintf(stdout,
                 "\nTYPE_CASTER_ODR_GUARD_IMPL %s %s\n",
                 clean_type_id(intrinsic_type_info.name()).c_str(),
                 source_file_line_from_sloc.c_str());
```
2022-07-07 19:08:10 -07:00
Ralf W. Grosse-Kunstleve
85bc088441
Report C++ Info: via pytest_report_header() (#4046)
* Report `C++ Info:` from `pytest_configure()`

* Use pytest_report_header() as suggested by @skylion007
2022-07-07 17:51:44 -07:00
Ralf W. Grosse-Kunstleve
cd08869df1
PYBIND11_NAMESPACE consistency fixes. (#4043) 2022-07-06 14:29:20 -07:00
Henry Schreiner
0ab1fcfb1c
docs: update changelog (#4042)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-07-06 16:36:05 -04:00
Aaron Gokaslan
2af163d9c7
Fix: 3.11 beta support (#3923)
* Placeholder commit for 3.11 testing

* Does this fix it?

* Try suggestion

* Placeholder commit for 3.11 testing

* Does this fix it?

* Try suggestion

* fix: try using modern init for embedded interp

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: error message changed in 3.11

* fix: apply logic in Python manually

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix autodetect dynamic attrs in 3.11

* fix: include error message if possible in error

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* ci: enable standard Python 3.11 testing

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Make dynamic attrs condtiion exclusive to ver.

Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-07-06 16:35:12 -04:00
pre-commit-ci[bot]
c42e3ab793
[pre-commit.ci] pre-commit autoupdate (#4041)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0)
- [github.com/Lucas-C/pre-commit-hooks: v1.2.0 → v1.3.0](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.2.0...v1.3.0)
- [github.com/PyCQA/pylint: v2.14.3 → v2.14.4](https://github.com/PyCQA/pylint/compare/v2.14.3...v2.14.4)
- [github.com/pre-commit/mirrors-clang-format: v14.0.5 → v14.0.6](https://github.com/pre-commit/mirrors-clang-format/compare/v14.0.5...v14.0.6)

* Update blacken-docs

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Aaron Gokaslan <skylion.aaron@gmail.com>
2022-07-04 22:21:59 -04:00
dependabot[bot]
bc1f9f9ba6
chore(deps): bump actions/setup-python from 3 to 4 (#3999)
* chore(deps): bump actions/setup-python from 3 to 4

Bumps [actions/setup-python](https://github.com/actions/setup-python) from 3 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Apply suggestions from code review

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2022-07-04 10:24:55 -04:00
Henry Schreiner
5a3a1e3415
chore: simpler dependabot (#4035)
Ignores no longer needed after April 2022. Dependabot keeps the same style pinning now.
2022-07-04 10:24:34 -04:00
Matthew Woehlke
479e9a50f3
Fix arrays with zero-size dimensions (#4038)
When converting an array to an Eigen matrix, ignore the strides if any
dimension size is 0. If the array is empty, the strides aren't relevant,
and especially numpy ≥ 1.23 explicitly sets the strides to 0 in this
case. (See numpy commit dd5ab7b11520.)

Update tests to verify that this works, and continues to work.
2022-06-29 11:37:16 -07:00
Masaki Kozuki
374a5b000a
[docs] Fix "Enumerations and internal types" example (#4034)
* Fix binding of `Pet::Attributes`

* omit `attributes` as it's not needed

Signed-off-by: Masaki Kozuki <mkozuki@nvidia.com>
2022-06-28 12:38:37 -07:00
Ralf W. Grosse-Kunstleve
f158f96634 Tracking ci.yml changes from master. 2022-06-27 22:28:18 -07:00
Ralf W. Grosse-Kunstleve
cad2609381 Merge branch 'master' into smart_holder 2022-06-27 22:24:23 -07:00
Xiaofei Wang
c0cfe95b1b
Support loading unique_ptr<Derived> as unique_ptr<Base>. (#4031)
* Support loading unique_ptr<derived> as unique_ptr<base>.

* Fix incorrect test

* pre commit fix

* Fix clang tidy

* Resolve comments

* Resolve comments
2022-06-27 22:21:28 -07:00
pre-commit-ci[bot]
dd3bf7fd12
[pre-commit.ci] pre-commit autoupdate (#4030)
updates:
- [github.com/hadialqattan/pycln: v1.3.3 → v1.3.5](https://github.com/hadialqattan/pycln/compare/v1.3.3...v1.3.5)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-27 19:39:19 -04:00
Henry Schreiner
c3e9173f0f
ci: use almalinux instead of centos, add 9 (#4020)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-06-21 14:55:49 -04:00
pre-commit-ci[bot]
2ad974c945
[pre-commit.ci] pre-commit autoupdate (#4021)
updates:
- [github.com/PyCQA/pylint: v2.14.1 → v2.14.3](https://github.com/PyCQA/pylint/compare/v2.14.1...v2.14.3)
- [github.com/pre-commit/mirrors-clang-format: v14.0.4-1 → v14.0.5](https://github.com/pre-commit/mirrors-clang-format/compare/v14.0.4-1...v14.0.5)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-21 14:36:49 -04:00
Aaron Gokaslan
0964a9093a
Add a missing std::move in numpy.h (#4005) 2022-06-14 14:20:26 -04:00
pre-commit-ci[bot]
21f0e72b0f
[pre-commit.ci] pre-commit autoupdate (#4003) 2022-06-13 21:02:25 -04:00
dependabot[bot]
0e956a2e4f
chore(deps): bump pre-commit/action from 2.0.3 to 3.0.0 (#3992)
Bumps [pre-commit/action](https://github.com/pre-commit/action) from 2.0.3 to 3.0.0.
- [Release notes](https://github.com/pre-commit/action/releases)
- [Commits](https://github.com/pre-commit/action/compare/v2.0.3...v3.0.0)

---
updated-dependencies:
- dependency-name: pre-commit/action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-08 09:22:57 -04:00
Aaron Gokaslan
e2dcd95407
chore: optimize dictionary access in strip_padding numpy (#3994)
* emplace field descriptors

* reserve sufficient capacity

* remove std::move

* properly iterate through dict

* make handle casting more explicit

* Revert to old dict api
2022-06-06 22:33:28 -04:00
Maarten Baert
918892b97e
Make dtype::num() return type consistent with other functions (#3995) 2022-06-06 19:41:38 -04:00
pre-commit-ci[bot]
c5fa3436c6
[pre-commit.ci] pre-commit autoupdate (#3951)
updates:
- [github.com/asottile/pyupgrade: v2.32.1 → v2.33.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.33.0)
- [github.com/Lucas-C/pre-commit-hooks: v1.1.13 → v1.2.0](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.1.13...v1.2.0)
- [github.com/hadialqattan/pycln: v1.3.2 → v1.3.3](https://github.com/hadialqattan/pycln/compare/v1.3.2...v1.3.3)
- [github.com/PyCQA/pylint: v2.13.8 → v2.14.1](https://github.com/PyCQA/pylint/compare/v2.13.8...v2.14.1)
- [github.com/pre-commit/mirrors-mypy: v0.950 → v0.960](https://github.com/pre-commit/mirrors-mypy/compare/v0.950...v0.960)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-06 17:56:18 -04:00
Aaron Gokaslan
554c045377
enable two new clang-tidy checks (#3988)
* enable two new clang-tidy checks

* Use better loop var for char
2022-06-06 12:15:45 -04:00
Aaron Gokaslan
42a41bf3e7
remove useless ctor (#3989) 2022-06-03 15:18:06 -04:00
Ralf W. Grosse-Kunstleve
cf2c307e7b Merge branch 'master' into sh_merge_master 2022-06-02 16:26:40 -07:00
Sergei Lebedev
a05bc3d235
error_already_set::what() is now constructed lazily (#1895)
* error_already_set::what() is now constructed lazily

Prior to this commit throwing error_already_set was expensive due to the
eager construction of the error string (which required traversing the
Python stack). See #1853 for more context and an alternative take on the
issue.

Note that error_already_set no longer inherits from std::runtime_error
because the latter has no default constructor.

* Do not attempt to normalize if no exception occurred

This is not supported on PyPy-2.7 5.8.0.

* Extract exception name via tp_name

This is faster than dynamically looking up __name__ via GetAttrString.
Note though that the runtime of the code throwing an error_already_set
will be dominated by stack unwinding so the improvement will not be
noticeable.

Before:

396 ns ± 0.913 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

After:

277 ns ± 0.549 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Benchmark:

const std::string foo() {
    PyErr_SetString(PyExc_KeyError, "");
    const std::string &s = py::detail::error_string();
    PyErr_Clear();
    return s;
}

PYBIND11_MODULE(foo, m) {
    m.def("foo", &::foo);
}

* Reverted error_already_set to subclass std::runtime_error

* Revert "Extract exception name via tp_name"

The implementation of __name__ is slightly more complex than that.
It handles the module name prefix, and heap-allocated types. We could
port it to pybind11 later on but for now it seems like an overkill.

This reverts commit f1435c7e6b.

* Cosmit following @YannickJadoul's comments

Note that detail::error_string() no longer calls PyException_SetTraceback
as it is unncessary for pretty-printing the exception.

* Fixed PyPy build

* Moved normalization to error_already_set ctor

* Fix merge bugs

* Fix more merge errors

* Improve formatting

* Improve error message in rare case

* Revert back if statements

* Fix clang-tidy

* Try removing mutable

* Does build_mode release fix it

* Set to Debug to expose segfault

* Fix remove set error string

* Do not run error_string() more than once

* Trying setting the tracebackk to the value

* guard if m_type is null

* Try to debug PGI

* One last try for PGI

* Does reverting this fix PyPy

* Reviewer suggestions

* Remove unnecessary initialization

* Add noexcept move and explicit fail throw

* Optimize error_string creation

* Fix typo

* Revert noexcept

* Fix merge conflict error

* Abuse assignment operator

* Revert operator abuse

* See if we still need debug

* Remove unnecessary mutable

* Report "FATAL failure building pybind11::error_already_set error_string" and terminate process.

* Try specifying noexcept again

* Try explicit ctor

* default ctor is noexcept too

* Apply reviewer suggestions, simplify code, and make helper method private

* Remove unnecessary include

* Clang-Tidy fix

* detail::obj_class_name(), fprintf with [STDERR], [STDOUT] tags, polish comments

* consistently check m_lazy_what.empty() also in production builds

* Make a comment slightly less ambiguous.

* Bug fix: Remove `what();` from `restore()`.

It sure would need to be guarded by `if (m_type)`, otherwise `what()` fails and masks that no error was set (see update unit test). But since `error_already_set` is copyable, there is no point in releasing m_type, m_value, m_trace, therefore we can just as well avoid the runtime overhead of force-building `m_lazy_what`, it may never be used.

* Replace extremely opaque (unhelpful) error message with a truthful reflection of what we know.

* Fix clang-tidy error [performance-move-constructor-init].

* Make expected error message less specific.

* Various changes.

* bug fix: error_string(PyObject **, ...)

* Putting back the two eager PyErr_NormalizeException() calls.

* Change error_already_set() to call pybind11_fail() if the Python error indicator not set. The net result is that a std::runtime_error is thrown instead of error_already_set, but all tests pass as is.

* Remove mutable (fixes oversight in the previous commit).

* Normalize the exception only locally in error_string(). Python 3.6 & 3.7 test failures expected. This is meant for benchmarking, to determine if it is worth the trouble looking into the failures.

* clang-tidy: use auto

* Use `gil_scoped_acquire_local` in `error_already_set` destructor. See long comment.

* For Python < 3.8: `PyErr_NormalizeException` before `PyErr_WriteUnraisable`

* Go back to replacing the held Python exception with then normalized exception, if & when needed. Consistently document the side-effect.

* Slightly rewording comment. (There were also other failures.)

* Add 1-line comment for obj_class_name()

* Benchmark code, with results in this commit message.

          function                   #calls  test time [s]  μs / call
master    pure_unwind                729540      1.061      14.539876
          err_set_unwind_err_clear   681476      1.040      15.260282
          err_set_error_already_set  508038      1.049      20.640525
          error_already_set_restore  555578      1.052      18.933288
          pr1895_original_foo        244113      1.050      43.018168
                                                                       PR / master
PR #1895  pure_unwind                736981      1.054      14.295685       98.32%
          err_set_unwind_err_clear   685820      1.045      15.237399       99.85%
          err_set_error_already_set  661374      1.046      15.811879       76.61%
          error_already_set_restore  669881      1.048      15.645176       82.63%
          pr1895_original_foo        318243      1.059      33.290806       77.39%

master @ commit ad146b2a18

Running tests in directory "/usr/local/google/home/rwgk/forked/pybind11/tests":
============================= test session starts ==============================
platform linux -- Python 3.9.10, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /usr/local/google/home/rwgk/forked/pybind11/tests, configfile: pytest.ini
collecting ... collected 5 items

test_perf_error_already_set.py::test_perf[pure_unwind]
PERF pure_unwind,729540,1.061,14.539876
PASSED
test_perf_error_already_set.py::test_perf[err_set_unwind_err_clear]
PERF err_set_unwind_err_clear,681476,1.040,15.260282
PASSED
test_perf_error_already_set.py::test_perf[err_set_error_already_set]
PERF err_set_error_already_set,508038,1.049,20.640525
PASSED
test_perf_error_already_set.py::test_perf[error_already_set_restore]
PERF error_already_set_restore,555578,1.052,18.933288
PASSED
test_perf_error_already_set.py::test_perf[pr1895_original_foo]
PERF pr1895_original_foo,244113,1.050,43.018168
PASSED

============================== 5 passed in 12.38s ==============================

pr1895 @ commit 8dff51d12e

Running tests in directory "/usr/local/google/home/rwgk/forked/pybind11/tests":
============================= test session starts ==============================
platform linux -- Python 3.9.10, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /usr/local/google/home/rwgk/forked/pybind11/tests, configfile: pytest.ini
collecting ... collected 5 items

test_perf_error_already_set.py::test_perf[pure_unwind]
PERF pure_unwind,736981,1.054,14.295685
PASSED
test_perf_error_already_set.py::test_perf[err_set_unwind_err_clear]
PERF err_set_unwind_err_clear,685820,1.045,15.237399
PASSED
test_perf_error_already_set.py::test_perf[err_set_error_already_set]
PERF err_set_error_already_set,661374,1.046,15.811879
PASSED
test_perf_error_already_set.py::test_perf[error_already_set_restore]
PERF error_already_set_restore,669881,1.048,15.645176
PASSED
test_perf_error_already_set.py::test_perf[pr1895_original_foo]
PERF pr1895_original_foo,318243,1.059,33.290806
PASSED

============================== 5 passed in 12.40s ==============================

clang++ -o pybind11/tests/test_perf_error_already_set.os -c -std=c++17 -fPIC -fvisibility=hidden -Os -flto -Wall -Wextra -Wconversion -Wcast-qual -Wdeprecated -Wnon-virtual-dtor -Wunused-result -isystem /usr/include/python3.9 -isystem /usr/include/eigen3 -DPYBIND11_STRICT_ASSERTS_CLASS_HOLDER_VS_TYPE_CASTER_MIX -DPYBIND11_TEST_BOOST -Ipybind11/include -I/usr/local/google/home/rwgk/forked/pybind11/include -I/usr/local/google/home/rwgk/clone/pybind11/include /usr/local/google/home/rwgk/forked/pybind11/tests/test_perf_error_already_set.cpp

clang++ -o lib/pybind11_tests.so -shared -fPIC -Os -flto -shared ...

Debian clang version 13.0.1-3+build2
Target: x86_64-pc-linux-gnu
Thread model: posix

* Changing call_repetitions_target_elapsed_secs to 0.1 for regular unit testing.

* Adding in `recursion_depth`

* Optimized ctor

* Fix silly bug in recurse_first_then_call()

* Add tests that have equivalent PyErr_Fetch(), PyErr_Restore() but no try-catch.

* Add call_error_string to tests. Sample only recursion_depth 0, 100.

* Show lazy-what speed-up in percent.

* Include real_work in benchmarks.

* Replace all PyErr_SetString() with generate_python_exception_with_traceback()

* Better organization of test loops.

* Add test_error_already_set_copy_move

* Fix bug in newly added test (discovered by clang-tidy): actually use move ctor

* MSVC detects the unreachable return

* change test_perf_error_already_set.py back to quick mode

* Inherit from std::exception (instead of std::runtime_error, which does not make sense anymore with the lazy what)

* Special handling under Windows.

* print with leading newline

* Removing test_perf_error_already_set (copies are under 7765113fbb).

* Avoid gil and scope overhead if there is nothing to release.

* Restore default move ctor. "member function" instead of "function" (note that "method" is Python terminology).

* Delete error_already_set copy ctor.

* Make restore() non-const again to resolve clang-tidy failure (still experimenting).

* Bring back error_already_set copy ctor, to see if that resolves the 4 MSVC test failures.

* Add noexcept to error_already_set copy & move ctors (as suggested by @skylion007 IIUC).

* Trying one-by-one noexcept copy ctor for old compilers.

* Add back test covering copy ctor. Add another simple test that exercises the copy ctor.

* Exclude more older compilers from using the noexcept = default ctors. (The tests in the previous commit exposed that those are broken.)

* Factor out & reuse gil_scoped_acquire_local as gil_scoped_acquire_simple

* Guard gil_scoped_acquire_simple by _Py_IsFinalizing() check.

* what() GIL safety

* clang-tidy & Python 3.6 fixes

* Use `gil_scoped_acquire` in dtor, copy ctor, `what()`. Remove `_Py_IsFinalizing()` checks (they are racy: https://github.com/python/cpython/pull/28525).

* Remove error_scope from copy ctor.

* Add `error_scope` to `get_internals()`, to cover the situation that `get_internals()` is called from the `error_already_set` dtor while a new Python error is in flight already. Also backing out `gil_scoped_acquire_simple` change.

* Add `FlakyException` tests with failure triggers in `__init__` and `__str__`

THIS IS STILL A WORK IN PROGRESS. This commit is only an important resting point.

This commit is a first attempt at addressing the observation that `PyErr_NormalizeException()` completely replaces the original exception if `__init__` fails. This can be very confusing even in small applications, and extremely confusing in large ones.

* Tweaks to resolve Py 3.6 and PyPy CI failures.

* Normalize Python exception immediately in error_already_set ctor.

For background see: https://github.com/pybind/pybind11/pull/1895#issuecomment-1135304081

* Fix oversights based on CI failures (copy & move ctor initialization).

* Move @pytest.mark.xfail("env.PYPY") after @pytest.mark.parametrize(...)

* Use @pytest.mark.skipif (xfail does not work for segfaults, of course).

* Remove unused obj_class_name_or() function (it was added only under this PR).

* Remove already obsolete C++ comments and code that were added only under this PR.

* Slightly better (newly added) comments.

* Factor out detail::error_fetch_and_normalize. Preparation for producing identical results from error_already_set::what() and detail::error_string(). Note that this is a very conservative refactoring. It would be much better to first move detail::error_string into detail/error_string.h

* Copy most of error_string() code to new error_fetch_and_normalize::complete_lazy_error_string()

* Remove all error_string() code from detail/type_caster_base.h. Note that this commit includes a subtle bug fix: previously error_string() restored the Python error, which will upset pybind11_fail(). This never was a problem in practice because the two PyType_Ready() calls in detail/class.h do not usually fail.

* Return const std::string& instead of const char * and move error_string() to pytypes.h

* Remove gil_scope_acquire from error_fetch_and_normalize, add back to error_already_set

* Better handling of FlakyException __str__ failure.

* Move error_fetch_and_normalize::complete_lazy_error_string() implementation from pybind11.h to pytypes.h

* Add error_fetch_and_normalize::release_py_object_references() and use from error_already_set dtor.

* Use shared_ptr for m_fetched_error => 1. non-racy, copy ctor that does not need the GIL; 2. enables guard against duplicate restore() calls.

* Add comments.

* Trivial renaming of a newly introduced member function.

* Workaround for PyPy

* Bug fix (oversight). Only valgrind got this one.

* Use shared_ptr custom deleter for m_fetched_error in error_already_set. This enables removing the dtor, copy ctor, move ctor completely.

* Further small simplification. With the GIL held, simply deleting the raw_ptr takes care of everything.

* IWYU cleanup

```
iwyu version: include-what-you-use 0.17 based on Debian clang version 13.0.1-3+build2
```

Command used:

```
iwyu -c -std=c++17 -DPYBIND11_TEST_BOOST -Iinclude/pybind11 -I/usr/include/python3.9 -I/usr/include/eigen3 include/pybind11/pytypes.cpp
```

pytypes.cpp is a temporary file: `#include "pytypes.h"`

The raw output is very long and noisy.

I decided to use `#include <cstddef>` instead of `#include <cstdio>` for `std::size_t` (iwyu sticks to the manual choice).

I ignored all iwyu suggestions that are indirectly covered by `#include <Python.h>`.

I manually verified that all added includes are actually needed.

Co-authored-by: Aaron Gokaslan <skylion.aaron@gmail.com>
Co-authored-by: Ralf W. Grosse-Kunstleve <rwgk@google.com>
2022-06-02 16:17:38 -07:00
Ralf W. Grosse-Kunstleve
485dacef6a Merge branch 'master' into sh_merge_master 2022-06-01 14:39:51 -07:00
Aaron Gokaslan
58802de41b
perf: Add object rvalue overload for accessors. Enables reference stealing (#3970)
* Add object rvalue overload for accessors. Enables reference stealing

* Fix comments

* Fix more comment typos

* Fix bug

* reorder declarations for clarity

* fix another perf bug

* should be static

* future proof operator overloads

* Fix perfect forwarding

* Add a couple of tests

* Remove errant include

* Improve test documentation

* Add dict test

* add object attr tests

* Optimize STL map caster and cleanup enum

* Reorder to match declarations

* adjust increfs

* Remove comment

* revert value change

* add missing move
2022-06-01 15:19:13 -04:00
Ralf W. Grosse-Kunstleve
9f7b3f735a
addl unit tests for PR #3970 (#3977)
* Add test_perf_accessors (to be merged into test_pytypes).

* Python < 3.8 f-string compatibility

* Use thread_local in inc_ref_counter()

* Intentional breakage, brute-force way to quickly find out how many platforms reach the PYBIND11_HANDLE_REF_DEBUG code, with and without threads.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove Intentional breakage

* Drop perf test, move inc_refs tests to test_pytypes

* Fold in PR #3970 with `#ifdef`s

* Complete test coverage for all newly added code.

* Condense new unit tests via a simple local helper macro.

* Remove PYBIND11_PR3970 define. See https://github.com/pybind/pybind11/pull/3977#issuecomment-1142526417

* Move static keyword first (fixes silly oversight).

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-31 12:59:19 -07:00
Ralf W. Grosse-Kunstleve
b24c5ed204
Replace "Unknown internal error occurred" with a more helpful message. (#3982) 2022-05-31 11:54:33 -07:00
Ralf W. Grosse-Kunstleve
de4ba92c9f
Add error_scope to detail::get_internals() (#3981)
* Add `error_scope` to `detail::get_internals()`

* Adjust test to tolerate macOS PyPy behavior.
2022-05-31 11:51:13 -07:00
Aaron Gokaslan
8da58da539
chore: perfectly forward all make_iterator args (#3980)
* Perfectly forward all make_iterator args

* Try emplace back
2022-05-28 19:58:15 -04:00
Ralf W. Grosse-Kunstleve
748ae2270b
Add missing error handling to module_::def_submodule (#3973)
* Add missing error handling to module_::def_submodule

* Add test_def_submodule_failures

* PyPy only: Skip test with trigger for PyModule_GetName() failure.

* Reapply minor fix that accidentally got lost in transfer from PR #3964
2022-05-28 16:40:57 -07:00
Aaron Gokaslan
68f8010500
chore: add err guard to capsule destructor and add a move to iostream (#3958)
* Add err guard to capsule destructor

* only uses ostream currently

* can these be noexcept

* Add back header

* fix for older compilers

* This should at least be noexcept

* Add missing move

* Apparently not noexcept for old llvm
2022-05-27 14:32:57 -04:00
Ralf W. Grosse-Kunstleve
8d14e666e3
fix: avoid catch (...) for expected import numpy failures (#3974)
* Replace import numpy catch (...) with catch (error_already_set)

* Add missing const (not sure how those got lost).
2022-05-26 11:07:40 -04:00
Ralf W. Grosse-Kunstleve
2c549eb7aa
Move PyErr_NormalizeException() up a few lines (#3971)
* Add error_already_set_what what tests, asserting the status quo.

* Move PyErr_NormalizeException() up a few lines.

* @pytest.mark.skipif("env.PYPY") from PR #1895 is required even for this much simpler PR

* Move PyException_SetTraceback() with PyErr_NormalizeException() as suggested by @skylion007

* Insert a std::move() as suggested by @skylion007
2022-05-25 21:44:55 -07:00
Aaron Gokaslan
2d4a20c8cb
chore: add missing moves for buffer_func and staticmethod in pybind11.h (#3969)
* Use move converting ctor when making class staticmethod

* Add missing caster move in buffer func

* fix use after move

* add back move to staticmethod

* avoid shadowing with varname
2022-05-25 12:14:07 -04:00
Maarten Baert
4624e8e164
Don't return pointers to static objects with return_value_policy::take_ownership. (#3946)
* Don't return pointers to static objects with return_value_policy::take_ownership.

This fixes -Wfree-nonheap-object warnings produced by GCC.

* Use return value policy fix instead

Co-authored-by: Aaron Gokaslan <skylion.aaron@gmail.com>
2022-05-24 13:46:31 -04:00
Aaron Gokaslan
c42414db86
(perf): use a rvalue cast in func_wrapper (#3966)
* (perf): use an rvalue cast in func_wrapper

* Try to clarify comment

* Fix comment typo
2022-05-23 12:26:53 -04:00
Henry Schreiner
918d4481a4
fix(cmake): support cross-compiles with classic Python (#3959)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-05-20 09:38:29 -04:00
Henry Schreiner
1e4bd22bdc
fix(cmake): support release and debug at the same time (#3948) 2022-05-18 23:19:33 -04:00