fix interactive args cancellation

pull/2387/head
Simon Renblad 2024-03-22 17:30:56 +08:00 committed by Sébastien Bourdeauducq
parent dc0b803b19
commit 19b652d4c0
3 changed files with 18 additions and 5 deletions

View File

@ -12,7 +12,8 @@ from artiq.language.core import rpc
__all__ = ["NoDefault", "DefaultMissing",
"PYONValue", "BooleanValue", "EnumerationValue",
"NumberValue", "StringValue",
"HasEnvironment", "Experiment", "EnvExperiment"]
"HasEnvironment", "Experiment", "EnvExperiment",
"CancelledArgsError"]
class NoDefault:
@ -26,6 +27,12 @@ class DefaultMissing(Exception):
pass
class CancelledArgsError(Exception):
"""Raised by the ``interactive`` context manager when an interactive
arguments request is cancelled."""
pass
class _SimpleArgProcessor:
def __init__(self, default=NoDefault):
# If default is a list, it means multiple defaults are specified, with
@ -341,7 +348,10 @@ class HasEnvironment:
When the context manager terminates, the experiment is blocked
and the user is presented with the requested argument widgets.
After the user enters values, the experiment is resumed and
the namespace contains the values of the arguments."""
the namespace contains the values of the arguments.
If the interactive arguments request is cancelled, raises
``CancelledArgsError``."""
interactive_arglist = []
namespace = SimpleNamespace()
def setattr_argument(key, processor=None, group=None, tooltip=None):
@ -350,6 +360,8 @@ class HasEnvironment:
yield namespace
del namespace.setattr_argument
argdict = self.__argument_mgr.get_interactive(interactive_arglist, title)
if argdict is None:
raise CancelledArgsError
for key, value in argdict.items():
setattr(namespace, key, value)

View File

@ -144,4 +144,4 @@ class InteractiveArgDB:
if rid not in self.futures:
raise ValueError("no experiment with this RID is "
"waiting for interactive arguments")
self.futures[rid].cancel()
self.futures[rid].set_result(None)

View File

@ -222,8 +222,9 @@ class ArgumentManager(ProcessArgumentManager):
arglist_desc = [(k, p.describe(), g, t)
for k, p, g, t in interactive_arglist]
arguments = ArgumentManager._get_interactive(arglist_desc, title)
for key, processor, _, _ in interactive_arglist:
arguments[key] = processor.process(arguments[key])
if arguments is not None:
for key, processor, _, _ in interactive_arglist:
arguments[key] = processor.process(arguments[key])
return arguments