From 11de00258ecc13ea99376aa2c299905df1fd3d7b Mon Sep 17 00:00:00 2001
From: Matevz Morato <matevz.morato@gmail.com>
Date: Tue, 18 Jun 2024 18:21:35 +0200
Subject: [PATCH 1/3] Add support for numpy 2.0.0

---
 cmake/Hunter/config.cmake |   8 +--
 src/DeviceBindings.cpp    | 139 +-------------------------------------
 2 files changed, 6 insertions(+), 141 deletions(-)

diff --git a/cmake/Hunter/config.cmake b/cmake/Hunter/config.cmake
index 2d90c72ea..22fb2d494 100644
--- a/cmake/Hunter/config.cmake
+++ b/cmake/Hunter/config.cmake
@@ -1,7 +1,7 @@
-# Pybind11 2.9.2
+# Pybind11 2.12.0
 hunter_config(
     pybind11
-    VERSION "2.9.2"
-    URL "https://github.com/pybind/pybind11/archive/refs/tags/v2.9.2.tar.gz"
-    SHA1 "5e05583a210282c3251281b6ee5677915f0cbf95"
+    VERSION "2.12.0"
+    URL "https://github.com/pybind/pybind11/archive/refs/tags/v2.12.0.tar.gz"
+    SHA1 "e70610cba7b6b7d7a57827d5357c016ad2155c0f"
 )
diff --git a/src/DeviceBindings.cpp b/src/DeviceBindings.cpp
index 3d320fd96..6c27b4d6a 100644
--- a/src/DeviceBindings.cpp
+++ b/src/DeviceBindings.cpp
@@ -20,141 +20,6 @@
 PYBIND11_MAKE_OPAQUE(std::unordered_map<std::int8_t, dai::BoardConfig::GPIO>);
 PYBIND11_MAKE_OPAQUE(std::unordered_map<std::int8_t, dai::BoardConfig::UART>);
 
-// Patch for bind_map naming
-// Remove if it gets mainlined in pybind11
-namespace pybind11 {
-
-template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
-class_<Map, holder_type> bind_map_patched(handle scope, const std::string &name, Args &&...args) {
-    using KeyType = typename Map::key_type;
-    using MappedType = typename Map::mapped_type;
-    using KeysView = detail::keys_view<Map>;
-    using ValuesView = detail::values_view<Map>;
-    using ItemsView = detail::items_view<Map>;
-    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;
-    // otherwise (e.g. both types are either module-local or converting) the map will be
-    // module-local.
-    auto *tinfo = detail::get_type_info(typeid(MappedType));
-    bool local = !tinfo || tinfo->module_local;
-    if (local) {
-        tinfo = detail::get_type_info(typeid(KeyType));
-        local = !tinfo || tinfo->module_local;
-    }
-
-    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
-    class_<KeysView> keys_view(
-        scope, ("KeysView_" + name).c_str(), pybind11::module_local(local));
-    class_<ValuesView> values_view(
-        scope, ("ValuesView_" + name).c_str(), pybind11::module_local(local));
-    class_<ItemsView> items_view(
-        scope, ("ItemsView_" + name).c_str(), pybind11::module_local(local));
-
-    cl.def(init<>());
-
-    // Register stream insertion operator (if possible)
-    detail::map_if_insertion_operator<Map, Class_>(cl, name);
-
-    cl.def(
-        "__bool__",
-        [](const Map &m) -> bool { return !m.empty(); },
-        "Check whether the map is nonempty");
-
-    cl.def(
-        "__iter__",
-        [](Map &m) { return make_key_iterator(m.begin(), m.end()); },
-        keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
-    );
-
-    cl.def(
-        "keys",
-        [](Map &m) { return KeysView{m}; },
-        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
-    );
-
-    cl.def(
-        "values",
-        [](Map &m) { return ValuesView{m}; },
-        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
-    );
-
-    cl.def(
-        "items",
-        [](Map &m) { return ItemsView{m}; },
-        keep_alive<0, 1>() /* Essential: keep map alive while view exists */
-    );
-
-    cl.def(
-        "__getitem__",
-        [](Map &m, const KeyType &k) -> MappedType & {
-            auto it = m.find(k);
-            if (it == m.end()) {
-                throw key_error();
-            }
-            return it->second;
-        },
-        return_value_policy::reference_internal // ref + keepalive
-    );
-
-    cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
-        auto it = m.find(k);
-        if (it == m.end()) {
-            return false;
-        }
-        return true;
-    });
-    // Fallback for when the object is not of the key type
-    cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
-
-    // Assignment provided only if the type is copyable
-    detail::map_assignment<Map, Class_>(cl);
-
-    cl.def("__delitem__", [](Map &m, const KeyType &k) {
-        auto it = m.find(k);
-        if (it == m.end()) {
-            throw key_error();
-        }
-        m.erase(it);
-    });
-
-    cl.def("__len__", &Map::size);
-
-    keys_view.def("__len__", [](KeysView &view) { return view.map.size(); });
-    keys_view.def(
-        "__iter__",
-        [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },
-        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
-    );
-    keys_view.def("__contains__", [](KeysView &view, const KeyType &k) -> bool {
-        auto it = view.map.find(k);
-        if (it == view.map.end()) {
-            return false;
-        }
-        return true;
-    });
-    // Fallback for when the object is not of the key type
-    keys_view.def("__contains__", [](KeysView &, const object &) -> bool { return false; });
-
-    values_view.def("__len__", [](ValuesView &view) { return view.map.size(); });
-    values_view.def(
-        "__iter__",
-        [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },
-        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
-    );
-
-    items_view.def("__len__", [](ItemsView &view) { return view.map.size(); });
-    items_view.def(
-        "__iter__",
-        [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },
-        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
-    );
-
-    return cl;
-}
-
-} // namespace pybind11
-
 
 // Searches for available devices (as Device constructor)
 // but pooling, to check for python interrupts, and releases GIL in between
