Skip to content

resourcemodel

Import

Bases: ModelObject

Represents library, resource file or variable file import.

Source code in src/robot/running/resourcemodel.py
class Import(ModelObject):
    """Represents library, resource file or variable file import."""
    repr_args = ('type', 'name', 'args', 'alias')
    LIBRARY = 'LIBRARY'
    RESOURCE = 'RESOURCE'
    VARIABLES = 'VARIABLES'

    def __init__(self, type: Literal['LIBRARY', 'RESOURCE', 'VARIABLES'],
                 name: str,
                 args: Sequence[str] = (),
                 alias: 'str|None' = None,
                 owner: 'ResourceFile|None' = None,
                 lineno: 'int|None' = None):
        if type not in (self.LIBRARY, self.RESOURCE, self.VARIABLES):
            raise ValueError(f"Invalid import type: Expected '{self.LIBRARY}', "
                             f"'{self.RESOURCE}' or '{self.VARIABLES}', got '{type}'.")
        self.type = type
        self.name = name
        self.args = tuple(args)
        self.alias = alias
        self.owner = owner
        self.lineno = lineno

    @property
    def source(self) -> 'Path|None':
        return self.owner.source if self.owner is not None else None

    @property
    def directory(self) -> 'Path|None':
        source = self.source
        return source.parent if source and not source.is_dir() else source

    @property
    def setting_name(self) -> str:
        return self.type.title()

    def select(self, library: Any, resource: Any, variables: Any) -> Any:
        return {self.LIBRARY: library,
                self.RESOURCE: resource,
                self.VARIABLES: variables}[self.type]

    def report_error(self, message: str, level: str = 'ERROR'):
        source = self.source or '<unknown>'
        line = f' on line {self.lineno}' if self.lineno else ''
        LOGGER.write(f"Error in file '{source}'{line}: {message}", level)

    @classmethod
    def from_dict(cls, data) -> 'Import':
        return cls(**data)

    def to_dict(self) -> DataDict:
        data: DataDict = {'type': self.type, 'name': self.name}
        if self.args:
            data['args'] = self.args
        if self.alias:
            data['alias'] = self.alias
        if self.lineno:
            data['lineno'] = self.lineno
        return data

    def _include_in_repr(self, name: str, value: Any) -> bool:
        return name in ('type', 'name') or value

config(**attributes)

Configure model object with given attributes.

obj.config(name='Example', doc='Something') is equivalent to setting obj.name = 'Example' and obj.doc = 'Something'.

New in Robot Framework 4.0.

Source code in src/robot/model/modelobject.py
def config(self: T, **attributes) -> T:
    """Configure model object with given attributes.

    ``obj.config(name='Example', doc='Something')`` is equivalent to setting
    ``obj.name = 'Example'`` and ``obj.doc = 'Something'``.

    New in Robot Framework 4.0.
    """
    for name, value in attributes.items():
        try:
            orig = getattr(self, name)
        except AttributeError:
            raise AttributeError(f"'{full_name(self)}' object does not have "
                                 f"attribute '{name}'")
        # Preserve tuples. Main motivation is converting lists with `from_json`.
        if isinstance(orig, tuple) and not isinstance(value, tuple):
            try:
                value = tuple(value)
            except TypeError:
                raise TypeError(f"'{full_name(self)}' object attribute '{name}' "
                                f"is 'tuple', got '{type_name(value)}'.")
        try:
            setattr(self, name, value)
        except AttributeError as err:
            # Ignore error setting attribute if the object already has it.
            # Avoids problems with `from_dict` with body items having
            # un-settable `type` attribute that is needed in dict data.
            if value != orig:
                raise AttributeError(f"Setting attribute '{name}' failed: {err}")
    return self

copy(**attributes)

Return a shallow copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.copy(name='New name').

See also :meth:deepcopy. The difference between copy and deepcopy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def copy(self: T, **attributes) -> T:
    """Return a shallow copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.copy(name='New name')``.

    See also :meth:`deepcopy`. The difference between ``copy`` and
    ``deepcopy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.copy(self).config(**attributes)

deepcopy(**attributes)

Return a deep copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.deepcopy(name='New name').

See also :meth:copy. The difference between deepcopy and copy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def deepcopy(self: T, **attributes) -> T:
    """Return a deep copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.deepcopy(name='New name')``.

    See also :meth:`copy`. The difference between ``deepcopy`` and
    ``copy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.deepcopy(self).config(**attributes)

