From 06a61b069c2c741b7401063e19b7d0758b8df9a8 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Sun, 2 Oct 2022 12:45:56 -0500
Subject: [PATCH] Changes towards nanobind compatiblity that also work for
 pybind11

---
 pyopencl/invoker.py    |  2 +-
 src/tools.hpp          |  2 +-
 src/wrap_cl.cpp        |  8 ++--
 src/wrap_cl.hpp        | 87 ++++++++++++++++++++++--------------------
 src/wrap_cl_part_1.cpp | 44 ++++++++++-----------
 src/wrap_cl_part_2.cpp | 51 ++++++++++++-------------
 src/wrap_constants.cpp |  4 +-
 src/wrap_helpers.hpp   | 30 +++++++++------
 src/wrap_mempool.cpp   |  2 +-
 9 files changed, 119 insertions(+), 111 deletions(-)

diff --git a/pyopencl/invoker.py b/pyopencl/invoker.py
index 5b585bbf..1f6a155b 100644
--- a/pyopencl/invoker.py
+++ b/pyopencl/invoker.py
@@ -263,7 +263,7 @@ def _generate_enqueue_and_set_args_module(function_name,
                     ["self", "queue", "global_size", "local_size"]
                     + arg_names
                     + ["global_offset=None",
-                        "g_times_l=None",
+                        "g_times_l=False",
                         "allow_empty_ndrange=False",
                         "wait_for=None"])))
 
diff --git a/src/tools.hpp b/src/tools.hpp
index f64f443f..f8d01959 100644
--- a/src/tools.hpp
+++ b/src/tools.hpp
@@ -53,7 +53,7 @@ namespace pyopencl
   {
     namespace py = pybind11;
 
-    py::module::import("gc").attr("collect")();
+    py::module_::import("gc").attr("collect")();
   }
 
 
diff --git a/src/wrap_cl.cpp b/src/wrap_cl.cpp
index 50a48201..9a012524 100644
--- a/src/wrap_cl.cpp
+++ b/src/wrap_cl.cpp
@@ -36,10 +36,10 @@ using namespace pyopencl;
 
 
 
-extern void pyopencl_expose_constants(py::module &m);
-extern void pyopencl_expose_part_1(py::module &m);
-extern void pyopencl_expose_part_2(py::module &m);
-extern void pyopencl_expose_mempool(py::module &m);
+extern void pyopencl_expose_constants(py::module_ &m);
+extern void pyopencl_expose_part_1(py::module_ &m);
+extern void pyopencl_expose_part_2(py::module_ &m);
+extern void pyopencl_expose_mempool(py::module_ &m);
 
 static bool import_numpy_helper()
 {
diff --git a/src/wrap_cl.hpp b/src/wrap_cl.hpp
index 413b8452..482b5170 100644
--- a/src/wrap_cl.hpp
+++ b/src/wrap_cl.hpp
@@ -198,7 +198,7 @@
     { \
       for (py::handle py_dev: py_devices) \
         devices_vec.push_back( \
-            (py_dev).cast<device &>().data()); \
+            py::cast<device &>(py_dev).data()); \
       num_devices = devices_vec.size(); \
       devices = devices_vec.empty( ) ? nullptr : &devices_vec.front(); \
     } \
@@ -402,7 +402,7 @@
     { \
       for (py::handle evt: py_wait_for) \
       { \
-        event_wait_list.push_back(evt.cast<const event &>().data()); \
+        event_wait_list.push_back(py::cast<const event &>(evt).data()); \
         ++num_events_in_wait_list; \
       } \
     }
@@ -454,6 +454,7 @@ namespace pyopencl
   class command_queue;
 
   // {{{ error
