Skip to content

Commit

Permalink
Merge branch 'smart_holder' into pywrapcc_merge_sh
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf W. Grosse-Kunstleve committed Jan 17, 2024
2 parents 91a34cb + b8cf161 commit 7e3cab0
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 93 deletions.
6 changes: 5 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
interval: "weekly"
groups:
actions:
patterns:
- "*"
13 changes: 10 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.14

- name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.1
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: x86

Expand Down Expand Up @@ -854,7 +854,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.14

- name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.1
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: x86

Expand Down Expand Up @@ -960,14 +960,21 @@ jobs:
mingw-w64-${{matrix.env}}-gcc
mingw-w64-${{matrix.env}}-python-pip
mingw-w64-${{matrix.env}}-python-numpy
mingw-w64-${{matrix.env}}-python-scipy
mingw-w64-${{matrix.env}}-cmake
mingw-w64-${{matrix.env}}-make
mingw-w64-${{matrix.env}}-python-pytest
mingw-w64-${{matrix.env}}-eigen3
mingw-w64-${{matrix.env}}-boost
mingw-w64-${{matrix.env}}-catch
- uses: msys2/setup-msys2@v2
if: matrix.sys == 'mingw64'
with:
msystem: ${{matrix.sys}}
install: >-
git
mingw-w64-${{matrix.env}}-python-scipy
- uses: actions/checkout@v4

- name: Configure C++11
Expand Down
13 changes: 10 additions & 3 deletions .github/workflows/ci_sh_def.yml
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.14

- name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.1
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: x86

Expand Down Expand Up @@ -878,7 +878,7 @@ jobs:
uses: jwlawson/actions-setup-cmake@v1.14

- name: Prepare MSVC
uses: ilammy/msvc-dev-cmd@v1.12.1
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
arch: x86

Expand Down Expand Up @@ -987,14 +987,21 @@ jobs:
mingw-w64-${{matrix.env}}-gcc
mingw-w64-${{matrix.env}}-python-pip
mingw-w64-${{matrix.env}}-python-numpy
mingw-w64-${{matrix.env}}-python-scipy
mingw-w64-${{matrix.env}}-cmake
mingw-w64-${{matrix.env}}-make
mingw-w64-${{matrix.env}}-python-pytest
mingw-w64-${{matrix.env}}-eigen3
mingw-w64-${{matrix.env}}-boost
mingw-w64-${{matrix.env}}-catch
- uses: msys2/setup-msys2@v2
if: matrix.sys == 'mingw64'
with:
msystem: ${{matrix.sys}}
install: >-
git
mingw-w64-${{matrix.env}}-python-scipy
- uses: actions/checkout@v4

- name: Configure C++11
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/ci_sh_def.yml.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--- ci.yml 2023-12-14 23:14:57.621249678 -0800
+++ ci_sh_def.yml 2023-12-14 23:58:28.144667703 -0800
--- ci.yml 2024-01-16 21:10:28.100295655 -0800
+++ ci_sh_def.yml 2024-01-16 21:10:56.792251785 -0800
@@ -1,4 +1,16 @@
-name: CI
+# PLEASE KEEP THIS GROUP OF FILES IN SYNC AT ALL TIMES:
Expand Down Expand Up @@ -165,47 +165,47 @@
"-DPYBIND11_TEST_OVERRIDE=test_call_policies.cpp;test_gil_scoped.cpp;test_thread.cpp"

- name: Build C++20 - Exercise cmake -DPYBIND11_TEST_OVERRIDE
@@ -976,6 +1003,7 @@
@@ -983,6 +1010,7 @@
run: >-
cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=11 -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
+ -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT"
-S . -B build

- name: Build C++11
@@ -997,6 +1025,7 @@
@@ -1004,6 +1032,7 @@
run: >-
cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=14 -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
+ -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT"
-S . -B build2

- name: Build C++14
@@ -1018,6 +1047,7 @@
@@ -1025,6 +1054,7 @@
run: >-
cmake -G "MinGW Makefiles" -DCMAKE_CXX_STANDARD=17 -DPYBIND11_WERROR=ON -DDOWNLOAD_CATCH=ON
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
+ -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT"
-S . -B build3

