diff --git a/colcon_core/argument_parser/__init__.py b/colcon_core/argument_parser/__init__.py index e2b9045c..e5161bb7 100644 --- a/colcon_core/argument_parser/__init__.py +++ b/colcon_core/argument_parser/__init__.py @@ -3,6 +3,7 @@ import traceback import types +import warnings from colcon_core.logging import colcon_logger from colcon_core.plugin_system import instantiate_extensions @@ -108,11 +109,23 @@ def __init__(self, parser, **kwargs): """ assert '_parser' not in kwargs kwargs['_parser'] = parser - assert '_nested_decorators' not in kwargs - kwargs['_nested_decorators'] = [] + assert '_nested_decorators_' not in kwargs + kwargs['_nested_decorators_'] = [] + assert '_group_decorators' not in kwargs + kwargs['_group_decorators'] = [] + assert '_recursive_decorators' not in kwargs + kwargs['_recursive_decorators'] = [] for k, v in kwargs.items(): self.__dict__[k] = v + @property + def _nested_decorators(self): + warnings.warn( + 'colcon_core.argument_parser.ArgumentParserDecorator.' + '_nested_decorators is a private variable and has been ' + 'deprecated', stacklevel=2) + return self._nested_decorators_ + def __getattr__(self, name): """ Get an attribute from this decorator if it exists or the decoree. @@ -157,7 +170,8 @@ def add_argument_group(self, *args, **kwargs): """ group = self.__class__( self._parser.add_argument_group(*args, **kwargs)) - self._nested_decorators.append(group) + self._nested_decorators_.append(group) + self._group_decorators.append(group) return group def add_mutually_exclusive_group(self, *args, **kwargs): @@ -169,7 +183,8 @@ def add_mutually_exclusive_group(self, *args, **kwargs): """ group = self.__class__( self._parser.add_mutually_exclusive_group(*args, **kwargs)) - self._nested_decorators.append(group) + self._nested_decorators_.append(group) + self._group_decorators.append(group) return group def add_parser(self, *args, **kwargs): @@ -181,7 +196,8 @@ def add_parser(self, *args, **kwargs): """ parser = self.__class__( self._parser.add_parser(*args, **kwargs)) - self._nested_decorators.append(parser) + self._nested_decorators_.append(parser) + self._recursive_decorators.append(parser) return parser def add_subparsers(self, *args, **kwargs): @@ -193,7 +209,8 @@ def add_subparsers(self, *args, **kwargs): """ subparser = self.__class__( self._parser.add_subparsers(*args, **kwargs)) - self._nested_decorators.append(subparser) + self._nested_decorators_.append(subparser) + self._recursive_decorators.append(subparser) return subparser diff --git a/colcon_core/argument_parser/destination_collector.py b/colcon_core/argument_parser/destination_collector.py index 52a542a7..55e729f7 100644 --- a/colcon_core/argument_parser/destination_collector.py +++ b/colcon_core/argument_parser/destination_collector.py @@ -22,17 +22,23 @@ def __init__(self, parser, **kwargs): _destinations=OrderedDict(), **kwargs) - def get_destinations(self): + def get_destinations(self, *, recursive=True): """ Get destinations for all added arguments. + :param bool recursive: The flag if destinations from added parsers / + subparsers should be included, destinations from grouped arguments + are always included :returns: The destination names :rtype: OrderedDict """ destinations = OrderedDict() destinations.update(self._destinations) - for d in self._nested_decorators: + for d in self._group_decorators: destinations.update(d.get_destinations()) + if recursive: + for d in self._recursive_decorators: + destinations.update(d.get_destinations()) return destinations def add_argument(self, *args, **kwargs): diff --git a/test/spell_check.words b/test/spell_check.words index cceac5b8..614b2c4c 100644 --- a/test/spell_check.words +++ b/test/spell_check.words @@ -42,6 +42,7 @@ setuppy setuptools sigint stdeb +subparser subparsers symlink sysconfig diff --git a/test/test_destination_collector.py b/test/test_destination_collector.py index 615d4a71..0d4e18cd 100644 --- a/test/test_destination_collector.py +++ b/test/test_destination_collector.py @@ -21,3 +21,12 @@ def test_destination_collector_decorator(): group.add_argument('--other-option', action='store_true') assert decorator.get_destinations() == OrderedDict([ ('option', 'option'), ('other-option', 'other_option')]) + + subparser = decorator.add_subparsers(title='subs', dest='dest') + parser = subparser.add_parser('parser') + parser.add_argument('--another-option', action='store_true') + assert decorator.get_destinations() == OrderedDict([ + ('option', 'option'), ('other-option', 'other_option'), + ('another-option', 'another_option')]) + assert decorator.get_destinations(recursive=False) == OrderedDict([ + ('option', 'option'), ('other-option', 'other_option')])