Source code for robot.running.keywordimplementation

#  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 pathlib import Path
from typing import Any, Literal, Mapping, Sequence, TYPE_CHECKING

from robot.model import ModelObject, Tags
from robot.utils import eq, getshortdoc, setter

from .arguments import ArgInfo, ArgumentSpec, EmbeddedArguments
from .model import BodyItemParent, Keyword

if TYPE_CHECKING:
    from robot.conf import LanguagesLike

    from .librarykeywordrunner import LibraryKeywordRunner
    from .resourcemodel import ResourceFile
    from .testlibraries import TestLibrary
    from .userkeywordrunner import UserKeywordRunner


[docs] class KeywordImplementation(ModelObject): """Base class for different keyword implementations.""" USER_KEYWORD = "USER KEYWORD" LIBRARY_KEYWORD = "LIBRARY KEYWORD" INVALID_KEYWORD = "INVALID KEYWORD" type: Literal["USER KEYWORD", "LIBRARY KEYWORD", "INVALID KEYWORD"] repr_args = ("name", "args") __slots__ = ("_name", "embedded", "_doc", "_lineno", "owner", "parent", "error") def __init__( self, name: str = "", args: "ArgumentSpec|None" = None, doc: str = "", tags: "Tags|Sequence[str]" = (), lineno: "int|None" = None, owner: "ResourceFile|TestLibrary|None" = None, parent: "BodyItemParent|None" = None, error: "str|None" = None, ): self._name = name self.embedded = self._get_embedded(name) self.args = args self._doc = doc self.tags = tags self._lineno = lineno self.owner = owner self.parent = parent self.error = error def _get_embedded(self, name) -> "EmbeddedArguments|None": return EmbeddedArguments.from_name(name) @property def name(self) -> str: return self._name @name.setter def name(self, name: str): self.embedded = self._get_embedded(name) if self.owner and self._name: self.owner.keyword_finder.invalidate_cache() self._name = name @property def full_name(self) -> str: if self.owner and self.owner.name: return f"{self.owner.name}.{self.name}" return self.name @setter def args(self, spec: "ArgumentSpec|None") -> ArgumentSpec: """Information about accepted arguments. It would be more correct to use term *parameter* instead of *argument* in this context, and this attribute may be renamed accordingly in the future. A forward compatible :attr:`params` attribute exists already now. """ if spec is None: spec = ArgumentSpec() spec.name = lambda: self.full_name return spec @property def params(self) -> ArgumentSpec: """Keyword parameter information. This is a forward compatible alias for :attr:`args`. """ return self.args @property def doc(self) -> str: return self._doc @doc.setter def doc(self, doc: str): self._doc = doc @property def short_doc(self) -> str: return getshortdoc(self.doc) @setter def tags(self, tags: "Tags|Sequence[str]") -> Tags: return Tags(tags) @property def lineno(self) -> "int|None": return self._lineno @lineno.setter def lineno(self, lineno: "int|None"): self._lineno = lineno @property def private(self) -> bool: return bool(self.tags and self.tags.robot("private")) @property def source(self) -> "Path|None": return self.owner.source if self.owner is not None else None
[docs] def matches(self, name: str) -> bool: """Returns true if ``name`` matches the keyword name. With normal keywords matching is a case, space and underscore insensitive string comparison. With keywords accepting embedded arguments, matching is done against the name. """ if self.embedded: return self.embedded.matches(name) return eq(self.name, name, ignore="_")
[docs] def resolve_arguments( self, args: "Sequence[str|Any]", named_args: "Mapping[str, Any]|None" = None, variables=None, languages: "LanguagesLike" = None, ) -> "tuple[list, list]": return self.args.resolve(args, named_args, variables, languages=languages)
[docs] def create_runner( self, name: "str|None", languages: "LanguagesLike" = None, ) -> "LibraryKeywordRunner|UserKeywordRunner": raise NotImplementedError
[docs] def bind(self, data: Keyword) -> "KeywordImplementation": raise NotImplementedError
def _include_in_repr(self, name: str, value: Any) -> bool: return name == "name" or value def _repr_format(self, name: str, value: Any) -> str: if name == "args": value = [self._decorate_arg(a) for a in self.args] return super()._repr_format(name, value) def _decorate_arg(self, arg: ArgInfo) -> str: return str(arg)