New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement Action conditions #121
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f547732
add Condition class and use in Action class
wjwwood 85414c4
add If and Unless Conditions which use Substitutions
wjwwood 19ab52f
update actions to pass through condition arguments to Action base class
wjwwood 4e08ee4
fixup type annotations in ExecuteProcess action
wjwwood a65e6db
fixup architecture doc
wjwwood 3196ae9
address flake8 failure that doesn't show locally for me
wjwwood File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Copyright 2018 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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 Condition class.""" | ||
|
||
from typing import Callable | ||
from typing import Optional | ||
from typing import Text | ||
|
||
from .launch_context import LaunchContext | ||
|
||
|
||
class Condition: | ||
""" | ||
Encapsulates a condition to be evaluated when launching. | ||
|
||
The given predicate receives a launch context and is evaluated while | ||
launching, but must return True or False. | ||
|
||
If a predicate is not set when evaluated, False is returned. | ||
""" | ||
|
||
def __init__(self, *, predicate: Optional[Callable[[LaunchContext], bool]] = None) -> None: | ||
self._predicate = predicate | ||
|
||
def describe(self) -> Text: | ||
"""Return a description of this Condition.""" | ||
return self.__repr__() | ||
|
||
def evaluate(self, context: LaunchContext) -> bool: | ||
"""Evaluate the condition.""" | ||
if self._predicate is not None: | ||
return self._predicate(context) | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Copyright 2018 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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. | ||
|
||
"""conditions Module.""" | ||
|
||
from .evaluate_condition_expression_impl import evaluate_condition_expression | ||
from .if_condition import IfCondition | ||
from .invalid_condition_expression_error import InvalidConditionExpressionError | ||
from .unless_condition import UnlessCondition | ||
|
||
__all__ = [ | ||
'evaluate_condition_expression', | ||
'IfCondition', | ||
'InvalidConditionExpressionError', | ||
'UnlessCondition', | ||
] |
48 changes: 48 additions & 0 deletions
48
launch/launch/conditions/evaluate_condition_expression_impl.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Copyright 2018 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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 utility functions related to evaluating condition expressions.""" | ||
|
||
from typing import List | ||
|
||
from .invalid_condition_expression_error import InvalidConditionExpressionError | ||
from ..launch_context import LaunchContext | ||
from ..substitution import Substitution | ||
from ..utilities import perform_substitutions | ||
|
||
|
||
VALID_TRUE_EXPRESSIONS = ['true', '1'] | ||
VALID_FALSE_EXPRESSIONS = ['false', '0'] | ||
|
||
|
||
def evaluate_condition_expression(context: LaunchContext, expression: List[Substitution]) -> bool: | ||
""" | ||
Expand an expression and then evaluate it as a condition, returing true or false. | ||
|
||
The expanded expression is stripped and has ``lower()`` called on it before | ||
being logically evaluated as either true or false. | ||
A string will be considered True if it matches 'true' or '1'. | ||
A string will be considered False if it matches 'false' or '0'. | ||
Any other string content (including empty string) will result in an error. | ||
|
||
:raises: InvalidConditionExpressionError | ||
""" | ||
expanded_expression = perform_substitutions(context, expression) | ||
expanded_expression = expanded_expression.strip().lower() | ||
if expanded_expression in ['true', '1']: | ||
return True | ||
if expanded_expression in ['false', '0']: | ||
return False | ||
valid_expressions = VALID_TRUE_EXPRESSIONS + VALID_FALSE_EXPRESSIONS | ||
raise InvalidConditionExpressionError(expanded_expression, expression, valid_expressions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Copyright 2018 Open Source Robotics Foundation, Inc. | ||
# | ||
# 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 IfCondition class.""" | ||
|
||
from typing import Text | ||
|
||
from .evaluate_condition_expression_impl import evaluate_condition_expression | ||
from ..condition import Condition | ||
from ..launch_context import LaunchContext | ||
from ..some_substitutions_type import SomeSubstitutionsType | ||
from ..utilities import normalize_to_list_of_substitutions | ||
|
||
|
||
class IfCondition(Condition): | ||
""" | ||
Encapsulates an if condition to be evaluated when launching. | ||
|
||
This condition takes a string expression that is lexically evaluated as a | ||
boolean, but the expression may consist of :py:class:`launch.Substitution` | ||
instances. | ||
|
||
See :py:func:`evaluate_condition_expression` to understand what constitutes | ||
a valid condition expression. | ||
""" | ||
|
||
def __init__(self, predicate_expression: SomeSubstitutionsType) -> None: | ||
self.__predicate_expression = normalize_to_list_of_substitutions(predicate_expression) | ||
super().__init__(predicate=self._predicate_func) | ||
|
||
def _predicate_func(self, context: LaunchContext) -> bool: | ||
return evaluate_condition_expression(context, self.__predicate_expression) | ||
|
||
def describe(self) -> Text: | ||
"""Return a description of this Condition.""" | ||
return self.__repr__() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is F401 needed here, looks like you are using Tuple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we have to support python 3.5, we cannot use the type annotation for member variables syntax which was added in 3.6. So we use the type comment, which is the only place I use Tuple. So flake8 doesn’t count that as using it so I suppressed the unused import warning.