aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-01-16 12:58:04 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-01-16 12:58:06 +0100
commitf5ee713b60b541ad9d9cac11fa65b4b1091e25ac (patch)
treea960cc0b506f2f0a2d9f0df0986d1be7690a5d6c
parent317eb0ad107d056f4af097ff94d99233009c393d (diff)
parent77de5fb2d02551eb7563ba1a42c74ad6581815fb (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--build_scripts/setup_runner.py2
-rw-r--r--build_scripts/utils.py5
-rw-r--r--coin_build_instructions.py15
-rw-r--r--sources/pyside2/PySide2/templates/core_common.xml6
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp4
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp19
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h2
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp129
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/errorhandler.py16
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/loader.py4
10 files changed, 156 insertions, 46 deletions
diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py
index 8efb2883a..0e45a13f4 100644
--- a/build_scripts/setup_runner.py
+++ b/build_scripts/setup_runner.py
@@ -148,7 +148,7 @@ class SetupRunner(object):
for cmd in self.invocations_list:
cmd_as_string = " ".join(cmd)
print("\nRunning process: {}\n".format(cmd_as_string))
- exit_code = run_process(cmd, redirect_stderr_to_stdout=False)
+ exit_code = run_process(cmd)
if exit_code != 0:
msg = textwrap.dedent("""
setup.py invocation failed with exit code: {}.\n\n
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index 924b698dc..9500b3409 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -399,10 +399,9 @@ def run_process_output(args, initial_env=None):
result.append(line.rstrip())
return result
-def run_process(args, initial_env=None, redirect_stderr_to_stdout=True):
+def run_process(args, initial_env=None):
"""
Run process until completion and return the process exit code.
- Prints both stdout and stderr to the console.
No output is captured.
"""
log.info("Running process in directory {0}: command {1}".format(
@@ -415,8 +414,6 @@ def run_process(args, initial_env=None, redirect_stderr_to_stdout=True):
kwargs = {}
kwargs['env'] = initial_env
- if redirect_stderr_to_stdout:
- kwargs['stderr'] = subprocess.STDOUT
exit_code = subprocess.call(args, **kwargs)
return exit_code
diff --git a/coin_build_instructions.py b/coin_build_instructions.py
index 969b9272b..db021470f 100644
--- a/coin_build_instructions.py
+++ b/coin_build_instructions.py
@@ -122,21 +122,6 @@ def call_setup(python_ver):
cmd += ["--package-timestamp=" + CI_INTEGRATION_ID]
env = os.environ
- if CI_HOST_OS == "MacOS":
- # On Python 3, setuptools.dist.handle_display_options does some
- # weird sys.stdout.detach-ing if the stdout encoding is
- # different from utf-8. This causes issues when running
- # subprocess.call() because that access the original stdout
- # object stored in sys.__stdout__ which was detached, and
- # results in an exception being thrown.
- # The Coin macOS locale by default is US-ASCII, and that
- # triggers the above issue. Set the encoding to UTF-8 which
- # makes sure to skip over the detach-ing code.
- # Relevant links to the issue:
- # https://bugs.python.org/issue15216
- # https://bitbucket.org/tarek/distribute/issues/334/fix-for-311-breaks-packages-that-use
- # https://github.com/pypa/virtualenv/issues/359
- env['LC_CTYPE'] = 'UTF-8'
run_instruction(cmd, "Failed to run setup.py", initial_env=env)
def run_build_instructions():
diff --git a/sources/pyside2/PySide2/templates/core_common.xml b/sources/pyside2/PySide2/templates/core_common.xml
index 4f715ee1f..4984cb21a 100644
--- a/sources/pyside2/PySide2/templates/core_common.xml
+++ b/sources/pyside2/PySide2/templates/core_common.xml
@@ -278,8 +278,10 @@
if (PySequence_Check(%PYARG_0) &amp;&amp; (PySequence_Size(%PYARG_0) == 2)) {
Shiboken::AutoDecRef pyItem(PySequence_GetItem(%PYARG_0, 0));
%out = %CONVERTTOCPP[bool](pyItem);
- Shiboken::AutoDecRef pyResultItem(PySequence_GetItem(pyResult, 1));
- *result = %CONVERTTOCPP[long](pyResultItem);
+ if (result) {
+ Shiboken::AutoDecRef pyResultItem(PySequence_GetItem(pyResult, 1));
+ *result = %CONVERTTOCPP[long](pyResultItem);
+ }
}
</template>
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 3d87fcff0..ea0f43170 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -2704,8 +2704,8 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
} else if (!injectCodeCallsFunc && !func->isUserAdded() && !hasConversionRule) {
// When an argument is removed from a method signature and no other means of calling
// the method are provided (as with code injection) the generator must abort.
- qFatal(qPrintable(QString::fromLatin1("No way to call '%1::%2' with the modifications described in the type system.")
- .arg(func->ownerClass()->name(), func->signature())));
+ qFatal("No way to call '%s::%s' with the modifications described in the type system.",
+ qPrintable(func->ownerClass()->name()), qPrintable(func->signature()));
}
removedArgs++;
continue;
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index 7cca03c84..7b333f4ff 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -77,17 +77,22 @@ static struct PyMethodDef probe_methoddef[] = {
{0}
};
+static PyGetSetDef probe_getseters[] = {
+ {0} /* Sentinel */
+};
+
#define probe_tp_call make_dummy(1)
#define probe_tp_str make_dummy(2)
#define probe_tp_traverse make_dummy(3)
#define probe_tp_clear make_dummy(4)
#define probe_tp_methods probe_methoddef
-#define probe_tp_descr_get make_dummy(6)
-#define probe_tp_init make_dummy(7)
-#define probe_tp_alloc make_dummy(8)
-#define probe_tp_new make_dummy(9)
-#define probe_tp_free make_dummy(10)
-#define probe_tp_is_gc make_dummy(11)
+#define probe_tp_getset probe_getseters
+#define probe_tp_descr_get make_dummy(7)
+#define probe_tp_init make_dummy(8)
+#define probe_tp_alloc make_dummy(9)
+#define probe_tp_new make_dummy(10)
+#define probe_tp_free make_dummy(11)
+#define probe_tp_is_gc make_dummy(12)
#define probe_tp_name "type.probe"
#define probe_tp_basicsize make_dummy_int(42)
@@ -98,6 +103,7 @@ static PyType_Slot typeprobe_slots[] = {
{Py_tp_traverse, probe_tp_traverse},
{Py_tp_clear, probe_tp_clear},
{Py_tp_methods, probe_tp_methods},
+ {Py_tp_getset, probe_tp_getset},
{Py_tp_descr_get, probe_tp_descr_get},
{Py_tp_init, probe_tp_init},
{Py_tp_alloc, probe_tp_alloc},
@@ -138,6 +144,7 @@ check_PyTypeObject_valid(void)
|| probe_tp_clear != check->tp_clear
|| probe_tp_weakrefoffset != typetype->tp_weaklistoffset
|| probe_tp_methods != check->tp_methods
+ || probe_tp_getset != check->tp_getset
|| probe_tp_base != typetype->tp_base
|| !PyDict_Check(check->tp_dict)
|| !PyDict_GetItemString(check->tp_dict, "dummy")
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index bfa8f38a7..d883677ce 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -113,7 +113,7 @@ typedef struct _typeobject {
void *X26; // iternextfunc tp_iternext;
struct PyMethodDef *tp_methods;
void *X28; // struct PyMemberDef *tp_members;
- void *X29; // struct PyGetSetDef *tp_getset;
+ struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
PyObject *tp_dict;
descrgetfunc tp_descr_get;
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index a8874e2e0..da9c56c62 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -75,6 +75,7 @@ typedef struct safe_globals_struc {
PyObject *sigparse_func;
PyObject *createsig_func;
PyObject *seterror_argument_func;
+ PyObject *make_helptext_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = 0;
@@ -136,13 +137,15 @@ _get_class_of_cf(PyObject *ob_cf)
// This must be an overloaded function that we handled special.
Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload"));
selftype = PyDict_GetItem(pyside_globals->map_dict, special);
+ if (selftype == nullptr) {
+ // This is probably a module function. We will return type(None).
+ selftype = Py_None;
+ }
}
}
- assert(selftype);
PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype))
? selftype : (PyObject *)Py_TYPE(selftype);
- // do we support module functions?
Py_INCREF(typemod);
return typemod;
}
@@ -514,6 +517,9 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->seterror_argument_func = PyObject_GetAttrString(p->helper_module, "seterror_argument");
if (p->seterror_argument_func == NULL)
goto error;
+ p->make_helptext_func = PyObject_GetAttrString(p->helper_module, "make_helptext");
+ if (p->make_helptext_func == NULL)
+ goto error;
return 0;
error:
@@ -524,20 +530,50 @@ error:
}
static int
-add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp)
+_fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_gsp)
{
+ PyGetSetDef *gsp = type->tp_getset;
+ if (gsp != nullptr) {
+ for (; gsp->name != NULL; gsp++) {
+ if (strcmp(gsp->name, name) == 0) {
+ new_gsp->set = gsp->set;
+ new_gsp->doc = gsp->doc;
+ new_gsp->closure = gsp->closure;
+ return 1;
+ }
+ }
+ }
+ // staticmethod has just a __doc__ in the class
+ assert(strcmp(type->tp_name, "staticmethod") == 0);
+ return 0;
+}
+
+static int
+add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **old_descr)
+{
+ /*
+ * This function is used to assign a new __signature__ attribute,
+ * and also to override a __doc__ attribute.
+ */
assert(PyType_Check(type));
PyType_Ready(type);
PyObject *dict = type->tp_dict;
for (; gsp->name != NULL; gsp++) {
- if (PyDict_GetItemString(dict, gsp->name))
- continue;
+ PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
+ if (have_descr != nullptr) {
+ assert(strcmp(gsp->name, "__doc__") == 0);
+ Py_INCREF(have_descr);
+ *old_descr = have_descr;
+ if (!_fixup_getset(type, gsp->name, gsp))
+ continue;
+ }
Shiboken::AutoDecRef descr(PyDescr_NewGetSet(type, gsp));
if (descr.isNull())
return -1;
if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
return -1;
}
+ PyType_Modified(type);
return 0;
}
@@ -553,28 +589,91 @@ add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp)
// Please note that in fact we are modifying 'type', the metaclass of all
// objects, because we add new functionality.
//
+// Addendum 2019-01-12: We now also compute a docstring from the signature.
+//
+
+// keep the original __doc__ functions
+static PyObject *old_cf_doc_descr = 0;
+static PyObject *old_sm_doc_descr = 0;
+static PyObject *old_md_doc_descr = 0;
+static PyObject *old_tp_doc_descr = 0;
+static PyObject *old_wd_doc_descr = 0;
+
+static int handle_doc_in_progress = 0;
+
+static PyObject *
+handle_doc(PyObject *ob, PyObject *old_descr)
+{
+ init_module_1();
+ init_module_2();
+ Shiboken::AutoDecRef ob_type(GetClassOfFunc(ob));
+ PyTypeObject *type = reinterpret_cast<PyTypeObject *>(ob_type.object());
+ if (handle_doc_in_progress || strncmp(type->tp_name, "PySide2.", 8) != 0)
+ return PyObject_CallMethod(old_descr, const_cast<char *>("__get__"), const_cast<char *>("(O)"), ob);
+ handle_doc_in_progress++;
+ PyObject *res = PyObject_CallFunction(
+ pyside_globals->make_helptext_func,
+ const_cast<char *>("(O)"), ob);
+ handle_doc_in_progress--;
+ if (res == nullptr) {
+ PyErr_Print();
+ Py_FatalError("handle_doc did not receive a result");
+ }
+ return res;
+}
+
+static PyObject *
+pyside_cf_get___doc__(PyObject *cf) {
+ return handle_doc(cf, old_cf_doc_descr);
+}
+
+static PyObject *
+pyside_sm_get___doc__(PyObject *sm) {
+ return handle_doc(sm, old_sm_doc_descr);
+}
+
+static PyObject *
+pyside_md_get___doc__(PyObject *md) {
+ return handle_doc(md, old_md_doc_descr);
+}
+
+static PyObject *
+pyside_tp_get___doc__(PyObject *tp) {
+ return handle_doc(tp, old_tp_doc_descr);
+}
+
+static PyObject *
+pyside_wd_get___doc__(PyObject *wd) {
+ return handle_doc(wd, old_wd_doc_descr);
+}
+
static PyGetSetDef new_PyCFunction_getsets[] = {
- {(char *) "__signature__", (getter)pyside_cf_get___signature__},
+ {const_cast<char *>("__signature__"), (getter)pyside_cf_get___signature__},
+ {const_cast<char *>("__doc__"), (getter)pyside_cf_get___doc__},
{0}
};
static PyGetSetDef new_PyStaticMethod_getsets[] = {
- {(char *) "__signature__", (getter)pyside_sm_get___signature__},
+ {const_cast<char *>("__signature__"), (getter)pyside_sm_get___signature__},
+ {const_cast<char *>("__doc__"), (getter)pyside_sm_get___doc__},
{0}
};
static PyGetSetDef new_PyMethodDescr_getsets[] = {
- {(char *) "__signature__", (getter)pyside_md_get___signature__},
+ {const_cast<char *>("__signature__"), (getter)pyside_md_get___signature__},
+ {const_cast<char *>("__doc__"), (getter)pyside_md_get___doc__},
{0}
};
static PyGetSetDef new_PyType_getsets[] = {
- {(char *) "__signature__", (getter)pyside_tp_get___signature__},
+ {const_cast<char *>("__signature__"), (getter)pyside_tp_get___signature__},
+ {const_cast<char *>("__doc__"), (getter)pyside_tp_get___doc__},
{0}
};
static PyGetSetDef new_PyWrapperDescr_getsets[] = {
- {(char *) "__signature__", (getter)pyside_wd_get___signature__},
+ {const_cast<char *>("__signature__"), (getter)pyside_wd_get___signature__},
+ {const_cast<char *>("__doc__"), (getter)pyside_wd_get___doc__},
{0}
};
@@ -655,11 +754,11 @@ PySide_PatchTypes(void)
Shiboken::AutoDecRef wd(PyObject_GetAttrString((PyObject *)Py_TYPE(Py_True), "__add__")); // wrapper-descriptor
if (md.isNull() || wd.isNull()
|| PyType_Ready(Py_TYPE(md)) < 0
- || add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets) < 0
- || add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets) < 0
- || add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets) < 0
- || add_more_getsets(&PyType_Type, new_PyType_getsets) < 0
- || add_more_getsets(Py_TYPE(wd), new_PyWrapperDescr_getsets) < 0
+ || add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets, &old_md_doc_descr) < 0
+ || add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets, &old_cf_doc_descr) < 0
+ || add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets, &old_sm_doc_descr) < 0
+ || add_more_getsets(&PyType_Type, new_PyType_getsets, &old_tp_doc_descr) < 0
+ || add_more_getsets(Py_TYPE(wd), new_PyWrapperDescr_getsets, &old_wd_doc_descr) < 0
)
return -1;
#ifndef _WIN32
diff --git a/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py
index 902bb05af..df24234e3 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py
@@ -121,4 +121,20 @@ def seterror_argument(args, func_name):
# We don't raise the error here, to avoid the loader in the traceback.
return TypeError, msg
+
+def make_helptext(func):
+ existing_doc = func.__doc__
+ sigs = get_signature(func)
+ if not sigs:
+ return existing_doc
+ if type(sigs) != list:
+ sigs = [sigs]
+ try:
+ func_name = func.__name__
+ except AttribureError:
+ func_name = func.__func__.__name__
+ sigtext = "\n".join(func_name + str(sig) for sig in sigs)
+ msg = sigtext + "\n\n" + existing_doc if existing_doc else sigtext
+ return msg
+
# end of file
diff --git a/sources/shiboken2/shibokenmodule/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py
index be30483fe..8c7739d9a 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py
@@ -201,4 +201,8 @@ def create_signature(props, key):
def seterror_argument(args, func_name):
return errorhandler.seterror_argument(args, func_name)
+# name used in signature.cpp
+def make_helptext(func):
+ return errorhandler.make_helptext(func)
+
# end of file