Source code for gemseo.core.namespaces

# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License version 3 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
# Contributors:
#    INITIAL AUTHORS - initial API and implementation and/or initial
#                         documentation
#        :author: Francois Gallard
#    OTHER AUTHORS   - MACROSCOPIC CHANGES
"""Utility functions and classes to handle namespaces.

The namespaces implementation itself is mainly in :mod:`~gemseo.core.grammars` and
:mod:`~gemseo.core.discipline`
"""
from __future__ import annotations

from typing import Any
from typing import Iterable
from typing import List
from typing import Mapping
from typing import MutableMapping
from typing import Union

NamespacesMapping = MutableMapping[str, Union[str, List[str]]]

namespaces_separator = ":"


[docs]def split_namespace(data_name: str) -> list[str, str]: """Return the (namespace, name) pair from a data name. For instance if data_name = ``my:namesp:ace:a`` and the separator is ``:``, returns (``my:namesp:ace``,``a``). If there is no namespace prefix in ``data_name``, returns ``data_name``. In case data_name contains the namespace separator but empty name, or empty namespace, returns the (namespace, name) pair, containing eventually empty strings. Args: data_name: The data name containing the namespace name. Returns: The namespace name and the data name. """ return data_name.rsplit(namespaces_separator, -1)
[docs]def remove_prefix_from_name(name: str) -> str: """Remove namespace prefix from the name. Args: data: The container of data names, or a single data name. Returns: The data names without prefixes. """ return name.rsplit(namespaces_separator, 1)[-1]
[docs]def remove_prefix_from_dict(data: Mapping[str, Any]) -> dict[str, Any]: """Remove namespaces prefixes from mapping keys if any. Args: data: The mapping which names may contain namespaces. Returns: The mapping without prefixes in its keys. """ return {k.rsplit(namespaces_separator, 1)[-1]: v for k, v in data.items()}
[docs]def remove_prefix_from_list(names: Iterable[str]) -> list[str]: """Remove namespaces prefixes from names, if any. Args: data: The names that may contain namespaces. Returns: The names without prefixes in its keys. """ return [d.rsplit(namespaces_separator, 1)[-1] for d in names]
[docs]def update_namespaces( namespaces: NamespacesMapping, other_namespaces: NamespacesMapping ) -> None: """Update namespaces with the key/value pairs from other, overwriting existing keys. Args: namespaces: The namespaces to update. other_ns: The namespaces to update from. """ for name, other_ns in other_namespaces.items(): curr_ns = namespaces.get(name) if curr_ns is None: namespaces[name] = other_ns elif isinstance(curr_ns, str): if isinstance(other_ns, str): namespaces[name] = [curr_ns, other_ns] else: namespaces[name] = [curr_ns] + other_ns else: if isinstance(other_ns, str): namespaces[name].append(other_ns) else: namespaces[name].extend(other_ns)