+
   class error : public std::runtime_error
   {
     private:
@@ -1278,25 +1279,25 @@ namespace pyopencl
     {
       for (py::handle prop_tuple_py: py_properties)
       {
-        py::tuple prop_tuple(prop_tuple_py.cast<py::tuple>());
+        py::tuple prop_tuple(py::cast<py::tuple>(prop_tuple_py));
 
         if (len(prop_tuple) != 2)
           throw error("Context", CL_INVALID_VALUE, "property tuple must have length 2");
-        cl_context_properties prop = prop_tuple[0].cast<cl_context_properties>();
+        cl_context_properties prop = py::cast<cl_context_properties>(prop_tuple[0]);
         props.push_back(prop);
 
         if (prop == CL_CONTEXT_PLATFORM)
         {
           props.push_back(
               reinterpret_cast<cl_context_properties>(
-                prop_tuple[1].cast<const platform &>().data()));
+                py::cast<const platform &>(prop_tuple[1]).data()));
         }
 #if defined(PYOPENCL_GL_SHARING_VERSION) && (PYOPENCL_GL_SHARING_VERSION >= 1)
 #if defined(_WIN32)
        else if (prop == CL_WGL_HDC_KHR)
        {
          // size_t is a stand-in for HANDLE, hopefully has the same size.
-         size_t hnd = (prop_tuple[1]).cast<size_t>();
+         size_t hnd = py::cast<size_t>(prop_tuple[1]);
          props.push_back(hnd);
        }
 #endif
@@ -1311,10 +1312,10 @@ namespace pyopencl
 #endif
            )
        {
-          py::object ctypes = py::module::import("ctypes");
+          py::object ctypes = py::module_::import("ctypes");
           py::object prop = prop_tuple[1], c_void_p = ctypes.attr("c_void_p");
           py::object ptr = ctypes.attr("cast")(prop, c_void_p);
-          props.push_back(ptr.attr("value").cast<cl_context_properties>());
+          props.push_back(py::cast<cl_context_properties>(ptr.attr("value")));
        }
 #endif
         else
@@ -1350,7 +1351,7 @@ namespace pyopencl
 
       std::vector<cl_device_id> devices;
       for (py::handle py_dev: py_devices)
-        devices.push_back(py_dev.cast<const device &>().data());
+        devices.push_back(py::cast<const device &>(py_dev).data());
 
       PYOPENCL_PRINT_CALL_TRACE("clCreateContext");
       ctx = clCreateContext(
@@ -1364,7 +1365,7 @@ namespace pyopencl
     {
       cl_device_type dev_type = CL_DEVICE_TYPE_DEFAULT;
       if (py_dev_type.ptr() != Py_None)
-        dev_type = py_dev_type.cast<cl_device_type>();
+        dev_type = py::cast<cl_device_type>(py_dev_type);
 
       PYOPENCL_PRINT_CALL_TRACE("clCreateContextFromType");
       ctx = clCreateContextFromType(props_ptr, dev_type, 0, 0, &status_code);
@@ -2029,8 +2030,7 @@ namespace pyopencl
     std::vector<cl_event> event_wait_list(len(events));
 
     for (py::handle evt: events)
-      event_wait_list[num_events_in_wait_list++] =
-        evt.cast<event &>().data();
+      event_wait_list[num_events_in_wait_list++] = py::cast<event &>(evt).data();
 
     PYOPENCL_CALL_GUARDED_THREADED(clWaitForEvents, (
           PYOPENCL_WAITLIST_ARGS));
@@ -2088,7 +2088,7 @@ namespace pyopencl
     std::vector<cl_event> event_list(len(py_events));
 
     for (py::handle py_evt: py_events)
-      event_list[num_events++] = py_evt.cast<event &>().data();
+      event_list[num_events++] = py::cast<event &>(py_evt).data();
 
     PYOPENCL_CALL_GUARDED(clEnqueueWaitForEvents, (
           cq.data(), num_events, event_list.empty( ) ? nullptr : &event_list.front()));
@@ -2195,12 +2195,15 @@ namespace pyopencl
       }
 
       memory_object(memory_object &src)
-        : m_valid(true), m_mem(src.m_mem),
-        m_hostbuf(std::move(src.m_hostbuf))
+      : m_valid(true), m_mem(src.m_mem)
       {
         PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem));
       }
 
