Skip to content

Cannot retrieve Future from python on Windows #116

@vSLG

Description

@vSLG

Description

Python.call() does not receive anything if the called function returns asyncio.Future, only on Windows platform.

Environment 1

  • OS: Windows 8.1
  • Architecture: x86_64
  • pyotherside compiled manually in a MSYS2 environment
  • C compiler: MinGW-w64 (GCC 10.1.0), obtained from MSYS2 repository
  • QT version: 5.15, obtained from MSYS2 repository (shared lib version)
  • Python version: 3.8.3, obtained from MSYS2 repository

Environment 2

  • OS: Void Linux, kernel 5.6.18
  • Architecture: x86_64
  • pyotherside compiled manually
  • C compiler: GCC 9.3.0
  • QT version: 5.15
  • Python version: 3.8.3

Steps to reproduce (Environment 1)

  1. Write a python function that returns an asyncio.Future
  2. Run it on QML by using Python.call()
  3. Returned object by python function is blank

Programs used

main.py

import pyotherside
import sys
import asyncio as aio

from threading import Thread

class QMLTest:
    def __init__(self) -> None:
        # This is needed, else an exception is thrown on aio.get_event_loop()
        if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
            aio.set_event_loop_policy(
                aio.WindowsSelectorEventLoopPolicy(),
            )
        
        try:
            self._loop = aio.get_event_loop()
        except RuntimeError:
            self._loop = aio.new_event_loop()
            aio.set_event_loop(self._loop)

        Thread(target=self._start_asyncio_loop).start()

    def _start_asyncio_loop(self) -> None:
        aio.set_event_loop(self._loop)
        self._loop.run_forever()

    async def testfunc(self) -> None:
        pass

    def test(self) -> aio.Future:
        future = aio.run_coroutine_threadsafe(self.testfunc(), self._loop)
        print("Python future: " + str(future))
        return future

print("sys.pratform: " + sys.platform)
print("Python: " + sys.version)
print("Using pyotherside version " + pyotherside.version)
QMLTEST = QMLTest()

main.qml

import QtQuick 2.15
import io.thp.pyotherside 1.5

Rectangle {
    color: 'grey'
    width: 400
    height: 400

    Python {
        id: py

        Component.onCompleted: {
            // Add the directory of this .qml file to the search path
            addImportPath(Qt.resolvedUrl('.'));
            importNames("main", ["QMLTEST"], () => {
                call("QMLTEST.test", [], pyFuture => {
                    print(`future: ${pyFuture}`)
                })
            })
        }
    }
}

Output

Environment 1 (Windows)

$ qml.exe main.qml
sys.pratform: win32
Python: 3.8.3 (default, Jun 17 2020, 06:11:06)  [GCC 10.1.0 64 bit (AMD64)]
Using pyotherside version 1.5.9
Python future: <Future at 0x6bbaf10 state=pending>
qml: future:

Environment 2 (Linux)

$ qml main.qml
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-j'
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-j'
Got library name:  "/usr/lib/qt5/qml/io/thp/pyotherside/libpyothersideplugin.so"
sys.pratform: linux
Python: 3.8.3 (default, Jul  3 2020, 22:42:34) 
[GCC 9.3.0]
Using pyotherside version 1.5.9
Python future: <Future at 0x7efc057e10d0 state=pending>
qml: future: QVariant(PyObjectRef, )

Expected behavior

It is expected that on a Windows system we may be able to get the Future object on QML. It is expected that Environment 1 have the same behavior as on Environment 2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions