From e26506744d37774e7245e9727502fd5cdbfa1194 Mon Sep 17 00:00:00 2001 From: Daniel Hollas Date: Wed, 11 Oct 2023 16:02:25 +0000 Subject: [PATCH] FIX: Do not evaluate callable defaults during tab-completion --- aiida/cmdline/params/options/__init__.py | 2 ++ aiida/cmdline/params/options/callable.py | 34 +++++++++++++++++++++ aiida/cmdline/params/options/interactive.py | 2 +- aiida/cmdline/params/options/main.py | 2 ++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 aiida/cmdline/params/options/callable.py diff --git a/aiida/cmdline/params/options/__init__.py b/aiida/cmdline/params/options/__init__.py index b509d4e0ba..e5dd70f91b 100644 --- a/aiida/cmdline/params/options/__init__.py +++ b/aiida/cmdline/params/options/__init__.py @@ -14,6 +14,7 @@ # yapf: disable # pylint: disable=wildcard-import +from .callable import * from .config import * from .main import * from .multivalue import * @@ -39,6 +40,7 @@ 'COMPUTER', 'COMPUTERS', 'CONFIG_FILE', + 'CallableDefaultOption', 'ConfigFileOption', 'DATA', 'DATUM', diff --git a/aiida/cmdline/params/options/callable.py b/aiida/cmdline/params/options/callable.py new file mode 100644 index 0000000000..4fde0e96b6 --- /dev/null +++ b/aiida/cmdline/params/options/callable.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +########################################################################### +# Copyright (c), The AiiDA team. All rights reserved. # +# This file is part of the AiiDA code. # +# # +# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # +# For further information on the license, see the LICENSE.txt file # +# For further information please visit http://www.aiida.net # +########################################################################### +""" +.. py:module::callable + :synopsis: A monkey-patched subclass of click.Option that does not evaluate callable default during tab completion +""" + +import typing as t + +import click + +__all__ = ('CallableDefaultOption',) + + +class CallableDefaultOption(click.Option): + """A monkeypatch for click.Option that does not evaluate default callbacks during tab completion + + This is a temporary solution until a proper fix is implemented in click, see: + https://github.com/pallets/click/issues/2614 + """ + + def get_default(self, ctx: click.Context, call: bool = True) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """provides the functionality of :meth:`click.Option.get_default`, + but ensures we do not evaluate callable defaults when in tab-completion context.""" + if ctx.resilient_parsing: + return None + return super().get_default(ctx=ctx, call=call) diff --git a/aiida/cmdline/params/options/interactive.py b/aiida/cmdline/params/options/interactive.py index 987016d598..f2f5489b56 100644 --- a/aiida/cmdline/params/options/interactive.py +++ b/aiida/cmdline/params/options/interactive.py @@ -158,7 +158,7 @@ def get_default(self, ctx: click.Context, call: bool = True) -> t.Optional[t.Uni if self._contextual_default is not None: default = self._contextual_default(ctx) else: - default = super().get_default(ctx) + default = super().get_default(ctx, call=call) try: default = self.type.deconvert_default(default) diff --git a/aiida/cmdline/params/options/main.py b/aiida/cmdline/params/options/main.py index 60bc1a62de..661b523093 100644 --- a/aiida/cmdline/params/options/main.py +++ b/aiida/cmdline/params/options/main.py @@ -16,6 +16,7 @@ from .. import types from ...utils import defaults, echo # pylint: disable=no-name-in-module +from .callable import CallableDefaultOption from .config import ConfigFileOption from .multivalue import MultipleValueOption from .overridable import OverridableOption @@ -145,6 +146,7 @@ def set_log_level(_ctx, _param, value): 'profile', type=types.ProfileParamType(), default=defaults.get_default_profile, + cls=CallableDefaultOption, help='Execute the command for this profile instead of the default profile.' )