+      memory_object(memory_object &&src)
+      : m_valid(true), m_mem(src.m_mem), m_hostbuf(std::move(src.m_hostbuf))
+      { }
+
       memory_object(memory_object_holder const &src)
         : m_valid(true), m_mem(src.data())
       {
@@ -2247,7 +2250,7 @@ namespace pyopencl
 
     std::vector<cl_mem> mem_objects;
     for (py::handle mo: py_mem_objects)
-      mem_objects.push_back(mo.cast<const memory_object &>().data());
+      mem_objects.push_back(py::cast<const memory_object &>(mo).data());
 
     cl_event evt;
     PYOPENCL_RETRY_IF_MEM_ERROR(
@@ -2938,8 +2941,8 @@ namespace pyopencl
     cl_mem mem;
     if (dims == 2)
     {
-      size_t width = (shape[0]).cast<size_t>();
-      size_t height = (shape[1]).cast<size_t>();
+      size_t width = py::cast<size_t>(shape[0]);
+      size_t height = py::cast<size_t>(shape[1]);
 
       size_t pitch = 0;
       if (pitches.ptr() != Py_None)
@@ -2947,7 +2950,7 @@ namespace pyopencl
         if (py::len(pitches) != 1)
           throw pyopencl::error("Image", CL_INVALID_VALUE,
               "invalid length of pitch tuple");
-        pitch = (pitches[0]).cast<size_t>();
+        pitch = py::cast<size_t>(pitches[0]);
       }
 
       // check buffer size
@@ -2968,9 +2971,9 @@ namespace pyopencl
     }
     else if (dims == 3)
     {
-      size_t width = (shape[0]).cast<size_t>();
-      size_t height = (shape[1]).cast<size_t>();
-      size_t depth = (shape[2]).cast<size_t>();
+      size_t width = py::cast<size_t>(shape[0]);
+      size_t height = py::cast<size_t>(shape[1]);
+      size_t depth = py::cast<size_t>(shape[2]);
 
       size_t pitch_x = 0;
       size_t pitch_y = 0;
@@ -2981,8 +2984,8 @@ namespace pyopencl
           throw pyopencl::error("Image", CL_INVALID_VALUE,
               "invalid length of pitch tuple");
 
-        pitch_x = (pitches[0]).cast<size_t>();
-        pitch_y = (pitches[1]).cast<size_t>();
+        pitch_x = py::cast<size_t>(pitches[0]);
+        pitch_y = py::cast<size_t>(pitches[1]);
       }
 
       // check buffer size
@@ -3851,7 +3854,7 @@ namespace pyopencl
 
     if (!byte_count_py.is_none())
     {
-      size_t byte_count = byte_count_py.cast<size_t>();
+      size_t byte_count = py::cast<size_t>(byte_count_py);
       if (have_size && byte_count > size)
         throw error("_enqueue_svm_memcpy", CL_INVALID_VALUE,
             "specified byte_count larger than size of source or destination buffers");
@@ -4414,8 +4417,8 @@ namespace pyopencl
           if (py::len(name_hdr_tup) != 2)
             throw error("Program.compile", CL_INVALID_VALUE,
                 "epxected (name, header) tuple in headers list");
-          std::string name = (name_hdr_tup[0]).cast<std::string>();
-          program &prg = (name_hdr_tup[1]).cast<program &>();
+          std::string name = py::cast<std::string>(name_hdr_tup[0]);
+          program &prg = py::cast<program &>(name_hdr_tup[1]);
 
           header_names.push_back(name);
           programs.push_back(prg.data());
@@ -4497,8 +4500,7 @@ namespace pyopencl
 
     for (size_t i = 0; i < num_devices; ++i)
     {
-      devices.push_back(
-          (py_devices[i]).cast<device const &>().data());
+      devices.push_back(py::cast<device const &>(py_devices[i]).data());
       const void *buf;
       PYOPENCL_BUFFER_SIZE_T len;
 
@@ -4620,7 +4622,7 @@ namespace pyopencl
     std::vector<cl_program> programs;
     for (py::handle py_prg: py_programs)
     {
-      program &prg = (py_prg).cast<program &>();
+      program &prg = py::cast<program &>(py_prg);
       programs.push_back(prg.data());
     }
 
@@ -4859,7 +4861,7 @@ namespace pyopencl
 #if PYOPENCL_CL_VERSION >= 0x2000
           try
           {
-            set_arg_svm(arg_index, arg.cast<svm_pointer const &>());
+            set_arg_svm(arg_index, py::cast<svm_pointer const &>(arg));
             return;
           }
           catch (py::cast_error &) { }
@@ -4867,7 +4869,7 @@ namespace pyopencl
 
           try
           {
-            set_arg_mem(arg_index, arg.cast<memory_object_holder &>());
+            set_arg_mem(arg_index, py::cast<memory_object_holder &>(arg));
             m_set_arg_prefer_svm = false;
             return;
           }
@@ -4877,7 +4879,7 @@ namespace pyopencl
         {
           try
           {
-            set_arg_mem(arg_index, arg.cast<memory_object_holder &>());
+            set_arg_mem(arg_index, py::cast<memory_object_holder &>(arg));
             return;
           }
           catch (py::cast_error &) { }
@@ -4885,7 +4887,7 @@ namespace pyopencl
 #if PYOPENCL_CL_VERSION >= 0x2000
           try
           {
-            set_arg_svm(arg_index, arg.cast<svm_pointer const &>());
+            set_arg_svm(arg_index, py::cast<svm_pointer const &>(arg));
             m_set_arg_prefer_svm = true;
             return;
           }
@@ -4895,21 +4897,21 @@ namespace pyopencl
 
         try
         {
-          set_arg_local(arg_index, arg.cast<local_memory>());
+          set_arg_local(arg_index, py::cast<local_memory>(arg));
           return;
         }
         catch (py::cast_error &) { }
 
         try
         {
-          set_arg_sampler(arg_index, arg.cast<const sampler &>());
+          set_arg_sampler(arg_index, py::cast<const sampler &>(arg));
           return;
         }
         catch (py::cast_error &) { }
 
         try
         {
-          set_arg_command_queue(arg_index, arg.cast<const command_queue &>());
+          set_arg_command_queue(arg_index, py::cast<const command_queue &>(arg));
           return;
         }
         catch (py::cast_error &) { }
@@ -5087,7 +5089,8 @@ namespace pyopencl
       std::string msg( \
           std::string("when processing arg#") + std::to_string(arg_index+1) \
           + std::string(" (1-based): ") + std::string(err.what())); \
-      auto mod_cl_ary(py::module::import("pyopencl.array")); \
+      \
+      auto mod_cl_ary(py::module_::import("pyopencl.array")); \
       auto cls_array(mod_cl_ary.attr("Array")); \
       if (arg_value.ptr() && py::isinstance(arg_value, cls_array)) \
         msg.append( \
@@ -5454,7 +5457,7 @@ namespace pyopencl
     \
     std::vector<cl_mem> mem_objects; \
     for (py::handle mo: py_mem_objects) \
-      mem_objects.push_back((mo).cast<memory_object_holder &>().data()); \
+      mem_objects.push_back(py::cast<memory_object_holder &>(mo).data()); \
     \
     cl_event evt; \
     PYOPENCL_CALL_GUARDED(clEnqueue##What##GLObjects, ( \
@@ -5496,7 +5499,7 @@ namespace pyopencl
 #if PYOPENCL_CL_VERSION >= 0x1020
     if (py_platform.ptr() != Py_None)
     {
-      platform &plat = (py_platform).cast<platform &>();
+      platform &plat = py::cast<platform &>(py_platform);
 
       func_ptr = (func_ptr_type) clGetExtensionFunctionAddressForPlatform(
             plat.data(), "clGetGLContextInfoKHR");
@@ -5687,7 +5690,7 @@ namespace pyopencl
       py::object order_py)
   {
     memory_object_holder const &mem_obj =
-      (mem_obj_py).cast<memory_object_holder const &>();
+      py::cast<memory_object_holder const &>(mem_obj_py);
     PyArray_Descr *tp_descr;
     if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED)
       throw py::error_already_set();
@@ -5707,7 +5710,7 @@ namespace pyopencl
     catch (py::cast_error &)
     {
       for (auto it: shape)
-        dims.push_back(it.cast<npy_intp>());
+        dims.push_back(py::cast<npy_intp>(it));
     }
 
     NPY_ORDER order = PyArray_CORDER;
diff --git a/src/wrap_cl_part_1.cpp b/src/wrap_cl_part_1.cpp
index 3b9f79ed..3d123b6e 100644
--- a/src/wrap_cl_part_1.cpp
+++ b/src/wrap_cl_part_1.cpp
@@ -33,7 +33,7 @@
 using namespace pyopencl;
 
 
-void pyopencl_expose_part_1(py::module &m)
+void pyopencl_expose_part_1(py::module_ &m)
 {
   m.def("get_cl_header_version", get_cl_header_version);
   m.def("_sizeof_size_t", [](){ return sizeof(size_t); });
@@ -94,9 +94,9 @@ void pyopencl_expose_part_1(py::module &m)
                     py_dev_type);
               )
             }),
-          py::arg("devices")=py::none(),
-          py::arg("properties")=py::none(),
-          py::arg("dev_type")=py::none()
+          py::arg("devices").none(true)=py::none(),
+          py::arg("properties").none(true)=py::none(),
+          py::arg("dev_type").none(true)=py::none()
           )
       .DEF_SIMPLE_METHOD(get_info)
       .def(py::self == py::self)
@@ -163,18 +163,18 @@ void pyopencl_expose_part_1(py::module &m)
 
 #if PYOPENCL_CL_VERSION >= 0x1020
   m.def("_enqueue_marker_with_wait_list", enqueue_marker_with_wait_list,
-      py::arg("queue"), py::arg("wait_for")=py::none()
+      py::arg("queue"), py::arg("wait_for").none(true)=py::none()
       );
 #endif
   m.def("_enqueue_marker", enqueue_marker,
       py::arg("queue")
       );
   m.def("_enqueue_wait_for_events", enqueue_wait_for_events,
-      py::arg("queue"), py::arg("wait_for")=py::none());
+      py::arg("queue"), py::arg("wait_for").none(true)=py::none());
 
 #if PYOPENCL_CL_VERSION >= 0x1020
   m.def("_enqueue_barrier_with_wait_list", enqueue_barrier_with_wait_list,
-      py::arg("queue"), py::arg("wait_for")=py::none()
+      py::arg("queue"), py::arg("wait_for").none(true)=py::none()
       );
 #endif
   m.def("_enqueue_barrier", enqueue_barrier, py::arg("queue"));
@@ -246,7 +246,7 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("queue"),
       py::arg("mem_objects"),
       py::arg("flags")=0,
-      py::arg("wait_for")=py::none()
+      py::arg("wait_for").none(true)=py::none()
       );
 #endif
 
