diff options
Diffstat (limited to 'ext/pybind11/include/pybind11/cast.h')
-rw-r--r-- | ext/pybind11/include/pybind11/cast.h | 522 |
1 files changed, 329 insertions, 193 deletions
diff --git a/ext/pybind11/include/pybind11/cast.h b/ext/pybind11/include/pybind11/cast.h index 535516b37..fe19075e4 100644 --- a/ext/pybind11/include/pybind11/cast.h +++ b/ext/pybind11/include/pybind11/cast.h @@ -18,12 +18,16 @@ NAMESPACE_BEGIN(pybind11) NAMESPACE_BEGIN(detail) +inline PyTypeObject *make_static_property_type(); +inline PyTypeObject *make_default_metaclass(); /// Additional type information which does not fit into the PyTypeObject struct type_info { PyTypeObject *type; size_t type_size; + void *(*operator_new)(size_t); void (*init_holder)(PyObject *, const void *); + void (*dealloc)(PyObject *); std::vector<PyObject *(*)(PyObject *, PyTypeObject *)> implicit_conversions; std::vector<std::pair<const std::type_info *, void *(*)(void *)>> implicit_casts; std::vector<bool (*)(PyObject *, void *&)> *direct_conversions; @@ -32,6 +36,8 @@ struct type_info { /** A simple type never occurs as a (direct or indirect) parent * of a class that makes use of multiple inheritance */ bool simple_type = true; + /* for base vs derived holder_type checks */ + bool default_holder = true; }; PYBIND11_NOINLINE inline internals &get_internals() { @@ -71,6 +77,8 @@ PYBIND11_NOINLINE inline internals &get_internals() { } } ); + internals_ptr->static_property_type = make_static_property_type(); + internals_ptr->default_metaclass = make_default_metaclass(); } return *internals_ptr; } @@ -108,14 +116,10 @@ PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool t } PYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_info &tp) { - const auto type = detail::get_type_handle(tp, false); + handle type = detail::get_type_handle(tp, false); if (!type) return false; - - const auto result = PyObject_IsInstance(obj.ptr(), type.ptr()); - if (result == -1) - throw error_already_set(); - return result != 0; + return isinstance(obj, type); } PYBIND11_NOINLINE inline std::string error_string() { @@ -141,6 +145,7 @@ PYBIND11_NOINLINE inline std::string error_string() { PyException_SetTraceback(scope.value, scope.trace); #endif +#if !defined(PYPY_VERSION) if (scope.trace) { PyTracebackObject *trace = (PyTracebackObject *) scope.trace; @@ -160,6 +165,7 @@ PYBIND11_NOINLINE inline std::string error_string() { } trace = trace->tb_next; } +#endif return errorString; } @@ -176,7 +182,9 @@ PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr, const detail: } inline PyThreadState *get_thread_state_unchecked() { -#if PY_VERSION_HEX < 0x03000000 +#if defined(PYPY_VERSION) + return PyThreadState_GET(); +#elif PY_VERSION_HEX < 0x03000000 return _PyThreadState_Current; #elif PY_VERSION_HEX < 0x03050000 return (PyThreadState*) _Py_atomic_load_relaxed(&_PyThreadState_Current); @@ -224,7 +232,7 @@ public: /* If this is a python class, also check the parents recursively */ auto const &type_dict = get_internals().registered_types_py; - bool new_style_class = PyType_Check(tobj); + bool new_style_class = PyType_Check((PyObject *) tobj); if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { auto parents = reinterpret_borrow<tuple>(tobj->tp_bases); for (handle parent : parents) { @@ -400,6 +408,13 @@ public: make_copy_constructor(src), make_move_constructor(src)); } + static handle cast_holder(const itype *src, const void *holder) { + return type_caster_generic::cast( + src, return_value_policy::take_ownership, {}, + src ? &typeid(*src) : nullptr, &typeid(type), + nullptr, nullptr, holder); + } + template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>; operator itype*() { return (type *) value; } @@ -413,7 +428,7 @@ protected: template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) { return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; } template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) { - return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *) arg))); }; } + return [](const void *arg) -> void * { return (void *) new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg)))); }; } #else /* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations. Use a workaround that only tests for constructibility for now. */ @@ -455,6 +470,7 @@ public: public: \ static PYBIND11_DESCR name() { return type_descr(py_name); } \ static handle cast(const type *src, return_value_policy policy, handle parent) { \ + if (!src) return none().release(); \ return cast(*src, policy, parent); \ } \ operator type*() { return &value; } \ @@ -462,20 +478,31 @@ public: template <typename _T> using cast_op_type = pybind11::detail::cast_op_type<_T> +template <typename CharT> using is_std_char_type = any_of< + std::is_same<CharT, char>, /* std::string */ + std::is_same<CharT, char16_t>, /* std::u16string */ + std::is_same<CharT, char32_t>, /* std::u32string */ + std::is_same<CharT, wchar_t> /* std::wstring */ +>; + template <typename T> -struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value>> { - typedef typename std::conditional<sizeof(T) <= sizeof(long), long, long long>::type _py_type_0; - typedef typename std::conditional<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>::type _py_type_1; - typedef typename std::conditional<std::is_floating_point<T>::value, double, _py_type_1>::type py_type; +struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> { + using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>; + using _py_type_1 = conditional_t<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; + using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>; public: - bool load(handle src, bool) { + bool load(handle src, bool convert) { py_type py_value; - if (!src) { + if (!src) return false; - } if (std::is_floating_point<T>::value) { - py_value = (py_type) PyFloat_AsDouble(src.ptr()); + + if (std::is_floating_point<T>::value) { + if (convert || PyFloat_Check(src.ptr())) + py_value = (py_type) PyFloat_AsDouble(src.ptr()); + else + return false; } else if (sizeof(T) <= sizeof(long)) { if (PyFloat_Check(src.ptr())) return false; @@ -502,7 +529,7 @@ public: bool type_error = PyErr_ExceptionMatches(PyExc_TypeError); #endif PyErr_Clear(); - if (type_error && PyNumber_Check(src.ptr())) { + if (type_error && convert && PyNumber_Check(src.ptr())) { auto tmp = reinterpret_borrow<object>(std::is_floating_point<T>::value ? PyNumber_Float(src.ptr()) : PyNumber_Long(src.ptr())); @@ -604,133 +631,161 @@ public: PYBIND11_TYPE_CASTER(bool, _("bool")); }; -template <> class type_caster<std::string> { -public: - bool load(handle src, bool) { - object temp; - handle load_src = src; - if (!src) { - return false; - } else if (PyUnicode_Check(load_src.ptr())) { - temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError - load_src = temp; - } - char *buffer; - ssize_t length; - int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src.ptr(), &buffer, &length); - if (err == -1) { PyErr_Clear(); return false; } // TypeError - value = std::string(buffer, (size_t) length); - success = true; - return true; - } +// Helper class for UTF-{8,16,32} C++ stl strings: +template <typename CharT, class Traits, class Allocator> +struct type_caster<std::basic_string<CharT, Traits, Allocator>, enable_if_t<is_std_char_type<CharT>::value>> { + // Simplify life by being able to assume standard char sizes (the standard only guarantees + // minimums), but Python requires exact sizes + static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1, "Unsupported char size != 1"); + static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); + static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); + // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) + static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, + "Unsupported wchar_t size != 2/4"); + static constexpr size_t UTF_N = 8 * sizeof(CharT); + + using StringType = std::basic_string<CharT, Traits, Allocator>; - static handle cast(const std::string &src, return_value_policy /* policy */, handle /* parent */) { - return PyUnicode_FromStringAndSize(src.c_str(), (ssize_t) src.length()); - } - - PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME)); -protected: - bool success = false; -}; - -template <typename type, typename deleter> class type_caster<std::unique_ptr<type, deleter>> { -public: - static handle cast(std::unique_ptr<type, deleter> &&src, return_value_policy policy, handle parent) { - handle result = type_caster_base<type>::cast(src.get(), policy, parent); - if (result) - src.release(); - return result; - } - static PYBIND11_DESCR name() { return type_caster_base<type>::name(); } -}; - -template <> class type_caster<std::wstring> { -public: bool load(handle src, bool) { +#if PY_MAJOR_VERSION < 3 object temp; +#endif handle load_src = src; if (!src) { return false; } else if (!PyUnicode_Check(load_src.ptr())) { +#if PY_MAJOR_VERSION >= 3 + return false; + // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false +#else + if (!PYBIND11_BYTES_CHECK(load_src.ptr())) + return false; temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr())); if (!temp) { PyErr_Clear(); return false; } load_src = temp; - } - wchar_t *buffer = nullptr; - ssize_t length = -1; -#if PY_MAJOR_VERSION >= 3 - buffer = PyUnicode_AsWideCharString(load_src.ptr(), &length); -#else - temp = reinterpret_steal<object>( - sizeof(wchar_t) == sizeof(short) - ? PyUnicode_AsUTF16String(load_src.ptr()) - : PyUnicode_AsUTF32String(load_src.ptr())); - if (temp) { - int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), (char **) &buffer, &length); - if (err == -1) { buffer = nullptr; } // TypeError - length = length / (ssize_t) sizeof(wchar_t) - 1; ++buffer; // Skip BOM - } #endif - if (!buffer) { PyErr_Clear(); return false; } - value = std::wstring(buffer, (size_t) length); - success = true; + } + + object utfNbytes = reinterpret_steal<object>(PyUnicode_AsEncodedString( + load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); + if (!utfNbytes) { PyErr_Clear(); return false; } + + const CharT *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); + if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 + value = StringType(buffer, length); return true; } - static handle cast(const std::wstring &src, return_value_policy /* policy */, handle /* parent */) { - return PyUnicode_FromWideChar(src.c_str(), (ssize_t) src.length()); + static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + const char *buffer = reinterpret_cast<const char *>(src.c_str()); + ssize_t nbytes = ssize_t(src.size() * sizeof(CharT)); + handle s = decode_utfN(buffer, nbytes); + if (!s) throw error_already_set(); + return s; } - PYBIND11_TYPE_CASTER(std::wstring, _(PYBIND11_STRING_NAME)); -protected: - bool success = false; + PYBIND11_TYPE_CASTER(StringType, _(PYBIND11_STRING_NAME)); + +private: + static handle decode_utfN(const char *buffer, ssize_t nbytes) { +#if !defined(PYPY_VERSION) + return + UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : + UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : + PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); +#else + // PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version + // sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a + // non-const char * arguments, which is also a nuissance, so bypass the whole thing by just + // passing the encoding as a string value, which works properly: + return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); +#endif + } }; -template <> class type_caster<char> : public type_caster<std::string> { +// Type caster for C-style strings. We basically use a std::string type caster, but also add the +// ability to use None as a nullptr char* (which the string caster doesn't allow). +template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> { + using StringType = std::basic_string<CharT>; + using StringCaster = type_caster<StringType>; + StringCaster str_caster; + bool none = false; public: bool load(handle src, bool convert) { - if (src.is_none()) return true; - return type_caster<std::string>::load(src, convert); - } - - static handle cast(const char *src, return_value_policy /* policy */, handle /* parent */) { - if (src == nullptr) return none().inc_ref(); - return PyUnicode_FromString(src); + if (!src) return false; + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) return false; + none = true; + return true; + } + return str_caster.load(src, convert); } - static handle cast(char src, return_value_policy /* policy */, handle /* parent */) { - char str[2] = { src, '\0' }; - return PyUnicode_DecodeLatin1(str, 1, nullptr); + static handle cast(const CharT *src, return_value_policy policy, handle parent) { + if (src == nullptr) return pybind11::none().inc_ref(); + return StringCaster::cast(StringType(src), policy, parent); } - operator char*() { return success ? (char *) value.c_str() : nullptr; } - operator char&() { return value[0]; } - - static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); } -}; + static handle cast(CharT src, return_value_policy policy, handle parent) { + if (std::is_same<char, CharT>::value) { + handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); + if (!s) throw error_already_set(); + return s; + } + return StringCaster::cast(StringType(1, src), policy, parent); + } + + operator CharT*() { return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str()); } + operator CharT() { + if (none) + throw value_error("Cannot convert None to a character"); + + auto &value = static_cast<StringType &>(str_caster); + size_t str_len = value.size(); + if (str_len == 0) + throw value_error("Cannot convert empty string to a character"); + + // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that + // is too high, and one for multiple unicode characters (caught later), so we need to figure + // out how long the first encoded character is in bytes to distinguish between these two + // errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those + // can fit into a single char value. + if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { + unsigned char v0 = static_cast<unsigned char>(value[0]); + size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 + (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence + (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence + 4; // 0b11110xxx - start of 4-byte sequence + + if (char0_bytes == str_len) { + // If we have a 128-255 value, we can decode it into a single char: + if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx + return static_cast<CharT>(((v0 & 3) << 6) + (static_cast<unsigned char>(value[1]) & 0x3F)); + } + // Otherwise we have a single character, but it's > U+00FF + throw value_error("Character code point not in range(0x100)"); + } + } -template <> class type_caster<wchar_t> : public type_caster<std::wstring> { -public: - bool load(handle src, bool convert) { - if (src.is_none()) return true; - return type_caster<std::wstring>::load(src, convert); - } + // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a + // surrogate pair with total length 2 instantly indicates a range error (but not a "your + // string was too long" error). + else if (StringCaster::UTF_N == 16 && str_len == 2) { + char16_t v0 = static_cast<char16_t>(value[0]); + if (v0 >= 0xD800 && v0 < 0xE000) + throw value_error("Character code point not in range(0x10000)"); + } - static handle cast(const wchar_t *src, return_value_policy /* policy */, handle /* parent */) { - if (src == nullptr) return none().inc_ref(); - return PyUnicode_FromWideChar(src, (ssize_t) wcslen(src)); - } + if (str_len != 1) + throw value_error("Expected a character, but multi-character string found"); - static handle cast(wchar_t src, return_value_policy /* policy */, handle /* parent */) { - wchar_t wstr[2] = { src, L'\0' }; - return PyUnicode_FromWideChar(wstr, 1); + return value[0]; } - operator wchar_t*() { return success ? (wchar_t *) value.c_str() : nullptr; } - operator wchar_t&() { return value[0]; } - static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); } + template <typename _T> using cast_op_type = typename std::remove_reference<pybind11::detail::cast_op_type<_T>>::type; }; template <typename T1, typename T2> class type_caster<std::pair<T1, T2>> { @@ -832,12 +887,19 @@ protected: return result.release(); } -protected: std::tuple<make_caster<Tuple>...> value; }; +/// Helper class which abstracts away certain actions. Users can provide specializations for +/// custom holders, but it's only necessary if the type has a non-standard interface. +template <typename T> +struct holder_helper { + static auto get(const T &p) -> decltype(p.get()) { return p.get(); } +}; + /// Type caster for holder types like std::shared_ptr, etc. -template <typename type, typename holder_type> class type_caster_holder : public type_caster_base<type> { +template <typename type, typename holder_type> +struct copyable_holder_caster : public type_caster_base<type> { public: using base = type_caster_base<type>; using base::base; @@ -858,6 +920,9 @@ public: return true; } + if (typeinfo->default_holder) + throw cast_error("Unable to load a custom holder type from a default-holder instance"); + if (typeinfo->simple_type) { /* Case 1: no multiple inheritance etc. involved */ /* Check if we can safely perform a reinterpret-style cast */ if (PyType_IsSubtype(tobj, typeinfo->type)) @@ -869,7 +934,7 @@ public: /* If this is a python class, also check the parents recursively */ auto const &type_dict = get_internals().registered_types_py; - bool new_style_class = PyType_Check(tobj); + bool new_style_class = PyType_Check((PyObject *) tobj); if (type_dict.find(tobj) == type_dict.end() && new_style_class && tobj->tp_bases) { auto parents = reinterpret_borrow<tuple>(tobj->tp_bases); for (handle parent : parents) { @@ -916,7 +981,7 @@ public: template <typename T = holder_type, detail::enable_if_t<std::is_constructible<T, const T &, type*>::value, int> = 0> bool try_implicit_casts(handle src, bool convert) { for (auto &cast : typeinfo->implicit_casts) { - type_caster_holder sub_caster(*cast.first); + copyable_holder_caster sub_caster(*cast.first); if (sub_caster.load(src, convert)) { value = cast.second(sub_caster.value); holder = holder_type(sub_caster.holder, (type *) value); @@ -939,10 +1004,8 @@ public: #endif static handle cast(const holder_type &src, return_value_policy, handle) { - return type_caster_generic::cast( - src.get(), return_value_policy::take_ownership, handle(), - src.get() ? &typeid(*src.get()) : nullptr, &typeid(type), - nullptr, nullptr, &src); + const auto *ptr = holder_helper<holder_type>::get(src); + return type_caster_base<type>::cast_holder(ptr, &src); } protected: @@ -951,12 +1014,34 @@ protected: /// Specialize for the common std::shared_ptr, so users don't need to template <typename T> -class type_caster<std::shared_ptr<T>> : public type_caster_holder<T, std::shared_ptr<T>> { }; +class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> { }; + +template <typename type, typename holder_type> +struct move_only_holder_caster { + static handle cast(holder_type &&src, return_value_policy, handle) { + auto *ptr = holder_helper<holder_type>::get(src); + return type_caster_base<type>::cast_holder(ptr, &src); + } + static PYBIND11_DESCR name() { return type_caster_base<type>::name(); } +}; + +template <typename type, typename deleter> +class type_caster<std::unique_ptr<type, deleter>> + : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> { }; + +template <typename type, typename holder_type> +using type_caster_holder = conditional_t<std::is_copy_constructible<holder_type>::value, + copyable_holder_caster<type, holder_type>, + move_only_holder_caster<type, holder_type>>; + +template <typename T, bool Value = false> struct always_construct_holder { static constexpr bool value = Value; }; /// Create a specialization for custom holder types (silently ignores std::shared_ptr) -#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type) \ +#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \ namespace pybind11 { namespace detail { \ template <typename type> \ + struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> { }; \ + template <typename type> \ class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>> \ : public type_caster_holder<type, holder_type> { }; \ }} @@ -1004,23 +1089,24 @@ class type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caste // - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it // must have ref_count() == 1)h // If any of the above are not satisfied, we fall back to copying. -template <typename T, typename SFINAE = void> struct move_is_plain_type : std::false_type {}; -template <typename T> struct move_is_plain_type<T, enable_if_t< - !std::is_void<T>::value && !std::is_pointer<T>::value && !std::is_reference<T>::value && !std::is_const<T>::value - >> : std::true_type { }; +template <typename T> using move_is_plain_type = satisfies_none_of<T, + std::is_void, std::is_pointer, std::is_reference, std::is_const +>; template <typename T, typename SFINAE = void> struct move_always : std::false_type {}; -template <typename T> struct move_always<T, enable_if_t< - move_is_plain_type<T>::value && - !std::is_copy_constructible<T>::value && std::is_move_constructible<T>::value && - std::is_same<decltype(std::declval<type_caster<T>>().operator T&()), T&>::value - >> : std::true_type { }; +template <typename T> struct move_always<T, enable_if_t<all_of< + move_is_plain_type<T>, + negation<std::is_copy_constructible<T>>, + std::is_move_constructible<T>, + std::is_same<decltype(std::declval<make_caster<T>>().operator T&()), T&> +>::value>> : std::true_type {}; template <typename T, typename SFINAE = void> struct move_if_unreferenced : std::false_type {}; -template <typename T> struct move_if_unreferenced<T, enable_if_t< - move_is_plain_type<T>::value && - !move_always<T>::value && std::is_move_constructible<T>::value && - std::is_same<decltype(std::declval<type_caster<T>>().operator T&()), T&>::value - >> : std::true_type { }; -template <typename T> using move_never = std::integral_constant<bool, !move_always<T>::value && !move_if_unreferenced<T>::value>; +template <typename T> struct move_if_unreferenced<T, enable_if_t<all_of< + move_is_plain_type<T>, + negation<move_always<T>>, + std::is_move_constructible<T>, + std::is_same<decltype(std::declval<make_caster<T>>().operator T&()), T&> +>::value>> : std::true_type {}; +template <typename T> using move_never = none_of<move_always<T>, move_if_unreferenced<T>>; // Detect whether returning a `type` from a cast on type's type_caster is going to result in a // reference or pointer to a local variable of the type_caster. Basically, only @@ -1031,6 +1117,17 @@ template <typename type> using cast_is_temporary_value_reference = bool_constant !std::is_base_of<type_caster_generic, make_caster<type>>::value >; +// When a value returned from a C++ function is being cast back to Python, we almost always want to +// force `policy = move`, regardless of the return value policy the function/method was declared +// with. Some classes (most notably Eigen::Ref and related) need to avoid this, and so can do so by +// specializing this struct. +template <typename Return, typename SFINAE = void> struct return_value_policy_override { + static return_value_policy policy(return_value_policy p) { + return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value + ? return_value_policy::move : p; + } +}; + // Basic python -> C++ casting; throws if casting fails template <typename T, typename SFINAE> type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) { if (!conv.load(handle, true)) { @@ -1080,7 +1177,7 @@ template <typename T> T handle::cast() const { return pybind11::cast<T>(*this); template <> inline void handle::cast() const { return; } template <typename T> -detail::enable_if_t<detail::move_always<T>::value || detail::move_if_unreferenced<T>::value, T> move(object &&obj) { +detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) { if (obj.ref_count() > 1) #if defined(NDEBUG) throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references" @@ -1171,19 +1268,27 @@ template <return_value_policy policy = return_value_policy::automatic_reference, return result; } -/// Annotation for keyword arguments +/// \ingroup annotations +/// Annotation for arguments struct arg { - constexpr explicit arg(const char *name) : name(name) { } + /// Constructs an argument with the name of the argument; if null or omitted, this is a positional argument. + constexpr explicit arg(const char *name = nullptr) : name(name), flag_noconvert(false) { } + /// Assign a value to this argument template <typename T> arg_v operator=(T &&value) const; + /// Indicate that the type should not be converted in the type caster + arg &noconvert(bool flag = true) { flag_noconvert = flag; return *this; } - const char *name; + const char *name; ///< If non-null, this is a named kwargs argument + bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type caster!) }; -/// Annotation for keyword arguments with values +/// \ingroup annotations +/// Annotation for arguments with values struct arg_v : arg { +private: template <typename T> - arg_v(const char *name, T &&x, const char *descr = nullptr) - : arg(name), + arg_v(arg &&base, T &&x, const char *descr = nullptr) + : arg(base), value(reinterpret_steal<object>( detail::make_caster<T>::cast(x, return_value_policy::automatic, {}) )), @@ -1193,40 +1298,89 @@ struct arg_v : arg { #endif { } +public: + /// Direct construction with name, default, and description + template <typename T> + arg_v(const char *name, T &&x, const char *descr = nullptr) + : arg_v(arg(name), std::forward<T>(x), descr) { } + + /// Called internally when invoking `py::arg("a") = value` + template <typename T> + arg_v(const arg &base, T &&x, const char *descr = nullptr) + : arg_v(arg(base), std::forward<T>(x), descr) { } + + /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg& + arg_v &noconvert(bool flag = true) { arg::noconvert(flag); return *this; } + + /// The default value object value; + /// The (optional) description of the default value const char *descr; #if !defined(NDEBUG) + /// The C++ type name of the default value (only available when compiled in debug mode) std::string type; #endif }; template <typename T> -arg_v arg::operator=(T &&value) const { return {name, std::forward<T>(value)}; } +arg_v arg::operator=(T &&value) const { return {std::move(*this), std::forward<T>(value)}; } /// Alias for backward compatibility -- to be removed in version 2.0 template <typename /*unused*/> using arg_t = arg_v; inline namespace literals { -/// String literal version of arg +/** \rst + String literal version of `arg` + \endrst */ constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } } NAMESPACE_BEGIN(detail) +// forward declaration +struct function_record; + +/// Internal data associated with a single function call +struct function_call { + function_call(function_record &f, handle p); // Implementation in attr.h + + /// The function data: + const function_record &func; + + /// Arguments passed to the function: + std::vector<handle> args; + + /// The `convert` value the arguments should be loaded with + std::vector<bool> args_convert; + + /// The parent, if any + handle parent; +}; + + /// Helper class which loads arguments for C++ functions called from Python template <typename... Args> class argument_loader { - using itypes = type_list<intrinsic_t<Args>...>; using indices = make_index_sequence<sizeof...(Args)>; + template <typename Arg> using argument_is_args = std::is_same<intrinsic_t<Arg>, args>; + template <typename Arg> using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>; + // Get args/kwargs argument positions relative to the end of the argument list: + static constexpr auto args_pos = constexpr_first<argument_is_args, Args...>() - (int) sizeof...(Args), + kwargs_pos = constexpr_first<argument_is_kwargs, Args...>() - (int) sizeof...(Args); + + static constexpr bool args_kwargs_are_last = kwargs_pos >= - 1 && args_pos >= kwargs_pos - 1; + + static_assert(args_kwargs_are_last, "py::args/py::kwargs are only permitted as the last argument(s) of a function"); + public: - static constexpr auto has_kwargs = std::is_same<itypes, type_list<args, kwargs>>::value; - static constexpr auto has_args = has_kwargs || std::is_same<itypes, type_list<args>>::value; + static constexpr bool has_kwargs = kwargs_pos < 0; + static constexpr bool has_args = args_pos < 0; static PYBIND11_DESCR arg_names() { return detail::concat(make_caster<Args>::name()...); } - bool load_args(handle args, handle kwargs, bool convert) { - return load_impl(args, kwargs, convert, itypes{}); + bool load_args(function_call &call) { + return load_impl_sequence(call, indices{}); } template <typename Return, typename Func> @@ -1241,26 +1395,12 @@ public: } private: - bool load_impl(handle args_, handle, bool convert, type_list<args>) { - std::get<0>(value).load(args_, convert); - return true; - } - - bool load_impl(handle args_, handle kwargs_, bool convert, type_list<args, kwargs>) { - std::get<0>(value).load(args_, convert); - std::get<1>(value).load(kwargs_, convert); - return true; - } - - bool load_impl(handle args, handle, bool convert, ... /* anything else */) { - return load_impl_sequence(args, convert, indices{}); - } - static constexpr bool load_impl_sequence(handle, bool, index_sequence<>) { return true; } + static bool load_impl_sequence(function_call &, index_sequence<>) { return true; } template <size_t... Is> - bool load_impl_sequence(handle src, bool convert, index_sequence<Is...>) { - for (bool r : {std::get<Is>(value).load(PyTuple_GET_ITEM(src.ptr(), Is), convert)...}) + bool load_impl_sequence(function_call &call, index_sequence<Is...>) { + for (bool r : {std::get<Is>(value).load(call.args[Is], call.args_convert[Is])...}) if (!r) return false; return true; @@ -1271,29 +1411,9 @@ private: return std::forward<Func>(f)(cast_op<Args>(std::get<Is>(value))...); } -private: std::tuple<make_caster<Args>...> value; }; -NAMESPACE_BEGIN(constexpr_impl) -/// Implementation details for constexpr functions -constexpr int first(int i) { return i; } -template <typename T, typename... Ts> -constexpr int first(int i, T v, Ts... vs) { return v ? i : first(i + 1, vs...); } - -constexpr int last(int /*i*/, int result) { return result; } -template <typename T, typename... Ts> -constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } -NAMESPACE_END(constexpr_impl) - -/// Return the index of the first type in Ts which satisfies Predicate<T> -template <template<typename> class Predicate, typename... Ts> -constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate<Ts>::value...); } - -/// Return the index of the last type in Ts which satisfies Predicate<T> -template <template<typename> class Predicate, typename... Ts> -constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate<Ts>::value...); } - /// Helper class which collects only positional arguments for a Python function call. /// A fancier version below can collect any argument, but this one is optimal for simple calls. template <return_value_policy policy> @@ -1369,6 +1489,13 @@ private: } void process(list &/*args_list*/, arg_v a) { + if (!a.name) +#if defined(NDEBUG) + nameless_argument_error(); +#else + nameless_argument_error(a.type); +#endif + if (m_kwargs.contains(a.name)) { #if defined(NDEBUG) multiple_values_error(); @@ -1401,6 +1528,15 @@ private: } } + [[noreturn]] static void nameless_argument_error() { + throw type_error("Got kwargs without a name; only named arguments " + "may be passed via py::arg() to a python function call. " + "(compile in debug mode for details)"); + } + [[noreturn]] static void nameless_argument_error(std::string type) { + throw type_error("Got kwargs without a name of type '" + type + "'; only named " + "arguments may be passed via py::arg() to a python function call. "); + } [[noreturn]] static void multiple_values_error() { throw type_error("Got multiple values for keyword argument " "(compile in debug mode for details)"); @@ -1427,14 +1563,14 @@ private: /// Collect only positional arguments for a Python function call template <return_value_policy policy, typename... Args, - typename = enable_if_t<all_of_t<is_positional, Args...>::value>> + typename = enable_if_t<all_of<is_positional<Args>...>::value>> simple_collector<policy> collect_arguments(Args &&...args) { return simple_collector<policy>(std::forward<Args>(args)...); } /// Collect all arguments, including keywords and unpacking (only instantiated when needed) template <return_value_policy policy, typename... Args, - typename = enable_if_t<!all_of_t<is_positional, Args...>::value>> + typename = enable_if_t<!all_of<is_positional<Args>...>::value>> unpacking_collector<policy> collect_arguments(Args &&...args) { // Following argument order rules for generalized unpacking according to PEP 448 static_assert( |