- name: Build C++17
@@ -1085,6 +1115,7 @@
@@ -1092,6 +1122,7 @@
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_CXX_STANDARD=17
+ -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT"

- name: Build
run: cmake --build . -j 2
@@ -1150,6 +1181,7 @@
@@ -1157,6 +1188,7 @@
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_CXX_STANDARD=17
+ -DCMAKE_CXX_FLAGS="-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT"
-DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)")

- name: Build
@@ -1173,6 +1205,7 @@
@@ -1180,6 +1212,7 @@
-DDOWNLOAD_EIGEN=ON
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_CXX_STANDARD=17
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ repos:

# Ruff, the Python auto-correcting linter/formatter written in Rust
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.6
rev: v0.1.9
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
- id: ruff-format

# Check static types with mypy
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.7.1"
rev: "v1.8.0"
hooks:
- id: mypy
args: []
Expand Down Expand Up @@ -144,7 +144,7 @@ repos:

# PyLint has native support - not always usable, but works for us
- repo: https://github.com/PyCQA/pylint
rev: "v3.0.1"
rev: "v3.0.3"
hooks:
- id: pylint
files: ^pybind11
4 changes: 2 additions & 2 deletions include/pybind11/stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ struct list_caster {
auto s = reinterpret_borrow<sequence>(seq);
value.clear();
reserve_maybe(s, &value);
for (auto it : seq) {
for (const auto &it : seq) {
value_conv conv;
if (!conv.load(it, convert)) {
return false;
Expand Down Expand Up @@ -375,7 +375,7 @@ struct array_caster {
return false;
}
size_t ctr = 0;
for (auto it : l) {
for (const auto &it : l) {
value_conv conv;
if (!conv.load(it, convert)) {
return false;
Expand Down
79 changes: 25 additions & 54 deletions include/pybind11/stl_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,49 +645,50 @@ auto map_if_insertion_operator(Class_ &cl, std::string const &name)
"Return the canonical string representation of this map.");
}

template <typename KeyType>
struct keys_view {
virtual size_t len() = 0;
virtual iterator iter() = 0;
virtual bool contains(const KeyType &k) = 0;
virtual bool contains(const object &k) = 0;
virtual bool contains(const handle &k) = 0;
virtual ~keys_view() = default;
};

template <typename MappedType>
struct values_view {
virtual size_t len() = 0;
virtual iterator iter() = 0;
virtual ~values_view() = default;
};

template <typename KeyType, typename MappedType>
struct items_view {
virtual size_t len() = 0;
virtual iterator iter() = 0;
virtual ~items_view() = default;
};

template <typename Map, typename KeysView>
struct KeysViewImpl : public KeysView {
template <typename Map>
struct KeysViewImpl : public detail::keys_view {
explicit KeysViewImpl(Map &map) : map(map) {}
size_t len() override { return map.size(); }
iterator iter() override { return make_key_iterator(map.begin(), map.end()); }
bool contains(const typename Map::key_type &k) override { return map.find(k) != map.end(); }
bool contains(const object &) override { return false; }
bool contains(const handle &k) override {
try {
return map.find(k.template cast<typename Map::key_type>()) != map.end();
} catch (const cast_error &) {
return false;
}
}
Map &map;
};

template <typename Map, typename ValuesView>
struct ValuesViewImpl : public ValuesView {
template <typename Map>
struct ValuesViewImpl : public detail::values_view {
explicit ValuesViewImpl(Map &map) : map(map) {}
size_t len() override { return map.size(); }
iterator iter() override { return make_value_iterator(map.begin(), map.end()); }
Map &map;
};

template <typename Map, typename ItemsView>
struct ItemsViewImpl : public ItemsView {
template <typename Map>
struct ItemsViewImpl : public detail::items_view {
explicit ItemsViewImpl(Map &map) : map(map) {}
size_t len() override { return map.size(); }
iterator iter() override { return make_iterator(map.begin(), map.end()); }
Expand All @@ -700,11 +701,9 @@ template <typename Map, typename holder_type = default_holder_type<Map>, typenam
class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
using KeyType = typename Map::key_type;
using MappedType = typename Map::mapped_type;
using StrippedKeyType = detail::remove_cvref_t<KeyType>;
using StrippedMappedType = detail::remove_cvref_t<MappedType>;
using KeysView = detail::keys_view<StrippedKeyType>;
using ValuesView = detail::values_view<StrippedMappedType>;
using ItemsView = detail::items_view<StrippedKeyType, StrippedMappedType>;
using KeysView = detail::keys_view;
using ValuesView = detail::values_view;
using ItemsView = detail::items_view;
using Class_ = class_<Map, holder_type>;

// If either type is a non-module-local bound type then make the map binding non-local as well;
Expand All @@ -718,39 +717,20 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
}

Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
static constexpr auto key_type_descr = detail::make_caster<KeyType>::name;
static constexpr auto mapped_type_descr = detail::make_caster<MappedType>::name;
std::string key_type_name(key_type_descr.text), mapped_type_name(mapped_type_descr.text);

// If key type isn't properly wrapped, fall back to C++ names
if (key_type_name == "%") {
key_type_name = detail::type_info_description(typeid(KeyType));
}
// Similarly for value type:
if (mapped_type_name == "%") {
mapped_type_name = detail::type_info_description(typeid(MappedType));
}

// Wrap KeysView[KeyType] if it wasn't already wrapped
// Wrap KeysView if it wasn't already wrapped
if (!detail::get_type_info(typeid(KeysView))) {
class_<KeysView> keys_view(
scope, ("KeysView[" + key_type_name + "]").c_str(), pybind11::module_local(local));
class_<KeysView> keys_view(scope, "KeysView", pybind11::module_local(local));
keys_view.def("__len__", &KeysView::len);
keys_view.def("__iter__",
&KeysView::iter,
keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
);
keys_view.def("__contains__",
static_cast<bool (KeysView::*)(const KeyType &)>(&KeysView::contains));
// Fallback for when the object is not of the key type
keys_view.def("__contains__",
static_cast<bool (KeysView::*)(const object &)>(&KeysView::contains));
keys_view.def("__contains__", &KeysView::contains);
}
// Similarly for ValuesView:
if (!detail::get_type_info(typeid(ValuesView))) {
class_<ValuesView> values_view(scope,
("ValuesView[" + mapped_type_name + "]").c_str(),
pybind11::module_local(local));
class_<ValuesView> values_view(scope, "ValuesView", pybind11::module_local(local));
values_view.def("__len__", &ValuesView::len);
values_view.def("__iter__",
&ValuesView::iter,
Expand All @@ -759,10 +739,7 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&
}
// Similarly for ItemsView:
if (!detail::get_type_info(typeid(ItemsView))) {
class_<ItemsView> items_view(
scope,
("ItemsView[" + key_type_name + ", ").append(mapped_type_name + "]").c_str(),
pybind11::module_local(local));
class_<ItemsView> items_view(scope, "ItemsView", pybind11::module_local(local));
items_view.def("__len__", &ItemsView::len);
items_view.def("__iter__",
&ItemsView::iter,
Expand All @@ -788,25 +765,19 @@ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&

cl.def(
"keys",
[](Map &m) {
return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map, KeysView>(m));
},
[](Map &m) { return std::unique_ptr<KeysView>(new detail::KeysViewImpl<Map>(m)); },
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
);

cl.def(
"values",
[](Map &m) {
return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map, ValuesView>(m));
},
[](Map &m) { return std::unique_ptr<ValuesView>(new detail::ValuesViewImpl<Map>(m)); },
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
);

cl.def(
"items",
[](Map &m) {
return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map, ItemsView>(m));
},
[](Map &m) { return std::unique_ptr<ItemsView>(new detail::ItemsViewImpl<Map>(m)); },
keep_alive<0, 1>() /* Essential: keep map alive while view exists */
);

Expand Down
Loading

0 comments on commit 7e3cab0

Please sign in to comment.