@@ -351,8 +216,8 @@ void DeviceBindings::bind(pybind11::module& m, void* pCallstack){
     py::class_<PyClock> clock(m, "Clock");
 
 
-    py::bind_map_patched<std::unordered_map<std::int8_t, dai::BoardConfig::GPIO>>(boardConfig, "GPIOMap");
-    py::bind_map_patched<std::unordered_map<std::int8_t, dai::BoardConfig::UART>>(boardConfig, "UARTMap");
+    py::bind_map<std::unordered_map<std::int8_t, dai::BoardConfig::GPIO>>(boardConfig, "GPIOMap");
+    py::bind_map<std::unordered_map<std::int8_t, dai::BoardConfig::UART>>(boardConfig, "UARTMap");
 
 
     // pybind11 limitation of having actual classes as exceptions

From 3185963623c3887846d52988c0c41ce05a804003 Mon Sep 17 00:00:00 2001
From: Matevz Morato <matevz.morato@gmail.com>
Date: Wed, 19 Jun 2024 16:09:12 +0200
Subject: [PATCH 2/3] [Experimental] Remove support for Python 3.6

---
 .github/workflows/main.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d6566a8cd..d3840f361 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -182,7 +182,7 @@ jobs:
     runs-on: windows-latest
     strategy:
       matrix:
-        python-version: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12']
+        python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12']
         python-architecture: [x64, x86]
       fail-fast: false
     steps:
@@ -342,7 +342,7 @@ jobs:
           /opt/python/cp38-cp38/bin/python3.8 setup.py sdist --formats=gztar
           mv dist/* wheelhouse/audited/
       - name: Build wheels
-        run: for PYBIN in /opt/python/cp3{6..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
+        run: for PYBIN in /opt/python/cp3{7..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
       - name: Audit wheels
         run: for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done
       - name: Archive wheel artifacts
@@ -399,7 +399,7 @@ jobs:
         if: startsWith(github.ref, 'refs/tags/v') != true
         run: echo "BUILD_COMMIT_HASH=${{github.sha}}" >> $GITHUB_ENV
       - name: Building wheels
-        run: for PYBIN in /opt/python/cp3{6..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
+        run: for PYBIN in /opt/python/cp3{7..12}*/bin; do "${PYBIN}/pip" wheel . -w ./wheelhouse/ --verbose; done
       - name: Auditing wheels
         run: for whl in wheelhouse/*.whl; do auditwheel repair "$whl" --plat $PLAT -w wheelhouse/audited/; done
       - name: Archive wheel artifacts

From f1f86fd96c9dc589ffc99645ec31200a479a078e Mon Sep 17 00:00:00 2001
From: Matevz Morato <matevz.morato@gmail.com>
Date: Thu, 20 Jun 2024 13:12:32 +0200
Subject: [PATCH 3/3] Remove support for python3.6

---
 setup.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/setup.py b/setup.py
index 4d29979b5..f9ebe5167 100644
--- a/setup.py
+++ b/setup.py
@@ -238,7 +238,6 @@ def build_extension(self, ext):
         "Operating System :: Unix",
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
@@ -250,7 +249,7 @@ def build_extension(self, ext):
         "Topic :: Scientific/Engineering",
         "Topic :: Software Development",
     ],
-    python_requires='>=3.6',
+    python_requires='>=3.7',
     entry_points={
         "console_scripts": [
             f'depthai={DEPTHAI_CLI_MODULE_NAME}.depthai_cli:cli'