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

View File

@ -144,4 +144,4 @@ class InteractiveArgDB:
if rid not in self.futures: if rid not in self.futures:
raise ValueError("no experiment with this RID is " raise ValueError("no experiment with this RID is "
"waiting for interactive arguments") "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) arglist_desc = [(k, p.describe(), g, t)
for k, p, g, t in interactive_arglist] for k, p, g, t in interactive_arglist]
arguments = ArgumentManager._get_interactive(arglist_desc, title) arguments = ArgumentManager._get_interactive(arglist_desc, title)
for key, processor, _, _ in interactive_arglist: if arguments is not None:
arguments[key] = processor.process(arguments[key]) for key, processor, _, _ in interactive_arglist:
arguments[key] = processor.process(arguments[key])
return arguments return arguments