@@ -264,7 +264,7 @@ void pyopencl_expose_part_1(py::module &m)
           py::arg("context"),
           py::arg("flags"),
           py::arg("size")=0,
-          py::arg("hostbuf")=py::none()
+          py::arg("hostbuf").none(true)=py::none()
           )
 #if PYOPENCL_CL_VERSION >= 0x1010
       .def("get_sub_region", &cls::get_sub_region,
@@ -288,7 +288,7 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("mem"),
       py::arg("hostbuf"),
       py::arg("src_offset")=0,
-      py::arg("wait_for")=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true
       );
   m.def("_enqueue_write_buffer", enqueue_write_buffer,
@@ -296,7 +296,7 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("mem"),
       py::arg("hostbuf"),
       py::arg("dst_offset")=0,
-      py::arg("wait_for")=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true
       );
   m.def("_enqueue_copy_buffer", enqueue_copy_buffer,
@@ -306,7 +306,7 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("byte_count")=-1,
       py::arg("src_offset")=0,
       py::arg("dst_offset")=0,
-      py::arg("wait_for")=py::none()
+      py::arg("wait_for").none(true)=py::none()
       );
 
   // }}}
@@ -321,9 +321,9 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("buffer_origin"),
       py::arg("host_origin"),
       py::arg("region"),
