diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-06-07 15:18:37 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2019-06-07 15:18:37 +0200 |
commit | d9f4a921ca88bf0bd340f42a874cf7c22b6b1a36 (patch) | |
tree | 3b4d20a6fc4ea61fa6b1eabe0e8a955dcec176c6 /sources/shiboken2/libshiboken | |
parent | 4c4fdca8ee3ee3807dd3d56876cfcc1ea1a8cac8 (diff) | |
parent | 41b864397ab9f999a7b140b12d2117b8492ed066 (diff) |
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r-- | sources/shiboken2/libshiboken/qapp_macro.cpp | 32 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/signature.cpp | 106 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/voidptr.cpp | 87 |
3 files changed, 201 insertions, 24 deletions
diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp index f69d0f937..19e985b20 100644 --- a/sources/shiboken2/libshiboken/qapp_macro.cpp +++ b/sources/shiboken2/libshiboken/qapp_macro.cpp @@ -67,7 +67,9 @@ qApp_module_index(PyObject *module) return ret; } -#define Py_NONE_TYPE Py_TYPE(Py_None) +#define PYTHON_IS_PYTHON3 (PY_VERSION_HEX >= 0x03000000) +#define PYTHON_IS_PYTHON2 (!PYTHON_IS_PYTHON3) +#define Py_NONE_TYPE Py_TYPE(Py_None) #if PYTHON_IS_PYTHON3 # define BRACE_OPEN { @@ -156,6 +158,31 @@ MakeSingletonQAppWrapper(PyTypeObject *type) return qApp_content; } +#if PYTHON_IS_PYTHON2 + +// Install support in Py_NONE_TYPE for Python 2: 'bool(qApp) == False'. +static int +none_bool(PyObject *v) +{ + return 0; +} + +static PyNumberMethods none_as_number = { + nullptr, /* nb_add */ + nullptr, /* nb_subtract */ + nullptr, /* nb_multiply */ + nullptr, /* nb_divide */ + nullptr, /* nb_remainder */ + nullptr, /* nb_divmod */ + nullptr, /* nb_power */ + nullptr, /* nb_negative */ + nullptr, /* nb_positive */ + nullptr, /* nb_absolute */ + reinterpret_cast<inquiry>(none_bool), /* nb_nonzero */ +}; + +#endif + static int setup_qApp_var(PyObject *module) { @@ -163,6 +190,9 @@ setup_qApp_var(PyObject *module) static int init_done = 0; if (!init_done) { +#if PYTHON_IS_PYTHON2 + Py_NONE_TYPE->tp_as_number = &none_as_number; +#endif qApp_var = Py_BuildValue("s", "qApp"); if (qApp_var == NULL) return -1; diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index 3defca7d2..c83f90d64 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -71,6 +71,7 @@ typedef struct safe_globals_struc { PyObject *helper_module; PyObject *arg_dict; PyObject *map_dict; + PyObject *value_dict; // for writing signatures // init part 2: run module PyObject *pyside_type_init_func; PyObject *create_signature_func; @@ -86,6 +87,7 @@ static PyObject *GetSignature_Function(PyObject *, const char *); static PyObject *GetSignature_TypeMod(PyObject *, const char *); static PyObject *GetSignature_Wrapper(PyObject *, const char *); static PyObject *get_signature(PyObject *self, PyObject *args); +static PyObject *get_signature_intern(PyObject *ob, const char *modifier); static PyObject *PySide_BuildSignatureProps(PyObject *class_mod); @@ -105,11 +107,36 @@ CreateSignature(PyObject *props, PyObject *key) const_cast<char *>("(OO)"), props, key); } +typedef PyObject *(*signaturefunc)(PyObject *, const char *); + +static PyObject * +_get_written_signature(signaturefunc sf, PyObject *ob, const char *modifier) +{ + /* + * Be a writable Attribute, but have a computed value. + * + * If a signature has not been written, call the signature function. + * If it has been written, return the written value. + * After __del__ was called, the function value re-appears. + * + * Note: This serves also for the new version that does not allow any + * assignment if we have a computed value. We only need to check if + * a computed value exists and then forbid writing. + * See pyside_set___signature + */ + PyObject *ret = PyDict_GetItem(pyside_globals->value_dict, ob); + if (ret == nullptr) { + return ob == nullptr ? nullptr : sf(ob, modifier); + } + Py_INCREF(ret); + return ret; +} + static PyObject * pyside_cf_get___signature__(PyObject *func, const char *modifier) { init_module_2(); - return GetSignature_Function(func, modifier); + return _get_written_signature(GetSignature_Function, func, modifier); } static PyObject * @@ -118,8 +145,8 @@ pyside_sm_get___signature__(PyObject *sm, const char *modifier) init_module_2(); Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__")); if (Py_TYPE(func) == PepFunction_TypePtr) - Py_RETURN_NONE; - return GetSignature_Function(func, modifier); + return PyObject_GetAttrString(func, "__signature__"); + return _get_written_signature(GetSignature_Function, func, modifier); } static PyObject * @@ -270,14 +297,14 @@ static PyObject * pyside_wd_get___signature__(PyObject *ob, const char *modifier) { init_module_2(); - return GetSignature_Wrapper(ob, modifier); + return _get_written_signature(GetSignature_Wrapper, ob, modifier); } static PyObject * pyside_tp_get___signature__(PyObject *obtype_mod, const char *modifier) { init_module_2(); - return GetSignature_TypeMod(obtype_mod, modifier); + return _get_written_signature(GetSignature_TypeMod, obtype_mod, modifier); } // forward @@ -510,6 +537,12 @@ init_phase_1(void) if (p->arg_dict == nullptr || PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0) goto error; + + // build a dict for assigned signature values + p->value_dict = PyDict_New(); + if (p->value_dict == nullptr) + goto error; + return p; } error: @@ -682,33 +715,56 @@ pyside_wd_get___doc__(PyObject *wd) { return handle_doc(wd, old_wd_doc_descr); } +// the default setter for all objects +static int +pyside_set___signature__(PyObject *op, PyObject *value) +{ + // By this additional check, this function refuses write access. + if (get_signature_intern(op, nullptr)) { + PyErr_Format(PyExc_AttributeError, + "Attribute '__signature__' of '%.50s' object is not writable", + Py_TYPE(op)->tp_name); + return -1; + } + int ret = value == nullptr + ? PyDict_DelItem(pyside_globals->value_dict, op) + : PyDict_SetItem(pyside_globals->value_dict, op, value); + Py_XINCREF(value); + return ret; +} + static PyGetSetDef new_PyCFunction_getsets[] = { - {const_cast<char *>("__signature__"), (getter)pyside_cf_get___signature__}, {const_cast<char *>("__doc__"), (getter)pyside_cf_get___doc__}, + {const_cast<char *>("__signature__"), (getter)pyside_cf_get___signature__, + (setter)pyside_set___signature__}, {0} }; static PyGetSetDef new_PyStaticMethod_getsets[] = { - {const_cast<char *>("__signature__"), (getter)pyside_sm_get___signature__}, {const_cast<char *>("__doc__"), (getter)pyside_sm_get___doc__}, + {const_cast<char *>("__signature__"), (getter)pyside_sm_get___signature__, + (setter)pyside_set___signature__}, {0} }; static PyGetSetDef new_PyMethodDescr_getsets[] = { - {const_cast<char *>("__signature__"), (getter)pyside_md_get___signature__}, {const_cast<char *>("__doc__"), (getter)pyside_md_get___doc__}, + {const_cast<char *>("__signature__"), (getter)pyside_md_get___signature__, + (setter)pyside_set___signature__}, {0} }; static PyGetSetDef new_PyType_getsets[] = { - {const_cast<char *>("__signature__"), (getter)pyside_tp_get___signature__}, {const_cast<char *>("__doc__"), (getter)pyside_tp_get___doc__}, + {const_cast<char *>("__signature__"), (getter)pyside_tp_get___signature__, + (setter)pyside_set___signature__}, {0} }; static PyGetSetDef new_PyWrapperDescr_getsets[] = { - {const_cast<char *>("__signature__"), (getter)pyside_wd_get___signature__}, {const_cast<char *>("__doc__"), (getter)pyside_wd_get___doc__}, + {const_cast<char *>("__signature__"), (getter)pyside_wd_get___signature__, + (setter)pyside_set___signature__}, {0} }; @@ -723,18 +779,8 @@ static PyGetSetDef new_PyWrapperDescr_getsets[] = { // static PyObject * -get_signature(PyObject *self, PyObject *args) +get_signature_intern(PyObject *ob, const char *modifier) { - PyObject *ob; - const char *modifier = nullptr; - - init_module_1(); - - if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier)) - return nullptr; - if (Py_TYPE(ob) == PepFunction_TypePtr) - Py_RETURN_NONE; - if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type)) return pyside_cf_get___signature__(ob, modifier); if (Py_TYPE(ob) == PepStaticMethod_TypePtr) @@ -745,6 +791,24 @@ get_signature(PyObject *self, PyObject *args) return pyside_tp_get___signature__(ob, modifier); if (Py_TYPE(ob) == &PyWrapperDescr_Type) return pyside_wd_get___signature__(ob, modifier); + return nullptr; +} + +static PyObject * +get_signature(PyObject *self, PyObject *args) +{ + PyObject *ob; + const char *modifier = nullptr; + + init_module_1(); + + if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier)) + return nullptr; + if (Py_TYPE(ob) == PepFunction_TypePtr) + Py_RETURN_NONE; + PyObject *ret = get_signature_intern(ob, modifier); + if (ret != nullptr) + return ret; Py_RETURN_NONE; } diff --git a/sources/shiboken2/libshiboken/voidptr.cpp b/sources/shiboken2/libshiboken/voidptr.cpp index e55ccfab5..5b0cb84ea 100644 --- a/sources/shiboken2/libshiboken/voidptr.cpp +++ b/sources/shiboken2/libshiboken/voidptr.cpp @@ -249,6 +249,83 @@ PyObject *SbkVoidPtrObject_str(PyObject *v) } +static int SbkVoidPtrObject_getbuffer(PyObject *obj, Py_buffer *view, int flags) +{ + if (view == NULL) + return -1; + + SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(obj); + if (sbkObject->size < 0) + return -1; + + int readonly = sbkObject->isWritable ? 0 : 1; + if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && + (readonly == 1)) { + PyErr_SetString(PyExc_BufferError, + "Object is not writable."); + return -1; + } + + view->obj = obj; + if (obj) + Py_XINCREF(obj); + view->buf = sbkObject->cptr; + view->len = sbkObject->size; + view->readonly = readonly; + view->itemsize = 1; + view->format = NULL; + if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) + view->format = "B"; + view->ndim = 1; + view->shape = NULL; + if ((flags & PyBUF_ND) == PyBUF_ND) + view->shape = &(view->len); + view->strides = NULL; + if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) + view->strides = &(view->itemsize); + view->suboffsets = NULL; + view->internal = NULL; + return 0; +} + +#if PY_VERSION_HEX < 0x03000000 + +static Py_ssize_t SbkVoidPtrObject_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr) +{ + if (segment || !Shiboken::Object::isValid(self)) + return -1; + + SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self); + *ptrptr = reinterpret_cast<void*>(sbkObject->cptr); + return sbkObject->size; +} + +static Py_ssize_t SbkVoidPtrObject_segcountproc(PyObject* self, Py_ssize_t* lenp) +{ + if (lenp) { + SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self); + *lenp = sbkObject->size; + } + return 1; +} + +PyBufferProcs SbkVoidPtrObjectBufferProc = { + &SbkVoidPtrObject_readbufferproc, // bf_getreadbuffer + (writebufferproc)&SbkVoidPtrObject_readbufferproc, // bf_getwritebuffer + &SbkVoidPtrObject_segcountproc, // bf_getsegcount + (charbufferproc)&SbkVoidPtrObject_readbufferproc, // bf_getcharbuffer + (getbufferproc)SbkVoidPtrObject_getbuffer, // bf_getbuffer +}; + +#else + +static PyBufferProcs SbkVoidPtrObjectBufferProc = { + (getbufferproc)SbkVoidPtrObject_getbuffer, // bf_getbuffer + (releasebufferproc)0 // bf_releasebuffer +}; + +#endif + // Void pointer type definition. static PyType_Slot SbkVoidPtrType_slots[] = { {Py_tp_repr, (void *)SbkVoidPtrObject_repr}, @@ -278,6 +355,14 @@ PyTypeObject *SbkVoidPtrTypeF(void) static PyTypeObject *type = nullptr; if (!type) type = (PyTypeObject *)PyType_FromSpec(&SbkVoidPtrType_spec); + +#if PY_VERSION_HEX < 0x03000000 + type->tp_as_buffer = &SbkVoidPtrObjectBufferProc; + type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; +#else + PepType_AS_BUFFER(type) = &SbkVoidPtrObjectBufferProc; +#endif + return type; } @@ -394,5 +479,3 @@ SbkConverter *createConverter() } } // namespace VoidPtr - - |