diff -Nru pyotherside-1.5.3/debian/changelog pyotherside-1.5.8/debian/changelog --- pyotherside-1.5.3/debian/changelog 2019-03-27 13:51:41.000000000 +0000 +++ pyotherside-1.5.8/debian/changelog 2019-07-08 17:18:04.000000000 +0000 @@ -1,8 +1,14 @@ -pyotherside (1.5.3-1build1) disco; urgency=medium +pyotherside (1.5.8-1) unstable; urgency=medium - * No change rebuild against qtdeclarative-abi-5-12-2. + [ Ondřej Nový ] + * d/control: Remove trailing whitespaces. - -- Rik Mills Wed, 27 Mar 2019 13:51:41 +0000 + [ Felix Zielcke ] + * New upstream version. + * Update to policy 4.4.0. + * Update to debhelper compat level 12. + + -- Felix Zielcke Mon, 08 Jul 2019 19:18:04 +0200 pyotherside (1.5.3-1) unstable; urgency=medium diff -Nru pyotherside-1.5.3/debian/control pyotherside-1.5.8/debian/control --- pyotherside-1.5.3/debian/control 2018-11-25 07:27:17.000000000 +0000 +++ pyotherside-1.5.8/debian/control 2019-07-08 17:18:04.000000000 +0000 @@ -2,8 +2,8 @@ Section: libs Priority: optional Maintainer: Debian Python Modules Team -Uploaders: Felix Zielcke -Build-Depends: debhelper-compat (= 11), +Uploaders: Felix Zielcke +Build-Depends: debhelper-compat (= 12), dh-exec, python3-dev, python3-sphinx, @@ -13,7 +13,7 @@ xauth, xvfb, libqt5svg5-dev -Standards-Version: 4.2.1 +Standards-Version: 4.4.0 Vcs-Git: https://salsa.debian.org/python-team/modules/pyotherside.git Vcs-Browser: https://salsa.debian.org/python-team/modules/pyotherside Homepage: https://thp.io/2011/pyotherside/ diff -Nru pyotherside-1.5.3/docs/conf.py pyotherside-1.5.8/docs/conf.py --- pyotherside-1.5.3/docs/conf.py 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/docs/conf.py 2019-06-16 07:10:16.000000000 +0000 @@ -41,7 +41,7 @@ # General information about the project. project = u'PyOtherSide' -copyright = u'2014, 2015, 2016, 2017 Thomas Perl' +copyright = u'2014-2019 Thomas Perl' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -50,7 +50,7 @@ # The short X.Y version. version = '1.5' # The full version, including alpha/beta/rc tags. -release = '1.5.3' +release = '1.5.8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff -Nru pyotherside-1.5.3/docs/index.rst pyotherside-1.5.8/docs/index.rst --- pyotherside-1.5.3/docs/index.rst 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/docs/index.rst 2019-06-16 07:10:16.000000000 +0000 @@ -411,38 +411,42 @@ The following data types are supported and can be used to pass data between Python and QML (and vice versa): -+--------------------+------------+-----------------------------+ -| Python | QML | Remarks | -+====================+============+=============================+ -| bool | bool | | -+--------------------+------------+-----------------------------+ -| int | int | | -+--------------------+------------+-----------------------------+ -| float | double | | -+--------------------+------------+-----------------------------+ -| str | string | | -+--------------------+------------+-----------------------------+ -| list | JS Array | JS Arrays are always | -| | | converted to Python lists. | -+--------------------+------------+-----------------------------+ -| tuple | JS Array | | -+--------------------+------------+-----------------------------+ -| dict | JS Object | Keys must be strings | -+--------------------+------------+-----------------------------+ -| datetime.date | QML date | since PyOtherSide 1.2.0 | -+--------------------+------------+-----------------------------+ -| datetime.time | QML time | since PyOtherSide 1.2.0 | -+--------------------+------------+-----------------------------+ -| datetime.datetime | JS Date | since PyOtherSide 1.2.0 | -+--------------------+------------+-----------------------------+ -| set | JS Array | since PyOtherSide 1.3.0 | -+--------------------+------------+-----------------------------+ -| iterable | JS Array | since PyOtherSide 1.3.0 | -+--------------------+------------+-----------------------------+ -| object | (opaque) | since PyOtherSide 1.4.0 | -+--------------------+------------+-----------------------------+ -| pyotherside.QObject| QObject | since PyOtherSide 1.4.0 | -+--------------------+------------+-----------------------------+ ++--------------------+----------------+-----------------------------+ +| Python | QML | Remarks | ++====================+================+=============================+ +| bool | bool | | ++--------------------+----------------+-----------------------------+ +| int | int | | ++--------------------+----------------+-----------------------------+ +| float | double | | ++--------------------+----------------+-----------------------------+ +| str | string | | ++--------------------+----------------+-----------------------------+ +| list | JS Array | JS Arrays are always | +| | | converted to Python lists. | ++--------------------+----------------+-----------------------------+ +| tuple | JS Array | | ++--------------------+----------------+-----------------------------+ +| dict | JS Object | Keys must be strings | ++--------------------+----------------+-----------------------------+ +| datetime.date | QML date | since PyOtherSide 1.2.0 | ++--------------------+----------------+-----------------------------+ +| datetime.time | QML time | since PyOtherSide 1.2.0 | ++--------------------+----------------+-----------------------------+ +| datetime.datetime | JS Date | since PyOtherSide 1.2.0 | ++--------------------+----------------+-----------------------------+ +| set | JS Array | since PyOtherSide 1.3.0 | ++--------------------+----------------+-----------------------------+ +| iterable | JS Array | since PyOtherSide 1.3.0 | ++--------------------+----------------+-----------------------------+ +| object | (opaque) | since PyOtherSide 1.4.0 | ++--------------------+----------------+-----------------------------+ +| pyotherside.QObject| QObject | since PyOtherSide 1.4.0 | ++--------------------+----------------+-----------------------------+ +| bytes | JS ArrayBuffer | since PyOtherSide 1.5.6; | +| | | requires Qt 5.8; the C++ | +| | | data type is QByteArray | ++--------------------+----------------+-----------------------------+ Trying to pass in other types than the ones listed here is undefined behavior and will usually result in an error. @@ -600,6 +604,15 @@ being deleted, but PyOtherSide tries hard to detect the deletion of objects and give meaningful error messages in case the reference is accessed). +Calling signals of QML objects +------------------------------ + +.. versionadded:: 1.5.4 + +Calling (emitting) signals of QML objects is supported since PyOtherSide 1.5.4. +However, as signals do not have a return value as such, the return value is +either just `true` or `false`, depending on whether the call worked or not. + OpenGL rendering in Python ========================== @@ -860,7 +873,7 @@ ] Of course, the function could do other things (such as doing web requests, querying -databases, etc..) - as long as it returns a list-olf-dicts, it will be fine (if you +databases, etc..) - as long as it returns a list-of-dicts, it will be fine (if you are using a generator that yields dicts, just wrap the generator with :func:`list`). Using this function from QML is straightforward: @@ -1175,33 +1188,6 @@ As of version 1.3.0, PyOtherSide does not build against Python 2.x anymore. -Building for Blackberry 10 --------------------------- - -On Blackberry 10 (tested versions: 10.1, 10.2), Python 3.2.2 is already -installed on-device. Qt 5 is not installed (only Qt 4), so if you are -packaging a PyOtherSide application, you need to ship Qt 5 with it. - -The approach we currently use is: - -1. Build Qt 5 using the Native SDK -2. Get a set of matching Python 3.2.2 headers -3. Fetch the following files from the device's filesystem: - * ``/usr/lib/libpython3.2m.so`` - * ``/usr/include/python3.2m/pyconfig.h`` -4. Use ``pyconfig.h`` with the Python 3.2.2 headers and link against ``libpython3.2m`` - -Modify ``python.pri`` to point to the fetched library and your -Python 3.2.2 headers (with ``pyconfig.h`` from the device): - -.. code-block:: qmake - - QMAKE_LIBS += -lpython3.2m -L/path/to/where/the/library/is - QMAKE_CXXFLAGS += -I/path/to/where/the/headers/are/include/python3.2m - -After installing PyOtherSide in the locally-build Qt 5 (cross-compiled for -BB10), the QML plugins folder can be deployed with the .bar file. - Building for Android -------------------- @@ -1381,6 +1367,35 @@ ChangeLog ========= + +Version 1.5.8 (2019-06-16) +-------------------------- + +* Really fix Python 3.8 build compatibility (fix by Dan Church, PR#105) + +Version 1.5.7 (2019-06-06) +-------------------------- + +* Fix Python 3.8 build compatibility by adding ``--embed`` to ``python-config`` (with fallback for previous versions) + +Version 1.5.6 (2019-06-06) +-------------------------- + +* Add support for ``QByteArray``, JS ``ArrayBuffer`` and Python ``bytes`` conversion (by Igor Malinovskiy, PR#103) + +Version 1.5.5 (2019-06-04) +-------------------------- + +* Include ``dlfcn.h`` to fix build errors against musl libc (by Heiko Becker, PR#100) +* Add ``--libs`` to ``python3-config`` command line (due to Python Issue 21536 changes; fixes #102) + +Version 1.5.4 (2019-01-27) +-------------------------- + +* Initialize ``sys.argv`` in Python for libraries that depend on it (issue #77) +* Update ``plugins.qmltypes`` and cleanup project files (by martyone, PR#95) +* Allow calling signals on QML objects from Python (issue #98) + Version 1.5.3 (2017-10-14) -------------------------- diff -Nru pyotherside-1.5.3/LICENSE pyotherside-1.5.8/LICENSE --- pyotherside-1.5.3/LICENSE 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/LICENSE 2019-06-16 07:10:16.000000000 +0000 @@ -2,7 +2,7 @@ ISC License -Copyright (c) 2011, 2013, 2014, Thomas Perl +Copyright (c) 2011, 2013-2019, Thomas Perl Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/pyotherside.pri pyotherside-1.5.8/pyotherside.pri --- pyotherside-1.5.3/pyotherside.pri 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/pyotherside.pri 2019-06-16 07:10:16.000000000 +0000 @@ -1,2 +1,2 @@ PROJECTNAME = pyotherside -VERSION = 1.5.3 +VERSION = 1.5.8 diff -Nru pyotherside-1.5.3/python-config-wrapper pyotherside-1.5.8/python-config-wrapper --- pyotherside-1.5.3/python-config-wrapper 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/python-config-wrapper 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,38 @@ +#!/bin/sh +# python3-config wrapper script to support Python 3.8 +# Works around https://bugs.python.org/issue36721 + +set -e + +usage() { + echo "Usage: $0 [python3-config] (--libs|--includes)" + exit 1 +} + +if [ $# -ne 2 ]; then + usage +fi + +PYTHON_CONFIG="$1" +shift + +WHICH_FLAG="$1" +shift + +case "$WHICH_FLAG" in + --libs) + # Python 3.8 needs --embed, but previous versions do not have it: + # https://github.com/python/cpython/pull/13500 + if "$PYTHON_CONFIG" --ldflags --libs --embed >/dev/null 2>&1; then + "$PYTHON_CONFIG" --ldflags --libs --embed + else + "$PYTHON_CONFIG" --ldflags --libs + fi + ;; + --includes) + "$PYTHON_CONFIG" --includes + ;; + *) + usage + ;; +esac diff -Nru pyotherside-1.5.3/python.pri pyotherside-1.5.8/python.pri --- pyotherside-1.5.3/python.pri 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/python.pri 2019-06-16 07:10:16.000000000 +0000 @@ -4,5 +4,5 @@ message(PYTHON_CONFIG = $$PYTHON_CONFIG) -QMAKE_LIBS += $$system($$PYTHON_CONFIG --ldflags) -QMAKE_CXXFLAGS += $$system($$PYTHON_CONFIG --includes) +QMAKE_LIBS += $$system($$PWD/python-config-wrapper $$PYTHON_CONFIG --libs) +QMAKE_CXXFLAGS += $$system($$PWD/python-config-wrapper $$PYTHON_CONFIG --includes) diff -Nru pyotherside-1.5.3/qtquicktests/tst_bytes.py pyotherside-1.5.8/qtquicktests/tst_bytes.py --- pyotherside-1.5.3/qtquicktests/tst_bytes.py 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/qtquicktests/tst_bytes.py 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,10 @@ +import struct + +def get_bytes(): + return struct.pack('src/pyotherside.qmltypes + QML2_IMPORT_PATH=$(pwd)/tmp/usr/lib/x86_64-linux-gnu/qt5/qml \ + make -C src qmltypes To run the included unit tests after building, use: diff -Nru pyotherside-1.5.3/src/converter.h pyotherside-1.5.8/src/converter.h --- pyotherside-1.5.3/src/converter.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/converter.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -100,6 +100,7 @@ FLOATING, BOOLEAN, STRING, + BYTES, LIST, DICT, DATE, @@ -114,6 +115,7 @@ virtual double floating(V&) = 0; virtual bool boolean(V&) = 0; virtual const char *string(V&) = 0; + virtual QByteArray bytes(V&) = 0; virtual ListIterator *list(V&) = 0; virtual DictIterator *dict(V&) = 0; virtual ConverterDate date(V&) = 0; @@ -126,6 +128,7 @@ virtual V fromFloating(double v) = 0; virtual V fromBoolean(bool v) = 0; virtual V fromString(const char *v) = 0; + virtual V fromBytes(const QByteArray &v) = 0; virtual V fromDate(ConverterDate date) = 0; virtual V fromTime(ConverterTime time) = 0; virtual V fromDateTime(ConverterDateTime dateTime) = 0; @@ -154,6 +157,8 @@ return tconv.fromBoolean(fconv.boolean(from)); case FC::STRING: return tconv.fromString(fconv.string(from)); + case FC::BYTES: + return tconv.fromBytes(fconv.bytes(from)); case FC::LIST: { ListBuilder *listBuilder = tconv.newList(); diff -Nru pyotherside-1.5.3/src/ensure_gil_state.h pyotherside-1.5.8/src/ensure_gil_state.h --- pyotherside-1.5.3/src/ensure_gil_state.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/ensure_gil_state.h 2019-06-16 07:10:16.000000000 +0000 @@ -17,7 +17,7 @@ * PERFORMANCE OF THIS SOFTWARE. **/ -#include "Python.h" +#include "python_wrap.h" class EnsureGILState { public: diff -Nru pyotherside-1.5.3/src/global_libpython_loader.cpp pyotherside-1.5.8/src/global_libpython_loader.cpp --- pyotherside-1.5.3/src/global_libpython_loader.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/global_libpython_loader.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -25,6 +25,7 @@ #define _GNU_SOURCE #include +#include #include #include diff -Nru pyotherside-1.5.3/src/pyglarea.h pyotherside-1.5.8/src/pyglarea.h --- pyotherside-1.5.3/src/pyglarea.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyglarea.h 2019-06-16 07:10:16.000000000 +0000 @@ -19,7 +19,7 @@ #ifndef PYOTHERSIDE_PYGLAREA_H #define PYOTHERSIDE_PYGLAREA_H -#include "Python.h" +#include "python_wrap.h" #include #include diff -Nru pyotherside-1.5.3/src/pyglrenderer.h pyotherside-1.5.8/src/pyglrenderer.h --- pyotherside-1.5.3/src/pyglrenderer.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyglrenderer.h 2019-06-16 07:10:16.000000000 +0000 @@ -19,7 +19,7 @@ #ifndef PYOTHERSIDE_PYGLRENDERER_H #define PYOTHERSIDE_PYGLRENDERER_H -#include "Python.h" +#include "python_wrap.h" #include #include diff -Nru pyotherside-1.5.3/src/pyobject_converter.h pyotherside-1.5.8/src/pyobject_converter.h --- pyotherside-1.5.3/src/pyobject_converter.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyobject_converter.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,7 +22,7 @@ #include "converter.h" #include "pyqobject.h" -#include "Python.h" +#include "python_wrap.h" #include "datetime.h" #include @@ -150,8 +150,10 @@ return INTEGER; } else if (PyFloat_Check(o)) { return FLOATING; - } else if (PyUnicode_Check(o) || PyBytes_Check(o)) { + } else if (PyUnicode_Check(o)) { return STRING; + } else if (PyBytes_Check(o)) { + return BYTES; } else if (PyDateTime_Check(o)) { // Need to check PyDateTime before PyDate, because // it is a subclass of PyDate. @@ -175,10 +177,6 @@ virtual double floating(PyObject *&o) { return PyFloat_AsDouble(o); } virtual bool boolean(PyObject *&o) { return (o == Py_True); } virtual const char *string(PyObject *&o) { - if (PyBytes_Check(o)) { - return PyBytes_AsString(o); - } - // XXX: In Python 3.3, we can use PyUnicode_UTF8() if (stringcontainer != NULL) { Py_DECREF(stringcontainer); @@ -186,6 +184,9 @@ stringcontainer = PyUnicode_AsUTF8String(o); return PyBytes_AsString(stringcontainer); } + virtual QByteArray bytes(PyObject *&o) { + return QByteArray(PyBytes_AsString(o), PyBytes_Size(o)); + } virtual ListIterator *list(PyObject *&o) { return new PyObjectListIterator(o); } virtual DictIterator *dict(PyObject *&o) { return new PyObjectDictIterator(o);; } virtual ConverterDate date(PyObject *&o) { @@ -222,6 +223,7 @@ virtual PyObject * fromFloating(double v) { return PyFloat_FromDouble(v); } virtual PyObject * fromBoolean(bool v) { return PyBool_FromLong((long)v); } virtual PyObject * fromString(const char *v) { return PyUnicode_FromString(v); } + virtual PyObject * fromBytes(const QByteArray &v) { return PyBytes_FromStringAndSize(v.constData(), v.size()); } virtual PyObject * fromDate(ConverterDate v) { return PyDate_FromDate(v.y, v.m, v.d); } virtual PyObject * fromTime(ConverterTime v) { return PyTime_FromTime(v.h, v.m, v.s, 1000 * v.ms); } virtual PyObject * fromDateTime(ConverterDateTime v) { diff -Nru pyotherside-1.5.3/src/pyobject_ref.h pyotherside-1.5.8/src/pyobject_ref.h --- pyotherside-1.5.3/src/pyobject_ref.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyobject_ref.h 2019-06-16 07:10:16.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef PYOTHERSIDE_PYOBJECT_REF_H #define PYOTHERSIDE_PYOBJECT_REF_H -#include "Python.h" +#include "python_wrap.h" #include diff -Nru pyotherside-1.5.3/src/pyotherside_plugin.cpp pyotherside-1.5.8/src/pyotherside_plugin.cpp --- pyotherside-1.5.3/src/pyotherside_plugin.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyotherside_plugin.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/pyotherside_plugin.h pyotherside-1.5.8/src/pyotherside_plugin.h --- pyotherside-1.5.3/src/pyotherside_plugin.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyotherside_plugin.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/pyotherside.qmltypes pyotherside-1.5.8/src/pyotherside.qmltypes --- pyotherside-1.5.3/src/pyotherside.qmltypes 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyotherside.qmltypes 2019-06-16 07:10:16.000000000 +0000 @@ -1,17 +1,18 @@ -import QtQuick.tooling 1.1 +import QtQuick.tooling 1.2 // This file describes the plugin-supplied types contained in the library. // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump io.thp.pyotherside 1.0 tmp/usr/lib/x86_64-linux-gnu/qt5/qml' +// 'qmlplugindump -nonrelocatable io.thp.pyotherside 1.5' Module { + dependencies: [] Component { name: "PyFbo" defaultProperty: "data" prototype: "QQuickFramebufferObject" - exports: ["PyFBO 1.5"] + exports: ["io.thp.pyotherside/PyFBO 1.5"] exportMetaObjectRevisions: [0] Property { name: "renderer"; type: "QVariant" } } @@ -19,7 +20,7 @@ name: "PyGLArea" defaultProperty: "data" prototype: "QQuickItem" - exports: ["PyGLArea 1.5"] + exports: ["io.thp.pyotherside/PyGLArea 1.5"] exportMetaObjectRevisions: [0] Property { name: "renderer"; type: "QVariant" } Property { name: "before"; type: "bool" } @@ -40,7 +41,7 @@ Signal { name: "process" Parameter { name: "func"; type: "QVariant" } - Parameter { name: "args"; type: "QVariant" } + Parameter { name: "unboxed_args"; type: "QVariant" } Parameter { name: "callback"; type: "QJSValue"; isPointer: true } } Signal { @@ -48,6 +49,12 @@ Parameter { name: "name"; type: "string" } Parameter { name: "callback"; type: "QJSValue"; isPointer: true } } + Signal { + name: "import_names" + Parameter { name: "name"; type: "string" } + Parameter { name: "args"; type: "QVariant" } + Parameter { name: "callback"; type: "QJSValue"; isPointer: true } + } Method { name: "addImportPath" Parameter { name: "path"; type: "string" } @@ -63,6 +70,18 @@ Parameter { name: "expr"; type: "string" } } Method { + name: "importNames" + Parameter { name: "name"; type: "string" } + Parameter { name: "args"; type: "QVariant" } + Parameter { name: "callback"; type: "QJSValue" } + } + Method { + name: "importNames_sync" + type: "bool" + Parameter { name: "name"; type: "string" } + Parameter { name: "args"; type: "QVariant" } + } + Method { name: "importModule" Parameter { name: "name"; type: "string" } Parameter { name: "callback"; type: "QJSValue" } @@ -91,7 +110,7 @@ name: "call_sync" type: "QVariant" Parameter { name: "func"; type: "QVariant" } - Parameter { name: "args"; type: "QVariant" } + Parameter { name: "boxed_args"; type: "QVariant" } } Method { name: "call_sync" @@ -110,31 +129,31 @@ Component { name: "QPython10" prototype: "QPython" - exports: ["Python 1.0"] + exports: ["io.thp.pyotherside/Python 1.0"] exportMetaObjectRevisions: [0] } Component { name: "QPython12" prototype: "QPython" - exports: ["Python 1.2"] + exports: ["io.thp.pyotherside/Python 1.2"] exportMetaObjectRevisions: [0] } Component { name: "QPython13" prototype: "QPython" - exports: ["Python 1.3"] + exports: ["io.thp.pyotherside/Python 1.3"] exportMetaObjectRevisions: [0] } Component { name: "QPython14" prototype: "QPython" - exports: ["Python 1.4"] + exports: ["io.thp.pyotherside/Python 1.4"] exportMetaObjectRevisions: [0] } Component { name: "QPython15" prototype: "QPython" - exports: ["Python 1.5"] + exports: ["io.thp.pyotherside/Python 1.5"] exportMetaObjectRevisions: [0] } Component { @@ -142,9 +161,168 @@ defaultProperty: "data" prototype: "QQuickItem" Property { name: "textureFollowsItemSize"; type: "bool" } + Property { name: "mirrorVertically"; type: "bool" } Signal { name: "textureFollowsItemSizeChanged" Parameter { type: "bool" } } + Signal { + name: "mirrorVerticallyChanged" + Parameter { type: "bool" } + } + } + Component { + name: "QQuickItem" + defaultProperty: "data" + prototype: "QObject" + Enum { + name: "TransformOrigin" + values: { + "TopLeft": 0, + "Top": 1, + "TopRight": 2, + "Left": 3, + "Center": 4, + "Right": 5, + "BottomLeft": 6, + "Bottom": 7, + "BottomRight": 8 + } + } + Property { name: "parent"; type: "QQuickItem"; isPointer: true } + Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "resources"; type: "QObject"; isList: true; isReadonly: true } + Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true } + Property { name: "x"; type: "float" } + Property { name: "y"; type: "float" } + Property { name: "z"; type: "float" } + Property { name: "width"; type: "float" } + Property { name: "height"; type: "float" } + Property { name: "opacity"; type: "float" } + Property { name: "enabled"; type: "bool" } + Property { name: "visible"; type: "bool" } + Property { name: "visibleChildren"; type: "QQuickItem"; isList: true; isReadonly: true } + Property { name: "states"; type: "QQuickState"; isList: true; isReadonly: true } + Property { name: "transitions"; type: "QQuickTransition"; isList: true; isReadonly: true } + Property { name: "state"; type: "string" } + Property { name: "childrenRect"; type: "QRectF"; isReadonly: true } + Property { name: "anchors"; type: "QQuickAnchors"; isReadonly: true; isPointer: true } + Property { name: "left"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "right"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "horizontalCenter"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "top"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "bottom"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "verticalCenter"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "baseline"; type: "QQuickAnchorLine"; isReadonly: true } + Property { name: "baselineOffset"; type: "float" } + Property { name: "clip"; type: "bool" } + Property { name: "focus"; type: "bool" } + Property { name: "activeFocus"; type: "bool"; isReadonly: true } + Property { name: "activeFocusOnTab"; revision: 1; type: "bool" } + Property { name: "rotation"; type: "float" } + Property { name: "scale"; type: "float" } + Property { name: "transformOrigin"; type: "TransformOrigin" } + Property { name: "transformOriginPoint"; type: "QPointF"; isReadonly: true } + Property { name: "transform"; type: "QQuickTransform"; isList: true; isReadonly: true } + Property { name: "smooth"; type: "bool" } + Property { name: "antialiasing"; type: "bool" } + Property { name: "implicitWidth"; type: "float" } + Property { name: "implicitHeight"; type: "float" } + Property { name: "layer"; type: "QQuickItemLayer"; isReadonly: true; isPointer: true } + Signal { + name: "childrenRectChanged" + Parameter { type: "QRectF" } + } + Signal { + name: "baselineOffsetChanged" + Parameter { type: "float" } + } + Signal { + name: "stateChanged" + Parameter { type: "string" } + } + Signal { + name: "focusChanged" + Parameter { type: "bool" } + } + Signal { + name: "activeFocusChanged" + Parameter { type: "bool" } + } + Signal { + name: "activeFocusOnTabChanged" + revision: 1 + Parameter { type: "bool" } + } + Signal { + name: "parentChanged" + Parameter { type: "QQuickItem"; isPointer: true } + } + Signal { + name: "transformOriginChanged" + Parameter { type: "TransformOrigin" } + } + Signal { + name: "smoothChanged" + Parameter { type: "bool" } + } + Signal { + name: "antialiasingChanged" + Parameter { type: "bool" } + } + Signal { + name: "clipChanged" + Parameter { type: "bool" } + } + Signal { + name: "windowChanged" + revision: 1 + Parameter { name: "window"; type: "QQuickWindow"; isPointer: true } + } + Method { name: "update" } + Method { + name: "grabToImage" + revision: 2 + type: "bool" + Parameter { name: "callback"; type: "QJSValue" } + Parameter { name: "targetSize"; type: "QSize" } + } + Method { + name: "grabToImage" + revision: 2 + type: "bool" + Parameter { name: "callback"; type: "QJSValue" } + } + Method { + name: "contains" + type: "bool" + Parameter { name: "point"; type: "QPointF" } + } + Method { + name: "mapFromItem" + Parameter { type: "QQmlV4Function"; isPointer: true } + } + Method { + name: "mapToItem" + Parameter { type: "QQmlV4Function"; isPointer: true } + } + Method { name: "forceActiveFocus" } + Method { + name: "forceActiveFocus" + Parameter { name: "reason"; type: "Qt::FocusReason" } + } + Method { + name: "nextItemInFocusChain" + revision: 1 + type: "QQuickItem*" + Parameter { name: "forward"; type: "bool" } + } + Method { name: "nextItemInFocusChain"; revision: 1; type: "QQuickItem*" } + Method { + name: "childAt" + type: "QQuickItem*" + Parameter { name: "x"; type: "float" } + Parameter { name: "y"; type: "float" } + } } } diff -Nru pyotherside-1.5.3/src/pyqobject.h pyotherside-1.5.8/src/pyqobject.h --- pyotherside-1.5.3/src/pyqobject.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/pyqobject.h 2019-06-16 07:10:16.000000000 +0000 @@ -19,7 +19,7 @@ #ifndef PYOTHERSIDE_PYQOBJECT_H #define PYOTHERSIDE_PYQOBJECT_H -#include "Python.h" +#include "python_wrap.h" #include "qobject_ref.h" diff -Nru pyotherside-1.5.3/src/python_wrap.h pyotherside-1.5.8/src/python_wrap.h --- pyotherside-1.5.3/src/python_wrap.h 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/src/python_wrap.h 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,6 @@ +#pragma once + +#pragma push_macro("slots") +#undef slots +#include "Python.h" +#pragma pop_macro("slots") diff -Nru pyotherside-1.5.3/src/qml_python_bridge.h pyotherside-1.5.8/src/qml_python_bridge.h --- pyotherside-1.5.3/src/qml_python_bridge.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qml_python_bridge.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qpython.cpp pyotherside-1.5.8/src/qpython.cpp --- pyotherside-1.5.3/src/qpython.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qpython.h pyotherside-1.5.8/src/qpython.h --- pyotherside-1.5.3/src/qpython.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,7 @@ #ifndef PYOTHERSIDE_QPYTHON_H #define PYOTHERSIDE_QPYTHON_H -#include "Python.h" +#include "python_wrap.h" #include #include diff -Nru pyotherside-1.5.3/src/qpython_imageprovider.cpp pyotherside-1.5.8/src/qpython_imageprovider.cpp --- pyotherside-1.5.3/src/qpython_imageprovider.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_imageprovider.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qpython_imageprovider.h pyotherside-1.5.8/src/qpython_imageprovider.h --- pyotherside-1.5.3/src/qpython_imageprovider.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_imageprovider.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qpython_priv.cpp pyotherside-1.5.8/src/qpython_priv.cpp --- pyotherside-1.5.3/src/qpython_priv.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_priv.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -390,6 +390,20 @@ QMetaMethod method = metaObject->method(i); if (method.name() == ref->method()) { + if (method.methodType() == QMetaMethod::Signal) { + // Signals can't be called directly, we just return true or + // false depending on whether method.invoke() worked or not + bool result = method.invoke(o, Qt::AutoConnection, + genericArguments.value(0), + genericArguments.value(1), genericArguments.value(2), + genericArguments.value(3), genericArguments.value(4), + genericArguments.value(5), genericArguments.value(6), + genericArguments.value(7), genericArguments.value(8), + genericArguments.value(9)); + + return convertQVariantToPyObject(result); + } + QVariant result; if (method.invoke(o, Qt::DirectConnection, Q_RETURN_ARG(QVariant, result), genericArguments.value(0), @@ -503,6 +517,13 @@ Py_InitializeEx(0); PyEval_InitThreads(); + // Initialize sys.argv (https://github.com/thp/pyotherside/issues/77) + int argc = 1; + wchar_t *argv[argc]; + argv[0] = Py_DecodeLocale("", nullptr); + PySys_SetArgvEx(argc, argv, 0); + PyMem_RawFree((void *)argv[0]); + locals = PyObjectRef(PyDict_New(), true); assert(locals); diff -Nru pyotherside-1.5.3/src/qpython_priv.h pyotherside-1.5.8/src/qpython_priv.h --- pyotherside-1.5.3/src/qpython_priv.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_priv.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,7 @@ #ifndef PYOTHERSIDE_QPYTHON_PRIV_H #define PYOTHERSIDE_QPYTHON_PRIV_H -#include "Python.h" +#include "python_wrap.h" #include "pyobject_ref.h" #include "pyqobject.h" diff -Nru pyotherside-1.5.3/src/qpython_worker.cpp pyotherside-1.5.8/src/qpython_worker.cpp --- pyotherside-1.5.3/src/qpython_worker.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_worker.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qpython_worker.h pyotherside-1.5.8/src/qpython_worker.h --- pyotherside-1.5.3/src/qpython_worker.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qpython_worker.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/src/qvariant_converter.h pyotherside-1.5.8/src/qvariant_converter.h --- pyotherside-1.5.3/src/qvariant_converter.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/qvariant_converter.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, 2014, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -134,6 +134,8 @@ return FLOATING; case QMetaType::QString: return STRING; + case QMetaType::QByteArray: + return BYTES; case QMetaType::QDate: return DATE; case QMetaType::QTime: @@ -213,6 +215,10 @@ return stringstorage.constData(); } + virtual QByteArray bytes(QVariant &v) { + return stringstorage = v.toByteArray(); + } + virtual PyObjectRef pyObject(QVariant &v) { return v.value(); } @@ -233,6 +239,7 @@ virtual QVariant fromFloating(double v) { return QVariant(v); } virtual QVariant fromBoolean(bool v) { return QVariant(v); } virtual QVariant fromString(const char *v) { return QVariant(QString::fromUtf8(v)); } + virtual QVariant fromBytes(const QByteArray &v) { return QVariant(v); } virtual QVariant fromDate(ConverterDate v) { return QVariant(QDate(v.y, v.m, v.d)); } virtual QVariant fromTime(ConverterTime v) { return QVariant(QTime(v.h, v.m, v.s, v.ms)); } virtual QVariant fromDateTime(ConverterDateTime v) { diff -Nru pyotherside-1.5.3/src/src.pro pyotherside-1.5.8/src/src.pro --- pyotherside-1.5.3/src/src.pro 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/src/src.pro 2019-06-16 07:10:16.000000000 +0000 @@ -13,10 +13,13 @@ target.path = $$[QT_INSTALL_QML]/$$PLUGIN_IMPORT_PATH INSTALLS += target -qmldir.files += $$_PRO_FILE_PWD_/qmldir $$_PRO_FILE_PWD_/pyotherside.qmltypes +qmldir.files += qmldir pyotherside.qmltypes qmldir.path += $$target.path INSTALLS += qmldir +qmltypes.commands = qmlplugindump -nonrelocatable io.thp.pyotherside 1.5 > $$PWD/pyotherside.qmltypes +QMAKE_EXTRA_TARGETS += qmltypes + DEPENDPATH += . INCLUDEPATH += . diff -Nru pyotherside-1.5.3/tests/test_call_signal/TestModule.py pyotherside-1.5.8/tests/test_call_signal/TestModule.py --- pyotherside-1.5.3/tests/test_call_signal/TestModule.py 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/tests/test_call_signal/TestModule.py 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,5 @@ +import pyotherside + +def makeCalls(obj): + print(f'result of callFunction: {obj.callFunction()}') + print(f'result of callSignal: {obj.callSignal()}') diff -Nru pyotherside-1.5.3/tests/test_call_signal/test.qml pyotherside-1.5.8/tests/test_call_signal/test.qml --- pyotherside-1.5.3/tests/test_call_signal/test.qml 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/tests/test_call_signal/test.qml 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,31 @@ +import QtQuick 2.9 +import io.thp.pyotherside 1.5 + +Item { +id: obj + + signal callSignal() + + function callFunction() { + print('Function Called') + return 'hoho' + } + + function signalConnection(){ + print('Signal Called') + } + + Component.onCompleted: { + obj.callSignal.connect(signalConnection) + } + + Python { + Component.onCompleted: { + addImportPath(Qt.resolvedUrl('.')); + + importModule('TestModule', function(){ + call('TestModule.makeCalls', [obj]) + }) + } + } +} diff -Nru pyotherside-1.5.3/tests/tests.cpp pyotherside-1.5.8/tests/tests.cpp --- pyotherside-1.5.3/tests/tests.cpp 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/tests/tests.cpp 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -62,6 +62,14 @@ QVERIFY(conv->type(v) == Converter::STRING); QVERIFY(strcmp(conv->string(v), "Hello World") == 0); + /* Convert from/to Bytes */ + static const char BUF[] = { 'a', 'b', '\0', 'c', 'd' }; + v = conv->fromBytes(QByteArray(BUF, sizeof(BUF))); + QVERIFY(conv->type(v) == Converter::BYTES); + QByteArray res = conv->bytes(v); + QVERIFY(res.size() == sizeof(BUF)); + QVERIFY(memcmp(BUF, res.constData(), res.size()) == 0); + /* Convert from/to List */ ListBuilder *builder = conv->newList(); v = conv->fromInteger(444); diff -Nru pyotherside-1.5.3/tests/tests.h pyotherside-1.5.8/tests/tests.h --- pyotherside-1.5.3/tests/tests.h 2017-10-14 10:35:32.000000000 +0000 +++ pyotherside-1.5.8/tests/tests.h 2019-06-16 07:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /** * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5 - * Copyright (c) 2011, 2013, Thomas Perl + * Copyright (c) 2011, 2013-2019, Thomas Perl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff -Nru pyotherside-1.5.3/tests/test_sys_argv/test_sys_argv.qml pyotherside-1.5.8/tests/test_sys_argv/test_sys_argv.qml --- pyotherside-1.5.3/tests/test_sys_argv/test_sys_argv.qml 1970-01-01 00:00:00.000000000 +0000 +++ pyotherside-1.5.8/tests/test_sys_argv/test_sys_argv.qml 2019-06-16 07:10:16.000000000 +0000 @@ -0,0 +1,17 @@ +import QtQuick 2.0 +import io.thp.pyotherside 1.5 + +Text { + id: txt + + Python { + Component.onCompleted: { + importModule('sys', function() { + var args = evaluate('sys.argv'); + for (var i=0; i