-      py::arg("buffer_pitches")=py::none(),
-      py::arg("host_pitches")=py::none(),
-      py::arg("wait_for")=py::none(),
+      py::arg("buffer_pitches").none(true)=py::none(),
+      py::arg("host_pitches").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true
       );
   m.def("_enqueue_write_buffer_rect", enqueue_write_buffer_rect,
@@ -333,9 +333,9 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("buffer_origin"),
       py::arg("host_origin"),
       py::arg("region"),
-      py::arg("buffer_pitches")=py::none(),
-      py::arg("host_pitches")=py::none(),
-      py::arg("wait_for")=py::none(),
+      py::arg("buffer_pitches").none(true)=py::none(),
+      py::arg("host_pitches").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true
       );
   m.def("_enqueue_copy_buffer_rect", enqueue_copy_buffer_rect,
@@ -345,9 +345,9 @@ void pyopencl_expose_part_1(py::module &m)
       py::arg("src_origin"),
       py::arg("dst_origin"),
       py::arg("region"),
-      py::arg("src_pitches")=py::none(),
-      py::arg("dst_pitches")=py::none(),
-      py::arg("wait_for")=py::none()
+      py::arg("src_pitches").none(true)=py::none(),
+      py::arg("dst_pitches").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none()
       );
 #endif
 
