class_docstr: Manage sibling configuration
  
  This command offers four different actions: 'query', 'add', 'remove',
  'configure', 'enable'. 'query' is the default action and can be used to obtain
  information about (all) known siblings. 'add' and 'configure' are highly
  similar actions, the only difference being that adding a sibling
  with a name that is already registered will fail, whereas
  re-configuring a (different) sibling under a known name will not
  be considered an error. 'enable' can be used to complete access
  configuration for non-Git sibling (aka git-annex special remotes).
  Lastly, the 'remove' action allows for the
  removal (or de-configuration) of a registered sibling.
  
  For each sibling (added, configured, or queried) all known sibling
  properties are reported. This includes:
  
  "name"
      Name of the sibling
  
  "path"
      Absolute path of the dataset
  
  "url"
      For regular siblings at minimum a "fetch" URL, possibly also a
      "pushurl"
  
  Additionally, any further configuration will also be reported using
  a key that matches that in the Git configuration.
  
  By default, sibling information is rendered as one line per sibling
  following this scheme::
  
    <dataset_path>: <sibling_name>(<+|->) [<access_specification]
  
  where the `+` and `-` labels indicate the presence or absence of a
  remote data annex at a particular remote, and `access_specification`
  contains either a URL and/or a type label for the sibling.
code: def __call__(
      action="query",
      *,
      dataset=None,
      name=None,
      url=None,
      pushurl=None,
      description=None,
      # TODO consider true, for now like add_sibling
      fetch=False,
      as_common_datasrc=None,
      publish_depends=None,
      publish_by_default=None,
      annex_wanted=None,
      annex_required=None,
      annex_group=None,
      annex_groupwanted=None,
      inherit=False,
      get_annex_info=True,
      recursive=False,
      recursion_limit=None,
  ):
      # TODO: Detect malformed URL and fail?
      # XXX possibly fail if fetch is False and as_common_datasrc
  
      if annex_groupwanted and not annex_group:
          raise InsufficientArgumentsError(
              "To set groupwanted, you need to provide annex_group option"
          )
  
      # TODO catch invalid action specified
      action_worker_map = {
          "query": _query_remotes,
          "add": _add_remote,
          "configure": _configure_remote,
          "remove": _remove_remote,
          "enable": _enable_remote,
      }
      # all worker strictly operate on a single dataset
      # anything that deals with hierarchies and/or dataset
      # relationships in general should be dealt with in here
      # at the top-level and vice versa
      worker = action_worker_map[action]
  
      ds = require_dataset(
          dataset,
          # it makes no sense to use this command without a dataset
          check_installed=True,
          purpose="configure sibling",
      )
      refds_path = ds.path
  
      res_kwargs = dict(refds=refds_path, logger=lgr)
  
      ds_name = op.basename(ds.path)
  
      # do not form single list of datasets (with recursion results) to
      # give fastest possible response, for the precise of a long-all
      # function call
  
      # minimize expensive calls to .repo
      ds_repo = ds.repo
  
      # prepare common parameterization package for all worker calls
      worker_kwargs = dict(
          name=name,
          fetch=fetch,
          description=description,
          as_common_datasrc=as_common_datasrc,
          publish_depends=publish_depends,
          publish_by_default=publish_by_default,
          annex_wanted=annex_wanted,
          annex_required=annex_required,
          annex_group=annex_group,
          annex_groupwanted=annex_groupwanted,
          inherit=inherit,
          get_annex_info=get_annex_info,
          res_kwargs=res_kwargs,
      )
      yield from worker(
          ds=ds,
          repo=ds_repo,
          known_remotes=ds_repo.get_remotes(),
          # for top-level dataset there is no layout questions
          url=_mangle_urls(url, ds_name),
          pushurl=_mangle_urls(pushurl, ds_name),
          **worker_kwargs,
      )
      if not recursive:
          return
  
      # do we have instructions to register siblings with some alternative
      # layout?
      replicate_local_structure = url and "%NAME" not in url
  
      subds_pushurl = None
      for subds in ds.subdatasets(
          state="present",
          recursive=recursive,
          recursion_limit=recursion_limit,
          result_xfm="datasets",
      ):
          subds_repo = subds.repo
          subds_name = op.relpath(subds.path, start=ds.path)
          if replicate_local_structure:
              subds_url = slash_join(url, subds_name)
              if pushurl:
                  subds_pushurl = slash_join(pushurl, subds_name)
          else:
              subds_url = _mangle_urls(
                  url, "/".join([ds_name, subds_name])
              )
              subds_pushurl = _mangle_urls(
                  pushurl, "/".join([ds_name, subds_name])
              )
          yield from worker(
              ds=subds,
              repo=subds_repo,
              known_remotes=subds_repo.get_remotes(),
              url=subds_url,
              pushurl=subds_pushurl,
              **worker_kwargs,
          )
  
imports: import logging
  import os
  import os.path
  from urllib.parse import urlparse
  import datalad.support.ansi_colors
  from datalad.distribution.dataset import Dataset, require_dataset
  from datalad.distribution.update import Update
  from datalad.downloaders.credentials import UserPassword
  from datalad.interface.base import Interface, build_doc, eval_results
  from datalad.interface.common_opts import annex_group_opt, annex_groupwanted_opt, annex_required_opt, annex_wanted_opt, as_common_datasrc, inherit_opt, location_description, publish_by_default, publish_depends, recursion_flag, recursion_limit
  from datalad.interface.results import get_status_dict
  from datalad.interface.utils import generic_result_renderer
  from datalad.support.annexrepo import AnnexRepo
  from datalad.support.constraints import EnsureBool, EnsureChoice, EnsureNone, EnsureStr
  from datalad.support.exceptions import AccessDeniedError, AccessFailedError, CapturedException, CommandError, DownloadError, InsufficientArgumentsError, RemoteNotAvailableError
  from datalad.support.gitrepo import GitRepo
  from datalad.support.network import RI, URL, PathRI
  from datalad.support.param import Parameter
  from datalad.utils import Path, ensure_list, slash_join
  from .dataset import EnsureDataset, datasetmethod
label_desc: Use image node_id 1 for calling the Siblings obj's underlying member method code with example usage: obj.__call__(action) without return types