*************** Our YAML module *************** The :py:mod:`swarmsim.yaml` module provides a custom YAML loader that defines some convenience tags. This article will explain how the YAML files are loaded and how to use the custom tags. .. seealso:: Looking for how to load or dump YAML files with our custom tags? See :py:mod:`swarmsim.yaml` Or for information on how to use your custom class in a YAML file, see :doc:`/guide/config_store_api`. YAML ==== YAML is a human-readable data serialization format. We use it to write configurations that describe simulations. It's a superset of JSON, so it's easy to read and write. We use the `PyYAML library `_ to load and dump YAML files. .. seealso:: Here's a nice and quick tutorial for YAML: `Learn YAML in Y minutes `_ Or have a look at the `YAML specification `_ YAML Tags ========= The YAML standard allows for !tags which provide information on how to parse a YAML entry. These tags usually start with ``!`` and are defined in the `YAML specification: Tags `_. An example of standard tags are type specifiers, such as ``!!str`` and ``!!int``. .. code-block:: yaml explicitly-typed-value: !!int 42 RobotSwarmSimulator uses a custom PyYAML loader to allow for some nice features. The custom YAML tags are defined in the :py:mod:`~swarmsim.yaml` module. .. _yaml_crazy_tag_example: Here's an example of a crazy YAML file that uses a bunch of YAML features and our custom tags: .. include:: crazy_yaml_example.rst If you're new to YAML or haven't seen the ``&anchor`` and ``*anchor`` syntax, check out `Learn YAML in Y minutes`_. To understand what the ``!include``, ``!relpath``, and ``!np`` tags do, read on. The ``!np`` tag --------------- This tag is used to convert a YAML string, sequence, or mapping to a numpy object. In this example, the following YAML files are in the same directory: .. code-block:: yaml :caption: foo.yaml example: !np complex('2+2j') See the :py:mod:`~swarmsim.yaml.mathexpr` module for more information on what you can do. .. _yaml-tags-include: The ``!include`` tag -------------------- This tag is used to include another YAML file as a mapping. For example, see the following YAML files: .. grid:: 2 :margin: 0 :gutter: 3 :padding: 0 0 0 0 .. grid-item:: .. code-block:: yaml :caption: bar.yaml my_list: - 1 - 2 - 3 .. grid-item:: .. code-block:: yaml :caption: foo.yaml foo: !include bar.yaml .. grid-item:: :columns: 12 .. code-block:: python :caption: Result >>> from swarmsim.yaml import load >>> mapping = load('foo.yaml') >>> print(mapping) {'foo': {'my_list': [1, 2, 3]}} The file extension of what you're including affects the behavior of the ``!include`` tag: * ``.yaml`` files will be loaded using the :py:func:`~swarmsim.yaml.load` function * ``.json`` files will be loaded using ``json.load`` * All other files are read as text and returned as a string .. _yaml-tags-relpath: The ``!relpath`` tag -------------------- This tag is used to resolve the relative path given, but unlike the ``!include`` tag, it does not load the file, and instead returns the absolute path as a string. .. code-block:: yaml :caption: /home/user/project/foo.yaml path: !relpath bar.yaml This is equivalent to: .. code-block:: yaml path: /home/user/project/bar.yaml .. _relpath-resolution: Path Resolution Order ===================== When loading a YAML file, the ``!include`` and ``!relpath`` tags will resolve the path by testing the following assumptions in order: .. card:: #. Path is **not** relative to the current working directory (i.e. the path is absolute or relative to the user home directory) #. Path is relative to the ``.yaml`` file with the tag #. Path is relative to the current working directory (where you were when you ran ``python``). This is the default behavior for relative paths in Python, but it is the last place we look. If a file isn't found at any of these locations, an error will be raised. See :py:func:`.include.search_file`.