@@ -359,7 +359,7 @@ void pyopencl_expose_part_1(py::module &m)
   m.def("_enqueue_fill_buffer", enqueue_fill_buffer,
       py::arg("queue"), py::arg("mem"), py::arg("pattern"),
       py::arg("offset"), py::arg("size"),
-      py::arg("wait_for")=py::none());
+      py::arg("wait_for").none(true)=py::none());
 #endif
 }
 
diff --git a/src/wrap_cl_part_2.cpp b/src/wrap_cl_part_2.cpp
index 80560bd7..769840e9 100644
--- a/src/wrap_cl_part_2.cpp
+++ b/src/wrap_cl_part_2.cpp
@@ -91,7 +91,7 @@ using namespace pyopencl;
 
 
 
-void pyopencl_expose_part_2(py::module &m)
+void pyopencl_expose_part_2(py::module_ &m)
 {
   // {{{ image
 
@@ -275,7 +275,7 @@ void pyopencl_expose_part_2(py::module &m)
     py::class_<cls>(m, "MemoryMap", py::dynamic_attr())
       .def("release", &cls::release,
           py::arg("queue").none(true)=nullptr,
-          py::arg("wait_for")=py::none()
+          py::arg("wait_for").none(true)=py::none()
           )
       ;
   }
@@ -290,8 +290,8 @@ void pyopencl_expose_part_2(py::module &m)
       py::arg("shape"),
       py::arg("dtype"),
       py::arg("order")="C",
-      py::arg("strides")=py::none(),
-      py::arg("wait_for")=py::none(),
+      py::arg("strides").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true);
   m.def("enqueue_map_image", enqueue_map_image,
       py::arg("queue"),
@@ -302,8 +302,8 @@ void pyopencl_expose_part_2(py::module &m)
       py::arg("shape"),
       py::arg("dtype"),
       py::arg("order")="C",
-      py::arg("strides")=py::none(),
-      py::arg("wait_for")=py::none(),
+      py::arg("strides").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("is_blocking")=true);
 #endif
 
@@ -431,16 +431,16 @@ void pyopencl_expose_part_2(py::module &m)
       py::arg("is_blocking"),
       py::arg("dst"),
       py::arg("src"),
-      py::arg("wait_for")=py::none(),
-      py::arg("byte_count")=py::none()
+      py::arg("wait_for").none(true)=py::none(),
+      py::arg("byte_count").none(true)=py::none()
       );
 
   m.def("_enqueue_svm_memfill", enqueue_svm_memfill,
       py::arg("queue"),
       py::arg("dst"),
       py::arg("pattern"),
-      py::arg("byte_count")=py::none(),
-      py::arg("wait_for")=py::none()
+      py::arg("byte_count").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none()
       );
 
   m.def("_enqueue_svm_map", enqueue_svm_map,
@@ -448,14 +448,14 @@ void pyopencl_expose_part_2(py::module &m)
       py::arg("is_blocking"),
       py::arg("flags"),
       py::arg("svm"),
-      py::arg("wait_for")=py::none(),
-      py::arg("size")=py::none()
+      py::arg("wait_for").none(true)=py::none(),
+      py::arg("size").none(true)=py::none()
       );
 
   m.def("_enqueue_svm_unmap", enqueue_svm_unmap,
       py::arg("queue"),
       py::arg("svm"),
-      py::arg("wait_for")=py::none()
+      py::arg("wait_for").none(true)=py::none()
       );
 #endif
 
