boss.helper
===========

.. py:module:: boss.helper


Attributes
----------

.. autoapisummary::

   boss.helper.log


Functions
---------

.. autoapisummary::

   boss.helper.get_module
   boss.helper.get_class_by_name
   boss.helper.file_from_url
   boss.helper.extend_none_allowed_list
   boss.helper.get_remote_hero
   boss.helper.add_class_descriptor
   boss.helper.get_or_create_dynamic_subclass


Module Contents
---------------

.. py:data:: log

.. py:function:: get_module(path, relative_path=None)

.. py:function:: get_class_by_name(name, relative_path=None)

   Resolve class by name

   :param name: (str) "%s.%s" % (module.name, class.name)
   :return: (class)


.. py:function:: file_from_url(url: str) -> io.IOBase

   Load content from a file specified by a URL.

   This can be every type of URL supported by pythons urllib
   (e.g. http://, file://, etc ). Giving the basic auth credentials in the URL in the form
   http://user:password@hostname:port/path is supported.

   :returns: file handle on the file


.. py:function:: extend_none_allowed_list(list1: list | None, list2: list | None) -> list | None

   Extend a list with another list which both can be None.

   If one of the lists is None, the other list is returned. If both lists are None, None is returned.

   :param list1: list to extend
   :param list2: list to extend with


.. py:function:: get_remote_hero(name: str, realm: str, trials: int = 10, delay: float = 1.0)

   Try multiple times to get RemoteHERO.

   :param name: name of the remote HERO.
   :param realm: realm of the remote HERO.
   :param trials: number of trials before giving up
   :param delays: time delay between trials in seconds.


.. py:function:: add_class_descriptor(cls: type, attr_name: str, descriptor) -> None

   Add a descriptor to a class.

   This is a simple helper function which uses `setattr` to add an attribute to the class and then also calls
   `__set_name__` on the attribute.

   :param cls: Class to add the descriptor to
   :param attr_name: Name of the attribute the descriptor will be added to
   :param descriptor: The descriptor to be added


.. py:function:: get_or_create_dynamic_subclass(base_cls: Any, *args: Any, **kwargs: Any) -> type

   Return a cached dynamic subclass of ``base_cls`` based on the input arguments.

   This helper generates a subclass of ``base_cls`` whose identity is determined by ``*args`` and ``**kwargs``.
   The argument signature is serialized into a hash, which is then used as both a cache key and the dynamic subclass
   name. If the subclass for a given argument combination already exists, it is returned from cache.

   The generated subclass replaces ``__new__`` with a dummy implementation to prevent recursive invocation of
   ``base_cls.__new__``.

   :param base_cls: The base class to derive from. Must be passed positionally.
   :param \*args: Positional values that should influence subclass identity.
   :param \*\*kwargs: Keyword values that should influence subclass identity.

   :returns: A dynamically generated subclass of ``base_cls``.

   :raises TypeError: If arguments cannot be serialized for hashing.


