diff --git a/nexxT/core/ActiveApplication.py b/nexxT/core/ActiveApplication.py index c5478c1..c88a647 100644 --- a/nexxT/core/ActiveApplication.py +++ b/nexxT/core/ActiveApplication.py @@ -42,6 +42,7 @@ def __init__(self, graph): self._graphConnected = False self._interThreadConns = [] self._operationInProgress = False + self._shutdownInProgress = False # connect signals and slots for _, t in self._threads.items(): t.operationFinished.connect(self._operationFinished) @@ -119,23 +120,27 @@ def shutdown(self): """ assertMainThread() inProcessEvents = mainThread().property("processEventsRunning") - if inProcessEvents: + if inProcessEvents or self._shutdownInProgress: logging.getLogger(__name__).debug("shutdown waiting for inProcessEvents to be finished inProcessEvents=%s", inProcessEvents) MethodInvoker(dict(object=self, method="shutdown", thread=mainThread()), Qt.QueuedConnection) return - if self._state == FilterState.ACTIVE: - self.stop() - # while this is similar to code in FilterEnvironment, the lines here refer to applications - # and the lines in FilterEnvironment refer to filters. - if self._state == FilterState.OPENED: - self.close() - if self._state == FilterState.INITIALIZED: - self.deinit() - if self._state == FilterState.CONSTRUCTED: - self.destruct() - if not self._state == FilterState.DESTRUCTED: - raise NexTInternalError(f"Unexpected state '{FilterState.state2str(self._state)}' after shutdown.") + self._shutdownInProgress = True + try: + if self._state == FilterState.ACTIVE: + self.stop() + # while this is similar to code in FilterEnvironment, the lines here refer to applications + # and the lines in FilterEnvironment refer to filters. + if self._state == FilterState.OPENED: + self.close() + if self._state == FilterState.INITIALIZED: + self.deinit() + if self._state == FilterState.CONSTRUCTED: + self.destruct() + if self._state != FilterState.DESTRUCTED: + raise NexTInternalError(f"Unexpected state '{FilterState.state2str(self._state)}' after shutdown.") + finally: + self._shutdownInProgress = False def stopThreads(self): """ @@ -306,6 +311,8 @@ def _operationFinished(self): elif self._state == FilterState.DESTRUCTING: self._state = FilterState.DESTRUCTED self.stopThreads() + else: + logger.warning("Unexpected filter state at _operationFinished: %s", FilterState.state2str(self._state)) self.stateChanged.emit(self._state) @Slot() diff --git a/nexxT/core/PluginManager.py b/nexxT/core/PluginManager.py index f1a9b4a..8997867 100644 --- a/nexxT/core/PluginManager.py +++ b/nexxT/core/PluginManager.py @@ -17,6 +17,7 @@ import importlib.util from importlib.machinery import ExtensionFileLoader, EXTENSION_SUFFIXES import pkg_resources +import nexxT.shiboken from nexxT.Qt.QtCore import QObject from nexxT.core.Exceptions import UnknownPluginType, NexTRuntimeError, PluginException from nexxT.interface import Filter, FilterSurrogate @@ -283,7 +284,7 @@ def _load(self, library): @staticmethod def _loadPyfile(library, prop=None): - if prop is not None: + if prop is not None and nexxT.shiboken.isValid(prop): library = prop.evalpath(library) return PythonLibrary(library, libtype=PythonLibrary.LIBTYPE_FILE) diff --git a/nexxT/core/qrc_resources.py b/nexxT/core/qrc_resources.py index 4d04c73..01a35b4 100644 --- a/nexxT/core/qrc_resources.py +++ b/nexxT/core/qrc_resources.py @@ -1,6 +1,6 @@ # Resource object code (Python 3) # Created by: object code -# Created by: The Resource Compiler for Qt version 6.4.0 +# Created by: The Resource Compiler for Qt version 6.5.1 # WARNING! All changes made in this file will be lost! from PySide6 import QtCore @@ -264,9 +264,9 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x7f\x11a`\x7f\ +\x00\x00\x01\x85\x81\x19\x98\xb7\ \x00\x00\x006\x00\x01\x00\x00\x00\x01\x00\x00\x08h\ -\x00\x00\x01\x7f\x11a`\x81\ +\x00\x00\x01\x85\x81\x19\x98\xba\ " def qInitResources(): diff --git a/nexxT/src/Logger.cpp b/nexxT/src/Logger.cpp index 6bb6ec9..9b79c32 100644 --- a/nexxT/src/Logger.cpp +++ b/nexxT/src/Logger.cpp @@ -23,7 +23,7 @@ namespace nexxT SharedQObjectPtr logger = Services::getService("Logging"); if( !logger.isNull() ) { - bool res = QMetaObject::invokeMethod(logger.get(), "log", Qt::DirectConnection, QGenericReturnArgument(), Q_ARG(int, level), Q_ARG(const QString &, message), Q_ARG(const QString &, file), Q_ARG(int, line)); + bool res = QMetaObject::invokeMethod(logger.get(), "log", Qt::DirectConnection, Q_ARG(int, level), Q_ARG(const QString &, message), Q_ARG(const QString &, file), Q_ARG(int, line)); if(!res) { fprintf(stderr, "WARNING: invokeMetod returned false!\n"); diff --git a/nexxT/tests/core/test_CompositeFilter.py b/nexxT/tests/core/test_CompositeFilter.py index 3f2eb80..1d0a598 100644 --- a/nexxT/tests/core/test_CompositeFilter.py +++ b/nexxT/tests/core/test_CompositeFilter.py @@ -305,7 +305,6 @@ def state_changed(state): nexxT.Qt.call_exec(app) - return events finally: del t del t2 diff --git a/nexxT/tests/integration/test_gui.py b/nexxT/tests/integration/test_gui.py index bb831d5..79f13ba 100644 --- a/nexxT/tests/integration/test_gui.py +++ b/nexxT/tests/integration/test_gui.py @@ -1601,6 +1601,7 @@ def _stage0(self): appidx = conf.model.indexOfSubConfig(conf.configuration().applicationByName("application")) self.cmContextMenu(conf, appidx, CM_INIT_APP) self.qtbot.wait(1000) + # note: the following depends on --forked isolation which is broken with PySide6 self.assertLogItem(log, "INFO", "myfilter version 1") # move the window to non-standard position self.getMdiWindow().move(QPoint(37, 63)) diff --git a/setup.py b/setup.py index 3fda891..446a21e 100644 --- a/setup.py +++ b/setup.py @@ -147,8 +147,8 @@ def is_pure(*args): setup(name='nexxT', install_requires=[ - "PySide6==6.4.1", - "shiboken6==6.4.1", + "PySide6==6.5.1.1", + "shiboken6==6.5.1.1", "jsonschema>=3.2.0", "h5py>=2.10.0", "setuptools>=41.0.0", diff --git a/workspace/pytest_nexxT.sh b/workspace/pytest_nexxT.sh index d7769ea..d499270 100644 --- a/workspace/pytest_nexxT.sh +++ b/workspace/pytest_nexxT.sh @@ -8,7 +8,7 @@ fi ADD_FLAGS="" # release variant - "$PYTEST" -m "gui" $ADD_FLAGS --cov=../nexxT/core --cov=../nexxT/interface --cov=../nexxT/services --cov=../nexxT/filters --cov-report html --forked ../nexxT/tests + "$PYTEST" -m "gui" $ADD_FLAGS --cov=../nexxT/core --cov=../nexxT/interface --cov=../nexxT/services --cov=../nexxT/filters --cov-report html -s ../nexxT/tests "$PYTEST" -m "not gui" $ADD_FLAGS --cov-append --cov=../nexxT/core --cov=../nexxT/interface --cov=../nexxT/services --cov=../nexxT/filters --cov-report html ../nexxT/tests # other variants NEXXT_VARIANT=nonopt "$PYTEST" -m "not gui" $ADD_FLAGS --cov-append --cov=../nexxT/core --cov=../nexxT/interface --cov=../nexxT/services --cov=../nexxT/filters --cov-report html ../nexxT/tests diff --git a/workspace/requirements.txt b/workspace/requirements.txt index 2ec32d9..d190054 100644 --- a/workspace/requirements.txt +++ b/workspace/requirements.txt @@ -1,12 +1,12 @@ -PySide6==6.4.1 +PySide6==6.5.1.1 scons==4.3.0 -shiboken6==6.4.1 -shiboken6-generator==6.4.1 +shiboken6==6.5.1.1 +shiboken6-generator==6.5.1.1 pytest==7.1.3 pytest-cov==4.0.0 pylint==2.15.4 -pytest-qt==4.1.0 -pytest-xvfb==2.0.0 +pytest-qt==4.2.0 +pytest-xvfb==3.0.0 pytest-xdist==2.5.0 pytest-timeout==2.1.0 -e ..