@@ -463,8 +463,8 @@ void pyopencl_expose_part_2(py::module &m)
   m.def("_enqueue_svm_migrate_mem", enqueue_svm_migratemem,
       py::arg("queue"),
       py::arg("svms"),
-      py::arg("flags")=py::none(),
-      py::arg("wait_for")=py::none()
+      py::arg("flags").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none()
       );
 #endif
 
@@ -529,17 +529,17 @@ void pyopencl_expose_part_2(py::module &m)
       .DEF_SIMPLE_METHOD(get_build_info)
       .def("_build", &cls::build,
           py::arg("options")="",
-          py::arg("devices")=py::none())
+          py::arg("devices").none(true)=py::none())
 #if PYOPENCL_CL_VERSION >= 0x1020
       .def("compile", &cls::compile,
           py::arg("options")="",
-          py::arg("devices")=py::none(),
+          py::arg("devices").none(true)=py::none(),
           py::arg("headers")=py::list())
       .def_static("link", &link_program,
           py::arg("context"),
           py::arg("programs"),
           py::arg("options")="",
-          py::arg("devices")=py::none()
+          py::arg("devices").none(true)=py::none()
           )
 #endif
 #if PYOPENCL_CL_VERSION >= 0x2020
@@ -615,7 +615,7 @@ void pyopencl_expose_part_2(py::module &m)
       .def("get_sub_group_info", &cls::get_sub_group_info,
           py::arg("device"),
           py::arg("param"),
-          py::arg("input_value")=py::none()
+          py::arg("input_value").none(true)=py::none()
           )
 #endif
       ;
@@ -631,14 +631,13 @@ void pyopencl_expose_part_2(py::module &m)
       ;
   }
 
-
   m.def("enqueue_nd_range_kernel", enqueue_nd_range_kernel,
       py::arg("queue"),
       py::arg("kernel"),
       py::arg("global_work_size"),
-      py::arg("local_work_size"),
-      py::arg("global_work_offset")=py::none(),
-      py::arg("wait_for")=py::none(),
+      py::arg("local_work_size").none(true),
+      py::arg("global_work_offset").none(true)=py::none(),
+      py::arg("wait_for").none(true)=py::none(),
       py::arg("g_times_l")=false,
       py::arg("allow_empty_ndrange")=false
       );
@@ -711,19 +710,19 @@ void pyopencl_expose_part_2(py::module &m)
   m.def("enqueue_acquire_gl_objects", enqueue_acquire_gl_objects,
       py::arg("queue"),
       py::arg("mem_objects"),
-      py::arg("wait_for")=py::none()
+      py::arg("wait_for").none(true)=py::none()
       );
   m.def("enqueue_release_gl_objects", enqueue_release_gl_objects,
       py::arg("queue"),
       py::arg("mem_objects"),
-      py::arg("wait_for")=py::none()
+      py::arg("wait_for").none(true)=py::none()
       );
 
 #if defined(cl_khr_gl_sharing) && (cl_khr_gl_sharing >= 1)
   m.def("get_gl_context_info_khr", get_gl_context_info_khr,
       py::arg("properties"),
       py::arg("param_name"),
-      py::arg("platform")=py::none()
+      py::arg("platform").none(true)=py::none()
       );
 #endif
 
diff --git a/src/wrap_constants.cpp b/src/wrap_constants.cpp
index e313a340..2c06f2f5 100644
--- a/src/wrap_constants.cpp
+++ b/src/wrap_constants.cpp
@@ -99,14 +99,14 @@ namespace
 }
 
 
