Source code for robot.model.control

#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#
#  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.

from robot.utils import setter

from .body import Body, BodyItem, Branches
from .keyword import Keywords


[docs]@Body.register class For(BodyItem): type = BodyItem.FOR body_class = Body repr_args = ('variables', 'flavor', 'values') __slots__ = ['variables', 'flavor', 'values'] def __init__(self, variables=(), flavor='IN', values=(), parent=None): self.variables = variables self.flavor = flavor self.values = values self.parent = parent self.body = None @setter def body(self, body): return self.body_class(self, body) @property def keywords(self): """Deprecated since Robot Framework 4.0. Use :attr:`body` instead.""" return Keywords(self, self.body) @keywords.setter def keywords(self, keywords): Keywords.raise_deprecation_error()
[docs] def visit(self, visitor): visitor.visit_for(self)
def __str__(self): variables = ' '.join(self.variables) values = ' '.join(self.values) return 'FOR %s %s %s' % (variables, self.flavor, values)
[docs]@Body.register class While(BodyItem): type = BodyItem.WHILE body_class = Body repr_args = ('condition', 'limit') __slots__ = ['condition', 'limit'] def __init__(self, condition=None, limit=None, parent=None): self.condition = condition self.limit = limit self.parent = parent self.body = None @setter def body(self, body): return self.body_class(self, body)
[docs] def visit(self, visitor): visitor.visit_while(self)
def __str__(self): return f'WHILE {self.condition}' + (f' {self.limit}' if self.limit else '')
[docs]class IfBranch(BodyItem): body_class = Body repr_args = ('type', 'condition') __slots__ = ['type', 'condition'] def __init__(self, type=BodyItem.IF, condition=None, parent=None): self.type = type self.condition = condition self.parent = parent self.body = None @setter def body(self, body): return self.body_class(self, body) @property def id(self): """Branch id omits IF/ELSE root from the parent id part.""" if not self.parent: return 'k1' if not self.parent.parent: return 'k%d' % (self.parent.body.index(self) + 1) return self._get_id(self.parent.parent) def __str__(self): if self.type == self.IF: return 'IF %s' % self.condition if self.type == self.ELSE_IF: return 'ELSE IF %s' % self.condition return 'ELSE'
[docs] def visit(self, visitor): visitor.visit_if_branch(self)
[docs]@Body.register class If(BodyItem): """IF/ELSE structure root. Branches are stored in :attr:`body`.""" type = BodyItem.IF_ELSE_ROOT branch_class = IfBranch branches_class = Branches __slots__ = ['parent'] def __init__(self, parent=None): self.parent = parent self.body = None @setter def body(self, branches): return self.branches_class(self.branch_class, self, branches) @property def id(self): """Root IF/ELSE id is always ``None``.""" return None
[docs] def visit(self, visitor): visitor.visit_if(self)
[docs]class TryBranch(BodyItem): body_class = Body repr_args = ('type', 'patterns', 'pattern_type', 'variable') __slots__ = ['type', 'patterns', 'pattern_type', 'variable'] def __init__(self, type=BodyItem.TRY, patterns=(), pattern_type=None, variable=None, parent=None): if (patterns or pattern_type or variable) and type != BodyItem.EXCEPT: raise TypeError(f"'{type}' branches do not accept patterns or variables.") self.type = type self.patterns = patterns self.pattern_type = pattern_type self.variable = variable self.parent = parent self.body = None @setter def body(self, body): return self.body_class(self, body) @property def id(self): """Branch id omits TRY/EXCEPT root from the parent id part.""" if not self.parent: return 'k1' if not self.parent.parent: return 'k%d' % (self.parent.body.index(self) + 1) return self._get_id(self.parent.parent) def __str__(self): if self.type != BodyItem.EXCEPT: return self.type parts = ['EXCEPT'] + list(self.patterns) if self.pattern_type: parts.append(f'type={self.pattern_type}') if self.variable: parts.extend(['AS', self.variable]) return ' '.join(parts) def __repr__(self): repr_args = self.repr_args if self.type == BodyItem.EXCEPT else ['type'] return self._repr(repr_args)
[docs] def visit(self, visitor): visitor.visit_try_branch(self)
[docs]@Body.register class Try(BodyItem): """TRY/EXCEPT structure root. Branches are stored in :attr:`body`.""" type = BodyItem.TRY_EXCEPT_ROOT branch_class = TryBranch branches_class = Branches __slots__ = [] def __init__(self, parent=None): self.parent = parent self.body = None @setter def body(self, branches): return self.branches_class(self.branch_class, self, branches) @property def try_branch(self): if self.body and self.body[0].type == BodyItem.TRY: return self.body[0] raise TypeError("No 'TRY' branch or 'TRY' branch is not first.") @property def except_branches(self): return [branch for branch in self.body if branch.type == BodyItem.EXCEPT] @property def else_branch(self): for branch in self.body: if branch.type == BodyItem.ELSE: return branch return None @property def finally_branch(self): if self.body and self.body[-1].type == BodyItem.FINALLY: return self.body[-1] return None @property def id(self): """Root TRY/EXCEPT id is always ``None``.""" return None
[docs] def visit(self, visitor): visitor.visit_try(self)
[docs]@Body.register class Return(BodyItem): type = BodyItem.RETURN repr_args = ('values',) __slots__ = ['values'] def __init__(self, values=(), parent=None): self.values = values self.parent = parent
[docs] def visit(self, visitor): visitor.visit_return(self)
[docs]@Body.register class Continue(BodyItem): type = BodyItem.CONTINUE __slots__ = [] def __init__(self, parent=None): self.parent = parent
[docs] def visit(self, visitor): visitor.visit_continue(self)
[docs]@Body.register class Break(BodyItem): type = BodyItem.BREAK __slots__ = [] def __init__(self, parent=None): self.parent = parent
[docs] def visit(self, visitor): visitor.visit_break(self)