Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions launch/launch/actions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

"""actions Module."""

from .declare_boolean_launch_argument import DeclareBooleanLaunchArgument
from .declare_launch_argument import DeclareLaunchArgument
from .append_environment_variable import AppendEnvironmentVariable # noqa: I100
from .emit_event import EmitEvent
Expand Down Expand Up @@ -49,6 +50,7 @@
__all__ = [
'AppendEnvironmentVariable',
'DeclareLaunchArgument',
'DeclareBooleanLaunchArgument',
'EmitEvent',
'ExecuteLocal',
'ExecuteProcess',
Expand Down
84 changes: 84 additions & 0 deletions launch/launch/actions/declare_boolean_launch_argument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Copyright 2026 Metro Robots
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Module for the DeclareBooleanLaunchArgument action."""

from typing import Any
from typing import Dict
from typing import Optional
from typing import Text
from typing import Tuple
from typing import Type

from .declare_launch_argument import DeclareLaunchArgument
from ..frontend import Entity
from ..frontend import expose_action
from ..frontend import Parser # noqa: F401
from ..some_substitutions_type import SomeSubstitutionsType


@expose_action('bool_arg')
class DeclareBooleanLaunchArgument(DeclareLaunchArgument):
"""
Action that declares a new boolean launch argument.

This is a bit of syntactic sugar for
:py:class:`launch.actions.DeclareLaunchArgument`
that sets the choices to be either true or false (caps-insensitive)

.. doctest::

>>> ld = LaunchDescription([
... DeclareBooleanLaunchArgument('simple_argument'), # default value is False
... DeclareBooleanLaunchArgument('with_default_value', default_value=True),
... # other actions here, ...
... ])

.. code-block:: xml

<launch>
<bool_arg name="simple_argument"/>
<bool_arg name="with_default_value" default_value="true"/>
</launch>
"""

def __init__(
self,
name: Text,
*,
default_value: Optional[SomeSubstitutionsType | bool] = None,
**kwargs: Any
) -> None:
"""Create a DeclareBooleanLaunchArgument action."""
super().__init__(
name=name,
default_value=(default_value if not isinstance(default_value, bool)
else str(default_value)),
choices=['true', 'false', 'True', 'False'],
**kwargs
)

@classmethod
def parse(
cls,
entity: Entity,
parser: 'Parser'
) -> Tuple[Type['DeclareBooleanLaunchArgument'], Dict[str, Any]]:
"""Parse `bool_arg` tag."""
_, kwargs = super().parse(entity, parser)

if 'choices' in kwargs:
raise ValueError('Cannot specify choices for bool_arg')

return cls, kwargs
46 changes: 46 additions & 0 deletions launch/test/launch/actions/test_declare_boolean_launch_argument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2026 Metro Robots
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests for the DeclareBooleanLaunchArgument action class."""

# from launch import LaunchContext
from launch.actions import DeclareBooleanLaunchArgument

import pytest


def test_declare_launch_argument_constructors():
"""Test the constructors for DeclareLaunchArgument class."""
DeclareBooleanLaunchArgument('name')

# All possible default values
DeclareBooleanLaunchArgument('name', default_value='True')
DeclareBooleanLaunchArgument('name', default_value='true')
DeclareBooleanLaunchArgument('name', default_value='False')
DeclareBooleanLaunchArgument('name', default_value='false')
DeclareBooleanLaunchArgument('name', default_value=True)
DeclareBooleanLaunchArgument('name', default_value=False)

# With description
DeclareBooleanLaunchArgument('name', description='description')

# With invalid default value
with pytest.raises(RuntimeError) as excinfo:
DeclareBooleanLaunchArgument('name', default_value='invalid')
assert 'not in provided choices' in str(excinfo.value)

# With invalid choices override
with pytest.raises(TypeError) as excinfo:
DeclareBooleanLaunchArgument('name', choices=['verdad', 'no verdad'])
assert "multiple values for keyword argument 'choices'" in str(excinfo.value)