-void pyopencl_expose_constants(py::module &m)
+void pyopencl_expose_constants(py::module_ &m)
 {
   // {{{ exceptions
   {
 #define DECLARE_EXC(NAME, BASE) \
   static py::exception<pyopencl::error> CL##NAME(m, #NAME, BASE);
 
-    DECLARE_EXC(Error, nullptr);
+    DECLARE_EXC(Error, PyExc_Exception);
     DECLARE_EXC(MemoryError, CLError.ptr());
     DECLARE_EXC(LogicError, CLError.ptr());
     DECLARE_EXC(RuntimeError, CLError.ptr());
diff --git a/src/wrap_helpers.hpp b/src/wrap_helpers.hpp
index cabc012d..84e1fbd6 100644
--- a/src/wrap_helpers.hpp
+++ b/src/wrap_helpers.hpp
@@ -65,10 +65,14 @@ namespace py = pybind11;
 #define DEF_SIMPLE_RW_MEMBER(NAME) \
   def_readwrite(#NAME, &cls::m_##NAME)
 
+// }}}
+
+// {{{ COPY_PY_XXX
+
 #define COPY_PY_LIST(TYPE, NAME) \
   { \
     for (auto it: py_##NAME) \
-      NAME.push_back(it.cast<TYPE>()); \
+      NAME.push_back(py::cast<TYPE>(it)); \
   }
 
 #define COPY_PY_ARRAY(FUNC_NAME, TYPE, NAME, COUNTER) \
@@ -79,44 +83,46 @@ namespace py = pybind11;
       if (COUNTER == NAME.size()) \
         throw error(FUNC_NAME, \
             CL_INVALID_VALUE, "too many entries in " #NAME " argument"); \
-      NAME[COUNTER++] = it.cast<TYPE>(); \
+      NAME[COUNTER++] = py::cast<TYPE>(it); \
     } \
   }
 
 #define COPY_PY_COORD_TRIPLE(NAME) \
   size_t NAME[3] = {0, 0, 0}; \
   { \
-    py::tuple py_tup_##NAME = py_##NAME; \
-    size_t my_len = len(py_tup_##NAME); \
+    py::sequence py_seq_##NAME = py::cast<py::sequence>(py_##NAME); \
+    size_t my_len = len(py_seq_##NAME); \
     if (my_len > 3) \
       throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
     for (size_t i = 0; i < my_len; ++i) \
-      NAME[i] = py_tup_##NAME[i].cast<size_t>(); \
+      NAME[i] = py::cast<size_t>(py_seq_##NAME[i]); \
   }
 
 #define COPY_PY_PITCH_TUPLE(NAME) \
   size_t NAME[2] = {0, 0}; \
   if (py_##NAME.ptr() != Py_None) \
   { \
-    py::tuple py_tup_##NAME = py::cast<py::sequence>(py_##NAME);	\
-    size_t my_len = len(py_tup_##NAME); \
+    py::sequence py_seq_##NAME = py::cast<py::sequence>(py_##NAME); \
+    size_t my_len = len(py_seq_##NAME); \
     if (my_len > 2) \
       throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
     for (size_t i = 0; i < my_len; ++i) \
-      NAME[i] = py_tup_##NAME[i].cast<size_t>(); \
+      NAME[i] = py::cast<size_t>(py_seq_##NAME[i]); \
   }
 
 #define COPY_PY_REGION_TRIPLE(NAME) \
   size_t NAME[3] = {1, 1, 1}; \
   { \
-    py::tuple py_tup_##NAME = py_##NAME; \
-    size_t my_len = len(py_tup_##NAME); \
+    py::sequence py_seq_##NAME = py::cast<py::sequence>(py_##NAME); \
+    size_t my_len = len(py_seq_##NAME); \
     if (my_len > 3) \
       throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
     for (size_t i = 0; i < my_len; ++i) \
-      NAME[i] = py_tup_##NAME[i].cast<size_t>(); \
+      NAME[i] = py::cast<size_t>(py_seq_##NAME[i]); \
   }
 
+// }}}
+
 #define PYOPENCL_PARSE_NUMPY_ARRAY_SPEC \
     PyArray_Descr *tp_descr; \
     if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED) \
@@ -125,7 +131,7 @@ namespace py = pybind11;
     std::vector<npy_intp> shape; \
     try \
     { \
-      shape.push_back(py_shape.cast<npy_intp>()); \
+      shape.push_back(py::cast<npy_intp>(py_shape)); \
     } \
     catch (py::cast_error &) \
     { \
diff --git a/src/wrap_mempool.cpp b/src/wrap_mempool.cpp
index 85da2e7e..6b2d61e0 100644
--- a/src/wrap_mempool.cpp
+++ b/src/wrap_mempool.cpp
@@ -574,7 +574,7 @@ namespace {
 
 
 
-void pyopencl_expose_mempool(py::module &m)
+void pyopencl_expose_mempool(py::module_ &m)
 {
   m.def("bitlog2", pyopencl::bitlog2);
 
-- 
GitLab