from_json(source) classmethod

Create this object based on JSON data.

The data is given as the source parameter. It can be:

  • a string (or bytes) containing the data directly,
  • an open file object where to read the data from, or
  • a path (pathlib.Path or string) to a UTF-8 encoded file to read.

The JSON data is first converted to a Python dictionary and the object created using the :meth:from_dict method.

Notice that the source is considered to be JSON data if it is a string and contains {. If you need to use { in a file system path, pass it in as a pathlib.Path instance.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

Source code in src/robot/model/modelobject.py
@classmethod
def from_json(cls: Type[T], source: 'str|bytes|TextIO|Path') -> T:
    """Create this object based on JSON data.

    The data is given as the ``source`` parameter. It can be:

    - a string (or bytes) containing the data directly,
    - an open file object where to read the data from, or
    - a path (``pathlib.Path`` or string) to a UTF-8 encoded file to read.

    The JSON data is first converted to a Python dictionary and the object
    created using the :meth:`from_dict` method.

    Notice that the ``source`` is considered to be JSON data if it is
    a string and contains ``{``. If you need to use ``{`` in a file system
    path, pass it in as a ``pathlib.Path`` instance.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.
    """
    try:
        data = JsonLoader().load(source)
    except (TypeError, ValueError) as err:
        raise DataError(f'Loading JSON data failed: {err}')
    return cls.from_dict(data)

to_json(file=None, *, ensure_ascii=False, indent=0, separators=(',', ':'))

Serialize this object into JSON.

The object is first converted to a Python dictionary using the :meth:to_dict method and then the dictionary is converted to JSON.

The file parameter controls what to do with the resulting JSON data. It can be:

  • None (default) to return the data as a string,
  • an open file object where to write the data to, or
  • a path (pathlib.Path or string) to a file where to write the data using UTF-8 encoding.

JSON formatting can be configured using optional parameters that are passed directly to the underlying json__ module. Notice that the defaults differ from what json uses.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

__ https://docs.python.org/3/library/json.html

Source code in src/robot/model/modelobject.py
def to_json(self, file: 'None|TextIO|Path|str' = None, *,
            ensure_ascii: bool = False, indent: int = 0,
            separators: 'tuple[str, str]' = (',', ':')) -> 'str|None':
    """Serialize this object into JSON.

    The object is first converted to a Python dictionary using the
    :meth:`to_dict` method and then the dictionary is converted to JSON.

    The ``file`` parameter controls what to do with the resulting JSON data.
    It can be:

    - ``None`` (default) to return the data as a string,
    - an open file object where to write the data to, or
    - a path (``pathlib.Path`` or string) to a file where to write
      the data using UTF-8 encoding.

    JSON formatting can be configured using optional parameters that
    are passed directly to the underlying json__ module. Notice that
    the defaults differ from what ``json`` uses.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.

    __ https://docs.python.org/3/library/json.html
    """
    return JsonDumper(ensure_ascii=ensure_ascii, indent=indent,
                      separators=separators).dump(self.to_dict(), file)

Imports

Bases: ItemList

Source code in src/robot/running/resourcemodel.py
class Imports(model.ItemList):

    def __init__(self, owner: ResourceFile, imports: Sequence[Import] = ()):
        super().__init__(Import, {'owner': owner}, items=imports)

    def library(self, name: str, args: Sequence[str] = (), alias: 'str|None' = None,
                lineno: 'int|None' = None) -> Import:
        """Create library import."""
        return self.create(Import.LIBRARY, name, args, alias, lineno=lineno)

    def resource(self, name: str, lineno: 'int|None' = None) -> Import:
        """Create resource import."""
        return self.create(Import.RESOURCE, name, lineno=lineno)

    def variables(self, name: str, args: Sequence[str] = (),
                  lineno: 'int|None' = None) -> Import:
        """Create variables import."""
        return self.create(Import.VARIABLES, name, args, lineno=lineno)

    def create(self, *args, **kwargs) -> Import:
        """Generic method for creating imports.

        Import type specific methods :meth:`library`, :meth:`resource` and
        :meth:`variables` are recommended over this method.
        """
        # RF 6.1 changed types to upper case. Code below adds backwards compatibility.
        if args:
            args = (args[0].upper(),) + args[1:]
        elif 'type' in kwargs:
            kwargs['type'] = kwargs['type'].upper()
        return super().create(*args, **kwargs)

create(*args, **kwargs)

Generic method for creating imports.

Import type specific methods :meth:library, :meth:resource and :meth:variables are recommended over this method.

Source code in src/robot/running/resourcemodel.py
def create(self, *args, **kwargs) -> Import:
    """Generic method for creating imports.

    Import type specific methods :meth:`library`, :meth:`resource` and
    :meth:`variables` are recommended over this method.
    """
    # RF 6.1 changed types to upper case. Code below adds backwards compatibility.
    if args:
        args = (args[0].upper(),) + args[1:]
    elif 'type' in kwargs:
        kwargs['type'] = kwargs['type'].upper()
    return super().create(*args, **kwargs)

library(name, args=(), alias=None, lineno=None)

Create library import.

Source code in src/robot/running/resourcemodel.py
def library(self, name: str, args: Sequence[str] = (), alias: 'str|None' = None,
            lineno: 'int|None' = None) -> Import:
    """Create library import."""
    return self.create(Import.LIBRARY, name, args, alias, lineno=lineno)

resource(name, lineno=None)

Create resource import.

Source code in src/robot/running/resourcemodel.py
def resource(self, name: str, lineno: 'int|None' = None) -> Import:
    """Create resource import."""
    return self.create(Import.RESOURCE, name, lineno=lineno)

to_dicts()

Return list of items converted to dictionaries.

Items are converted to dictionaries using the to_dict method, if they have it, or the built-in vars().

New in Robot Framework 6.1.

Source code in src/robot/model/itemlist.py
def to_dicts(self) -> 'list[DataDict]':
    """Return list of items converted to dictionaries.

    Items are converted to dictionaries using the ``to_dict`` method, if
    they have it, or the built-in ``vars()``.

    New in Robot Framework 6.1.
    """
    if not hasattr(self._item_class, 'to_dict'):
        return [vars(item) for item in self]
    return [item.to_dict() for item in self]    # type: ignore

variables(name, args=(), lineno=None)

Create variables import.

Source code in src/robot/running/resourcemodel.py
def variables(self, name: str, args: Sequence[str] = (),
              lineno: 'int|None' = None) -> Import:
    """Create variables import."""
    return self.create(Import.VARIABLES, name, args, lineno=lineno)

ResourceFile

Bases: ModelObject

Represents a resource file.

Source code in src/robot/running/resourcemodel.py
class ResourceFile(ModelObject):
    """Represents a resource file."""

    repr_args = ('source',)
    __slots__ = ('_source', 'owner', 'doc', 'keyword_finder')

    def __init__(self, source: 'Path|str|None' = None,
                 owner: 'TestSuite|None' = None,
                 doc: str = ''):
        self.source = source
        self.owner = owner
        self.doc = doc
        self.keyword_finder = KeywordFinder['UserKeyword'](self)
        self.imports = []
        self.variables = []
        self.keywords = []

    @property
    def source(self) -> 'Path|None':
        if self._source:
            return self._source
        if self.owner:
            return self.owner.source
        return None

    @source.setter
    def source(self, source: 'Path|str|None'):
        if isinstance(source, str):
            source = Path(source)
        self._source = source

    @property
    def name(self) -> 'str|None':
        """Resource file name.

        ``None`` if resource file is part of a suite or if it does not have
        :attr:`source`, name of the source file without the extension otherwise.
        """
        if self.owner or not self.source:
            return None
        return self.source.stem

    @setter
    def imports(self, imports: Sequence['Import']) -> 'Imports':
        return Imports(self, imports)

    @setter
    def variables(self, variables: Sequence['Variable']) -> 'Variables':
        return Variables(self, variables)

    @setter
    def keywords(self, keywords: Sequence['UserKeyword']) -> 'UserKeywords':
        return UserKeywords(self, keywords)

    @classmethod
    def from_file_system(cls, path: 'Path|str', **config) -> 'ResourceFile':
        """Create a :class:`ResourceFile` object based on the give ``path``.

        :param path: File path where to read the data from.
        :param config: Configuration parameters for :class:`~.builders.ResourceFileBuilder`
            class that is used internally for building the suite.

        New in Robot Framework 6.1. See also :meth:`from_string` and :meth:`from_model`.
        """
        from .builder import ResourceFileBuilder
        return ResourceFileBuilder(**config).build(path)

    @classmethod
    def from_string(cls, string: str, **config) -> 'ResourceFile':
        """Create a :class:`ResourceFile` object based on the given ``string``.

        :param string: String to create the resource file from.
        :param config: Configuration parameters for
             :func:`~robot.parsing.parser.parser.get_resource_model` used internally.

        New in Robot Framework 6.1. See also :meth:`from_file_system` and
        :meth:`from_model`.
        """
        from robot.parsing import get_resource_model
        model = get_resource_model(string, data_only=True, **config)
        return cls.from_model(model)

    @classmethod
    def from_model(cls, model: 'File') -> 'ResourceFile':
        """Create a :class:`ResourceFile` object based on the given ``model``.

        :param model: Model to create the suite from.

        The model can be created by using the
        :func:`~robot.parsing.parser.parser.get_resource_model` function and possibly
        modified by other tooling in the :mod:`robot.parsing` module.

        New in Robot Framework 6.1. See also :meth:`from_file_system` and
        :meth:`from_string`.
        """
        from .builder import RobotParser
        return RobotParser().parse_resource_model(model)

    @overload
    def find_keywords(self, name: str, count: Literal[1]) -> 'UserKeyword':
        ...

    @overload
    def find_keywords(self, name: str, count: 'int|None' = None) -> 'list[UserKeyword]':
        ...

    def find_keywords(self, name: str, count: 'int|None' = None) \
            -> 'list[UserKeyword]|UserKeyword':
        return self.keyword_finder.find(name, count)

    def to_dict(self) -> DataDict:
        data = {}
        if self._source:
            data['source'] = str(self._source)
        if self.doc:
            data['doc'] = self.doc
        if self.imports:
            data['imports'] = self.imports.to_dicts()
        if self.variables:
            data['variables'] = self.variables.to_dicts()
        if self.keywords:
            data['keywords'] = self.keywords.to_dicts()
        return data

name: str | None property

Resource file name.

None if resource file is part of a suite or if it does not have :attr:source, name of the source file without the extension otherwise.

config(**attributes)

Configure model object with given attributes.

obj.config(name='Example', doc='Something') is equivalent to setting obj.name = 'Example' and obj.doc = 'Something'.

New in Robot Framework 4.0.

Source code in src/robot/model/modelobject.py
def config(self: T, **attributes) -> T:
    """Configure model object with given attributes.

    ``obj.config(name='Example', doc='Something')`` is equivalent to setting
    ``obj.name = 'Example'`` and ``obj.doc = 'Something'``.

    New in Robot Framework 4.0.
    """
    for name, value in attributes.items():
        try:
            orig = getattr(self, name)
        except AttributeError:
            raise AttributeError(f"'{full_name(self)}' object does not have "
                                 f"attribute '{name}'")
        # Preserve tuples. Main motivation is converting lists with `from_json`.
        if isinstance(orig, tuple) and not isinstance(value, tuple):
            try:
                value = tuple(value)
            except TypeError:
                raise TypeError(f"'{full_name(self)}' object attribute '{name}' "
                                f"is 'tuple', got '{type_name(value)}'.")
        try:
            setattr(self, name, value)
        except AttributeError as err:
            # Ignore error setting attribute if the object already has it.
            # Avoids problems with `from_dict` with body items having
            # un-settable `type` attribute that is needed in dict data.
            if value != orig:
                raise AttributeError(f"Setting attribute '{name}' failed: {err}")
    return self

copy(**attributes)

Return a shallow copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.copy(name='New name').

See also :meth:deepcopy. The difference between copy and deepcopy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def copy(self: T, **attributes) -> T:
    """Return a shallow copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.copy(name='New name')``.

    See also :meth:`deepcopy`. The difference between ``copy`` and
    ``deepcopy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.copy(self).config(**attributes)

deepcopy(**attributes)

Return a deep copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.deepcopy(name='New name').

See also :meth:copy. The difference between deepcopy and copy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def deepcopy(self: T, **attributes) -> T:
    """Return a deep copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.deepcopy(name='New name')``.

    See also :meth:`copy`. The difference between ``deepcopy`` and
    ``copy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.deepcopy(self).config(**attributes)

from_dict(data) classmethod

Create this object based on data in a dictionary.

Data can be got from the :meth:to_dict method or created externally.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

Source code in src/robot/model/modelobject.py
@classmethod
def from_dict(cls: Type[T], data: DataDict) -> T:
    """Create this object based on data in a dictionary.

    Data can be got from the :meth:`to_dict` method or created externally.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.
    """
    try:
        return cls().config(**data)
    except (AttributeError, TypeError) as err:
        raise DataError(f"Creating '{full_name(cls)}' object from dictionary "
                        f"failed: {err}")

from_file_system(path, **config) classmethod

Create a :class:ResourceFile object based on the give path.

:param path: File path where to read the data from. :param config: Configuration parameters for :class:~.builders.ResourceFileBuilder class that is used internally for building the suite.

New in Robot Framework 6.1. See also :meth:from_string and :meth:from_model.

Source code in src/robot/running/resourcemodel.py
@classmethod
def from_file_system(cls, path: 'Path|str', **config) -> 'ResourceFile':
    """Create a :class:`ResourceFile` object based on the give ``path``.

    :param path: File path where to read the data from.
    :param config: Configuration parameters for :class:`~.builders.ResourceFileBuilder`
        class that is used internally for building the suite.

    New in Robot Framework 6.1. See also :meth:`from_string` and :meth:`from_model`.
    """
    from .builder import ResourceFileBuilder
    return ResourceFileBuilder(**config).build(path)

from_json(source) classmethod

Create this object based on JSON data.

The data is given as the source parameter. It can be:

  • a string (or bytes) containing the data directly,
  • an open file object where to read the data from, or
  • a path (pathlib.Path or string) to a UTF-8 encoded file to read.

The JSON data is first converted to a Python dictionary and the object created using the :meth:from_dict method.

Notice that the source is considered to be JSON data if it is a string and contains {. If you need to use { in a file system path, pass it in as a pathlib.Path instance.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

Source code in src/robot/model/modelobject.py
@classmethod
def from_json(cls: Type[T], source: 'str|bytes|TextIO|Path') -> T:
    """Create this object based on JSON data.

    The data is given as the ``source`` parameter. It can be:

    - a string (or bytes) containing the data directly,
    - an open file object where to read the data from, or
    - a path (``pathlib.Path`` or string) to a UTF-8 encoded file to read.

    The JSON data is first converted to a Python dictionary and the object
    created using the :meth:`from_dict` method.

    Notice that the ``source`` is considered to be JSON data if it is
    a string and contains ``{``. If you need to use ``{`` in a file system
    path, pass it in as a ``pathlib.Path`` instance.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.
    """
    try:
        data = JsonLoader().load(source)
    except (TypeError, ValueError) as err:
        raise DataError(f'Loading JSON data failed: {err}')
    return cls.from_dict(data)

from_model(model) classmethod

Create a :class:ResourceFile object based on the given model.

:param model: Model to create the suite from.

The model can be created by using the :func:~robot.parsing.parser.parser.get_resource_model function and possibly modified by other tooling in the :mod:robot.parsing module.

New in Robot Framework 6.1. See also :meth:from_file_system and :meth:from_string.

Source code in src/robot/running/resourcemodel.py
@classmethod
def from_model(cls, model: 'File') -> 'ResourceFile':
    """Create a :class:`ResourceFile` object based on the given ``model``.

    :param model: Model to create the suite from.

    The model can be created by using the
    :func:`~robot.parsing.parser.parser.get_resource_model` function and possibly
    modified by other tooling in the :mod:`robot.parsing` module.

    New in Robot Framework 6.1. See also :meth:`from_file_system` and
    :meth:`from_string`.
    """
    from .builder import RobotParser
    return RobotParser().parse_resource_model(model)

from_string(string, **config) classmethod

Create a :class:ResourceFile object based on the given string.

:param string: String to create the resource file from. :param config: Configuration parameters for :func:~robot.parsing.parser.parser.get_resource_model used internally.

New in Robot Framework 6.1. See also :meth:from_file_system and :meth:from_model.

Source code in src/robot/running/resourcemodel.py
@classmethod
def from_string(cls, string: str, **config) -> 'ResourceFile':
    """Create a :class:`ResourceFile` object based on the given ``string``.

    :param string: String to create the resource file from.
    :param config: Configuration parameters for
         :func:`~robot.parsing.parser.parser.get_resource_model` used internally.

    New in Robot Framework 6.1. See also :meth:`from_file_system` and
    :meth:`from_model`.
    """
    from robot.parsing import get_resource_model
    model = get_resource_model(string, data_only=True, **config)
    return cls.from_model(model)

to_json(file=None, *, ensure_ascii=False, indent=0, separators=(',', ':'))

Serialize this object into JSON.

The object is first converted to a Python dictionary using the :meth:to_dict method and then the dictionary is converted to JSON.

The file parameter controls what to do with the resulting JSON data. It can be:

  • None (default) to return the data as a string,
  • an open file object where to write the data to, or
  • a path (pathlib.Path or string) to a file where to write the data using UTF-8 encoding.

JSON formatting can be configured using optional parameters that are passed directly to the underlying json__ module. Notice that the defaults differ from what json uses.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

__ https://docs.python.org/3/library/json.html

Source code in src/robot/model/modelobject.py
def to_json(self, file: 'None|TextIO|Path|str' = None, *,
            ensure_ascii: bool = False, indent: int = 0,
            separators: 'tuple[str, str]' = (',', ':')) -> 'str|None':
    """Serialize this object into JSON.

    The object is first converted to a Python dictionary using the
    :meth:`to_dict` method and then the dictionary is converted to JSON.

    The ``file`` parameter controls what to do with the resulting JSON data.
    It can be:

    - ``None`` (default) to return the data as a string,
    - an open file object where to write the data to, or
    - a path (``pathlib.Path`` or string) to a file where to write
      the data using UTF-8 encoding.

    JSON formatting can be configured using optional parameters that
    are passed directly to the underlying json__ module. Notice that
    the defaults differ from what ``json`` uses.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.

    __ https://docs.python.org/3/library/json.html
    """
    return JsonDumper(ensure_ascii=ensure_ascii, indent=indent,
                      separators=separators).dump(self.to_dict(), file)

UserKeyword

Bases: KeywordImplementation

Represents a user keyword.

Source code in src/robot/running/resourcemodel.py
class UserKeyword(KeywordImplementation):
    """Represents a user keyword."""
    type = KeywordImplementation.USER_KEYWORD
    fixture_class = Keyword
    __slots__ = ['timeout', '_setup', '_teardown']

    def __init__(self, name: str = '',
                 args: 'ArgumentSpec|Sequence[str]|None' = (),
                 doc: str = '',
                 tags: 'Tags|Sequence[str]' = (),
                 timeout: 'str|None' = None,
                 lineno: 'int|None' = None,
                 owner: 'ResourceFile|None' = None,
                 parent: 'BodyItemParent|None' = None,
                 error: 'str|None' = None):
        super().__init__(name, args, doc, tags, lineno, owner, parent, error)
        self.timeout = timeout
        self._setup = None
        self._teardown = None
        self.body = []

    @setter
    def args(self, spec: 'ArgumentSpec|Sequence[str]|None') -> ArgumentSpec:
        if not spec:
            spec = ArgumentSpec()
        elif not isinstance(spec, ArgumentSpec):
            spec = UserKeywordArgumentParser().parse(spec)
        spec.name = lambda: self.full_name
        return spec

    @setter
    def body(self, body: 'Sequence[BodyItem|DataDict]') -> Body:
        return Body(self, body)

    @property
    def setup(self) -> Keyword:
        """User keyword setup as a :class:`Keyword` object.

        New in Robot Framework 7.0.
        """
        if self._setup is None:
            self.setup = None
        return self._setup

    @setup.setter
    def setup(self, setup: 'Keyword|DataDict|None'):
        self._setup = create_fixture(self.fixture_class, setup, self, Keyword.SETUP)

    @property
    def has_setup(self) -> bool:
        """Check does a keyword have a setup without creating a setup object.

        See :attr:`has_teardown` for more information. New in Robot Framework 7.0.
        """
        return bool(self._setup)

    @property
    def teardown(self) -> Keyword:
        """User keyword teardown as a :class:`Keyword` object."""
        if self._teardown is None:
            self.teardown = None
        return self._teardown

    @teardown.setter
    def teardown(self, teardown: 'Keyword|DataDict|None'):
        self._teardown = create_fixture(self.fixture_class, teardown, self, Keyword.TEARDOWN)

    @property
    def has_teardown(self) -> bool:
        """Check does a keyword have a teardown without creating a teardown object.

        A difference between using ``if kw.has_teardown:`` and ``if kw.teardown:``
        is that accessing the :attr:`teardown` attribute creates a :class:`Keyword`
        object representing the teardown even when the user keyword actually does
        not have one. This can have an effect on memory usage.

        New in Robot Framework 6.1.
        """
        return bool(self._teardown)

    def create_runner(self, name: 'str|None',
                      languages: 'LanguagesLike' = None) \
            -> 'UserKeywordRunner|EmbeddedArgumentsRunner':
        if self.embedded:
            return EmbeddedArgumentsRunner(self, name)
        return UserKeywordRunner(self)

    def bind(self, data: Keyword) -> 'UserKeyword':
        kw = UserKeyword('', self.args.copy(), self.doc, self.tags, self.timeout,
                         self.lineno, self.owner, data.parent, self.error)
        # Avoid possible errors setting name with invalid embedded args.
        kw._name = self._name
        kw.embedded = self.embedded
        if self.has_setup:
            kw.setup = self.setup.to_dict()
        if self.has_teardown:
            kw.teardown = self.teardown.to_dict()
        kw.body = self.body.to_dicts()
        return kw

    def to_dict(self) -> DataDict:
        data: DataDict = {'name': self.name}
        for name, value in [('args', tuple(self._decorate_arg(a) for a in self.args)),
                            ('doc', self.doc),
                            ('tags', tuple(self.tags)),
                            ('timeout', self.timeout),
                            ('lineno', self.lineno),
                            ('error', self.error)]:
            if value:
                data[name] = value
        if self.has_setup:
            data['setup'] = self.setup.to_dict()
        data['body'] = self.body.to_dicts()
        if self.has_teardown:
            data['teardown'] = self.teardown.to_dict()
        return data

    def _decorate_arg(self, arg: ArgInfo) -> str:
        if arg.kind == arg.VAR_NAMED:
            deco = '&'
        elif arg.kind in (arg.VAR_POSITIONAL, arg.NAMED_ONLY_MARKER):
            deco = '@'
        else:
            deco = '$'
        result = f'{deco}{{{arg.name}}}'
        if arg.default is not NOT_SET:
            result += f'={arg.default}'
        return result

has_setup: bool property

Check does a keyword have a setup without creating a setup object.

See :attr:has_teardown for more information. New in Robot Framework 7.0.

has_teardown: bool property

Check does a keyword have a teardown without creating a teardown object.

A difference between using if kw.has_teardown: and if kw.teardown: is that accessing the :attr:teardown attribute creates a :class:Keyword object representing the teardown even when the user keyword actually does not have one. This can have an effect on memory usage.

New in Robot Framework 6.1.

params: ArgumentSpec property

Keyword parameter information.

This is a forward compatible alias for :attr:args.

setup: Keyword property writable

User keyword setup as a :class:Keyword object.

New in Robot Framework 7.0.

teardown: Keyword property writable

User keyword teardown as a :class:Keyword object.

config(**attributes)

Configure model object with given attributes.

obj.config(name='Example', doc='Something') is equivalent to setting obj.name = 'Example' and obj.doc = 'Something'.

New in Robot Framework 4.0.

Source code in src/robot/model/modelobject.py
def config(self: T, **attributes) -> T:
    """Configure model object with given attributes.

    ``obj.config(name='Example', doc='Something')`` is equivalent to setting
    ``obj.name = 'Example'`` and ``obj.doc = 'Something'``.

    New in Robot Framework 4.0.
    """
    for name, value in attributes.items():
        try:
            orig = getattr(self, name)
        except AttributeError:
            raise AttributeError(f"'{full_name(self)}' object does not have "
                                 f"attribute '{name}'")
        # Preserve tuples. Main motivation is converting lists with `from_json`.
        if isinstance(orig, tuple) and not isinstance(value, tuple):
            try:
                value = tuple(value)
            except TypeError:
                raise TypeError(f"'{full_name(self)}' object attribute '{name}' "
                                f"is 'tuple', got '{type_name(value)}'.")
        try:
            setattr(self, name, value)
        except AttributeError as err:
            # Ignore error setting attribute if the object already has it.
            # Avoids problems with `from_dict` with body items having
            # un-settable `type` attribute that is needed in dict data.
            if value != orig:
                raise AttributeError(f"Setting attribute '{name}' failed: {err}")
    return self

copy(**attributes)

Return a shallow copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.copy(name='New name').

See also :meth:deepcopy. The difference between copy and deepcopy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def copy(self: T, **attributes) -> T:
    """Return a shallow copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.copy(name='New name')``.

    See also :meth:`deepcopy`. The difference between ``copy`` and
    ``deepcopy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.copy(self).config(**attributes)

deepcopy(**attributes)

Return a deep copy of this object.

:param attributes: Attributes to be set to the returned copy. For example, obj.deepcopy(name='New name').

See also :meth:copy. The difference between deepcopy and copy is the same as with the methods having same names in the copy__ module.

__ https://docs.python.org/3/library/copy.html

Source code in src/robot/model/modelobject.py
def deepcopy(self: T, **attributes) -> T:
    """Return a deep copy of this object.

    :param attributes: Attributes to be set to the returned copy.
        For example, ``obj.deepcopy(name='New name')``.

    See also :meth:`copy`. The difference between ``deepcopy`` and
    ``copy`` is the same as with the methods having same names in
    the copy__ module.

    __ https://docs.python.org/3/library/copy.html
    """
    return copy.deepcopy(self).config(**attributes)

from_dict(data) classmethod

Create this object based on data in a dictionary.

Data can be got from the :meth:to_dict method or created externally.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

Source code in src/robot/model/modelobject.py
@classmethod
def from_dict(cls: Type[T], data: DataDict) -> T:
    """Create this object based on data in a dictionary.

    Data can be got from the :meth:`to_dict` method or created externally.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.
    """
    try:
        return cls().config(**data)
    except (AttributeError, TypeError) as err:
        raise DataError(f"Creating '{full_name(cls)}' object from dictionary "
                        f"failed: {err}")

from_json(source) classmethod

Create this object based on JSON data.

The data is given as the source parameter. It can be:

  • a string (or bytes) containing the data directly,
  • an open file object where to read the data from, or
  • a path (pathlib.Path or string) to a UTF-8 encoded file to read.

The JSON data is first converted to a Python dictionary and the object created using the :meth:from_dict method.

Notice that the source is considered to be JSON data if it is a string and contains {. If you need to use { in a file system path, pass it in as a pathlib.Path instance.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

Source code in src/robot/model/modelobject.py
@classmethod
def from_json(cls: Type[T], source: 'str|bytes|TextIO|Path') -> T:
    """Create this object based on JSON data.

    The data is given as the ``source`` parameter. It can be:

    - a string (or bytes) containing the data directly,
    - an open file object where to read the data from, or
    - a path (``pathlib.Path`` or string) to a UTF-8 encoded file to read.

    The JSON data is first converted to a Python dictionary and the object
    created using the :meth:`from_dict` method.

    Notice that the ``source`` is considered to be JSON data if it is
    a string and contains ``{``. If you need to use ``{`` in a file system
    path, pass it in as a ``pathlib.Path`` instance.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.
    """
    try:
        data = JsonLoader().load(source)
    except (TypeError, ValueError) as err:
        raise DataError(f'Loading JSON data failed: {err}')
    return cls.from_dict(data)

matches(name)

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.

Source code in src/robot/running/keywordimplementation.py
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.match(name) is not None
    return eq(self.name, name, ignore='_')

to_json(file=None, *, ensure_ascii=False, indent=0, separators=(',', ':'))

Serialize this object into JSON.

The object is first converted to a Python dictionary using the :meth:to_dict method and then the dictionary is converted to JSON.

The file parameter controls what to do with the resulting JSON data. It can be:

  • None (default) to return the data as a string,
  • an open file object where to write the data to, or
  • a path (pathlib.Path or string) to a file where to write the data using UTF-8 encoding.

JSON formatting can be configured using optional parameters that are passed directly to the underlying json__ module. Notice that the defaults differ from what json uses.

With robot.running model objects new in Robot Framework 6.1, with robot.result new in Robot Framework 7.0.

__ https://docs.python.org/3/library/json.html

Source code in src/robot/model/modelobject.py
def to_json(self, file: 'None|TextIO|Path|str' = None, *,
            ensure_ascii: bool = False, indent: int = 0,
            separators: 'tuple[str, str]' = (',', ':')) -> 'str|None':
    """Serialize this object into JSON.

    The object is first converted to a Python dictionary using the
    :meth:`to_dict` method and then the dictionary is converted to JSON.

    The ``file`` parameter controls what to do with the resulting JSON data.
    It can be:

    - ``None`` (default) to return the data as a string,
    - an open file object where to write the data to, or
    - a path (``pathlib.Path`` or string) to a file where to write
      the data using UTF-8 encoding.

    JSON formatting can be configured using optional parameters that
    are passed directly to the underlying json__ module. Notice that
    the defaults differ from what ``json`` uses.

    With ``robot.running`` model objects new in Robot Framework 6.1,
    with ``robot.result`` new in Robot Framework 7.0.

    __ https://docs.python.org/3/library/json.html
    """
    return JsonDumper(ensure_ascii=ensure_ascii, indent=indent,
                      separators=separators).dump(self.to_dict(), file)