pyotherside
pyotherside copied to clipboard
Cannot retrieve `Future` from python on Windows
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)
- Write a python function that returns an
asyncio.Future - Run it on QML by using
Python.call() - 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.
Have you checked if you pass it back to the Python environment (e.g. as a parameter to another call ()) and print it there, what is the value of it?
vSLG [email protected] schrieb am Di., 14. Juli 2020, 20:25:
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)
- Write a python function that returns an asyncio.Future
- Run it on QML by using Python.call()
- Returned object by python function is blank
Programs used main.py
import pyothersideimport sysimport 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 futureprint("sys.pratform: " + sys.platform)print("Python: " + sys.version)print("Using pyotherside version " + pyotherside.version)QMLTEST = QMLTest()
main.qml
import QtQuick 2.15import 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.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/thp/pyotherside/issues/116, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABBASJVL6BWC2GBNJNZEPTR3SPKLANCNFSM4OZY4R5A .
Added this function to QMLTest Python:
def print_future(self, future: aio.Future) -> None:
print("QMLTEST.print_future(): " + str(future))
print("QMLTEST.print_future(): type(future) = " + str(type(future)))
And on QML:
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}`)
call("QMLTEST.print_future", [pyFuture], null)
})
})
}
Output
Environment 1 (Windows)
$ qml 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 0x6b9bf40 state=pending>
qml: future:
QMLTEST.print_future(): []
QMLTEST.print_future(): type(future) = <class 'list'>
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 0x7f6caf3e90d0 state=pending>
qml: future: QVariant(PyObjectRef, )
QMLTEST.print_future(): <Future at 0x7f6caf3e90d0 state=finished returned NoneType>
QMLTEST.print_future(): type(future) = <class 'concurrent.futures._base.Future'>