Open vxgmichel opened 3 years ago
Welp, aside from a few people that looked at it in the very early days, you are the first that seems to maybe be using QTrio? Welcome. :]
I have wondered whether it makes sense to provide 'pytest-qt support' or just reimplement the features. I haven't taken the time to look into pytest-qt in detail yet. My impression at this point is that a lot of what it provides is the "async" of the blocking functions you refer to. That when you call them it keeps the Qt loop going for you. This is exactly what QTrio makes available directly with await
so adding a compatibility layer to put the pytest-qt layer on top isn't obviously the best solution. But maybe.
Aside from an implementation of this functionality, with or without pytest-qt, I'm curious to know what situation you are developing in. Do you have tests that need to work with and without QTrio? If compatibility is needed, would a matching API from another library cut it or does it need to be pytest-qt specifically?
Without claiming these are solutions, here are the first thoughts of related code that exists and might aid thinking about the topic.
wait
await trio.sleep(37/1000)
waitCallback
event = trio.Event(); f(callback=event.set); await event.wait()
waitSignal
There's my first dump. I'll read through your scenario and see what it looks like. Thanks for checking in. :]
Thanks for quick reply!
My impression at this point is that a lot of what it provides is the "async" of the blocking functions you refer to. That when you call them it keeps the Qt loop going for you. This is exactly what QTrio makes available directly with await so adding a compatibility layer to put the pytest-qt layer on top isn't obviously the best solution. But maybe.
Right, that makes sense!
Aside from an implementation of this functionality, with or without pytest-qt, I'm curious to know what situation you are developing in. Do you have tests that need to work with and without QTrio? If compatibility is needed, would a matching API from another library cut it or does it need to be pytest-qt specifically?
We're currently considering a qtrio migration. At the moment we're using separate threads for Qt and each instance of a trio-based user session (the application can host several independent user sessions so it is fine to run each of them in a different trio loop). The communication between threads is done through a job scheduler we developed that lets the qt thread fire jobs that will run within the trio thread and trigger some qt signals when it's done. This works fine but the logic gets quite complicated to maintain when the workflow goes back and forth between qt and trio (error handling is especially tricky). Instead, qtrio would simply let us call some qt within a trio coroutine, and we could rely on standard python flow control (try-except, etc.).
My experimentation with qtrio was almost painless since all that's needed is a re-implementation of the job scheduler on top of a simple trio nursery. Migrating the test suite is bit tougher though since we wrote our own trio/qt test runner and wrapper on top of qtbot. In our case, each test is a trio coroutine that blocks the qt execution until a call to qtbot is performed. Still, the migration should mostly be ok if we replace our current async-wrapper of qtbot
by a qtrio-compatible implementation. Something that would probably look like this:
class AsyncQtBot(pytestqt.qtbot.QtBot):
@asynccontextmanager
async def waitSignal(self, signal, timeout=5000):
with trio.fail_after(timeout):
async with qtrio.wait_signal_context(signal):
yield
Without claiming these are solutions, here are the first thoughts of related code that exists and might aid thinking about the topic [...]
Thanks for the reference! I didn't know about wait_signal_context
, this is going to be very useful.
Well, be wary as it isn't documented and as such isn't super public. :]
But, maybe it should be, or something like it.
Anyways, it sounds like just a similar set of functions would satisfy your needs. Do you want to take a pass at it? It could end up here or in pytest-qt itself perhaps. Kind of depends on what it looks like but I suspect there's various sync code that could be reused, or at least ought to be used for reference. But yeah, big picture, this functionality ought to be easily usable with QTrio.
Hello,
Is there any plan to support some kind of wrapper on top of
qtbot
in order to turn thewait*
methods into async methods that could be called from a qtrio test? That would be very useful in my opinion, e.g:The problem with using the blocking methods directly is that all trio code is blocked while waiting for the corresponding signal. I experimented with it using the following test:
The blocking methods are listed below:
wait
waitActive
waitCallback
waitExposed
waitForWindowShown
waitSignal
waitSignals
waitUntil
My guess is that there are two ways to approach this:
qtrio
emission API (e.genter_emissions_channel
)Also, thanks for the library :)