# Component loader

class proton.loader.loader.Loader(*args, **kwargs)

  This is the loader for pluggable components. These components are identified by a type name (string) and a class name (also a string).

  In normal use, one will only use `get()`, as follows:

      from proton.loader import Loader
      # Note the parenthesis to instanciate an object, as Loader.get() returns a class.
      my_keyring = Loader.get('keyring')()

  You can influence which component to use using the `PROTON_LOADER_OVERRIDES` environment variable. It’s a comma separated list of `type_name=class_name` (to force `class_name` to be used) and `type_name=-class_name` (to exclude `class_name` from the options considered).

  To find the candidates, `Loader` will use entry points, that are to be defined in setup.py, as follows:

      setup(
          #[...],
          entry_points={
              "proton_loader_keyring": [
                  "json = proton.keyring.textfile:KeyringBackendJsonFiles"
              ]
          },
          #[...]
      )

  The class pointed by these entrypoints should implement the following class methods:

  - `_get_priority()`: return a numeric value, larger ones have higher priority. If it’s `None`, then this class won’t be considered

  - `_validate()`: check if the object can indeed be used (might be expensive/annoying). If it returns `False`, then the backend won’t be considered for the rest of the session.

  If `_validate()` is not defined, then it’s assumed that it will always succeed.

  To display the list of valid values, you can use `python3 -m proton.loader`.

  get(type_name: str, class_name: str | None = None, validate_params: dict | None = None) → type

    Get the implementation for type_name.

    Parameters:

      - type_name (str) – extension type

      - class_name (Optional[str], optional) – specific implementation to get, defaults to None (use preferred one)

      - validate_params (Optional[dict], optional) – pass custom arguments to backends during _validate Could be used in cases when the validity of a backend is to be dynamically evaluated upon calling get()

    Raises:

      RuntimeError – if no valid implementation can be found, or if PROTON_LOADER_OVERRIDES is invalid.

    Returns:

      the class implementing type_name. (careful: it’s a class, not an object!)

    Return type:

      class

  property type_names: list[str]
    Returns:

      Return a list of the known type names

    Return type:

      list[str]

  get_all(type_name: str) → list[PluggableComponent]

    Get a list of all implementations for `type_name`.

    Parameters:

      type_name (str) – type of implementation to query for

    Raises:

      RuntimeError – if `PROTON_LOADER_OVERRIDES` has conflicts

    Returns:

      Implementation for type_name (this includes the ones that are disabled)

    Return type:

      list[PluggableComponent]

  get_name(cls: type) → PluggableComponentName | None

    Return the type_name and class_name corresponding to the class in parameter.

    This is useful for inverse lookups (i.e. for logs for instance)

    Returns:

      `Tuple (type_name, class_name)`

    Return type:

      Optional[PluggableComponentName]

  reset() → None

    Erase the loader cache. (useful for tests)

  set_all(type_name: str, implementations: dict[str, type])

    Set a defined set of implementation for a given `type_name`.

    This method is probably useful only for testing.

    Parameters:

      - type_name (str) – Type

      - implementations (dict[str, class]) – Dictionary implementation name -> implementation class