class_docstr: Drop content of individual files or entire (sub)datasets
  
  This command is the antagonist of 'get'. It can undo the retrieval of file
  content, and the installation of subdatasets.
  
  Dropping is a safe-by-default operation. Before dropping any information,
  the command confirms the continued availability of file-content (see e.g.,
  configuration 'annex.numcopies'), and the state of all dataset branches
  from at least one known dataset sibling. Moreover, prior removal of an
  entire dataset annex, that it is confirmed that it is no longer marked
  as existing in the network of dataset siblings.
  
  Importantly, all checks regarding version history availability and local
  annex availability are performed using the current state of remote
  siblings as known to the local dataset. This is done for performance
  reasons and for resilience in case of absent network connectivity. To
  ensure decision making based on up-to-date information, it is advised to
  execute a dataset update before dropping dataset components.
class_docstr_tok: ["Drop","content","of","individual","files","or","entire","(","sub",")","datasets","This","command","is","the","antagonist","of","'get","'",".","It","can","undo","the","retrieval","of","file","content",",","and","the","installation","of","subdatasets",".","Dropping","is","a","safe-by-default","operation",".","Before","dropping","any","information",",","the","command","confirms","the","continued","availability","of","file-content","(","see","e.g.",",","configuration","'annex.numcopies","'",")",",","and","the","state","of","all","dataset","branches","from","at","least","one","known","dataset","sibling",".","Moreover",",","prior","removal","of","an","entire","dataset","annex",",","that","it","is","confirmed","that","it","is","no","longer","marked","as","existing","in","the","network","of","dataset","siblings",".","Importantly",",","all","checks","regarding","version","history","availability","and","local","annex","availability","are","performed","using","the","current","state","of","remote","siblings","as","known","to","the","local","dataset",".","This","is","done","for","performance","reasons","and","for","resilience","in","case","of","absent","network","connectivity",".","To","ensure","decision","making","based","on","up-to-date","information",",","it","is","advised","to","execute","a","dataset","update","before","dropping","dataset","components","."]
code: def __call__(
      path=None,
      *,
      what="filecontent",
      reckless=None,
      dataset=None,
      recursive=False,
      recursion_limit=None,
      jobs=None,
      # deprecated
      check=None,
      if_dirty=None,
  ):
      # TODO if reckless is None, initialize from a potential config setting
      # left behind by a reckless clone
  
      # proper spelling of mode switches is critical for implementation
      # below. double-check, also in Python API usage
      # TODO consider making a generic helper
      for label, value in (("what", what), ("reckless", reckless)):
          try:
              Drop._params_[label].constraints(value)
          except ValueError as e:
              raise ValueError(
                  f"Invalid '{label}' parameter value of: "
                  f"{repr(value)} [{str(e)}]"
              ) from e
  
      if check is not None:
          warnings.warn(
              "The `check` argument of `datalad drop` is deprecated, "
              "use the `reckless` argument instead.",
              DeprecationWarning,
          )
      if if_dirty is not None:
          warnings.warn(
              "The `if_dirty` argument of `datalad drop` is ignored, "
              "it can be removed for a safe-by-default behavior. For "
              "other cases consider the `reckless` argument.",
              DeprecationWarning,
          )
  
      if check is False:
          if reckless is not None:
              raise ValueError(
                  "Must not use deprecated `check` argument, and new "
                  "`reckless` argument together with `datalad drop`."
              )
          reckless = "availability"
  
      if (
          what in ("all", "datasets")
          and reckless == "kill"
          and not recursive
      ):
          raise ValueError(
              "A reckless kill is requested but no recursion flag is set. "
              "With 'kill' no checks for subdatasets will be made, "
              "acknowledge by setting the recursive flag"
          )
  
      # we cannot test for what=='allkeys' and path==None here,
      # on per each dataset. otherwise we will not be able to drop
      # from a subdataset, by given its path -- desirable MIH thinks
  
      ds = require_dataset(
          dataset, check_installed=True, purpose="drop"
      )
  
      res_props = dict(
          logger=lgr,
          refds=ds.path,
      )
      # if not paths are given, there will still be a single dataset record
      # with paths==None
      paths_by_ds, errors = get_paths_by_ds(
          ds,
          dataset,
          ensure_list(path),
          # XXX this needs more thought!! Maybe this is what the mode should be
          # in general?!
          # when we want to drop entire datasets, it is much more useful
          # to have subdatasets be their own record
          subdsroot_mode="sub"
          if what in ("all", "datasets")
          else "rsync",
      )
      for e in errors:
          yield dict(
              action="drop",
              path=str(e),
              status="error",
              message=(
                  "path not underneath the reference dataset %s",
                  ds,
              ),
              **res_props,
          )
          # we are not returning, a caller could decide on failure mode
  
      if what in ("all", "datasets") and _paths_atunder_dir(
          paths_by_ds, ds.pathobj.cwd()
      ):
          raise RuntimeError(
              "refuse to perform actions that would remove the current "
              "working directory"
          )
  
      lgr.debug(
          "Discovered %i datasets to drop (from)", len(paths_by_ds)
      )
  
      # a dataset paths are normalized and guaranteed to be under the same
      # root dataset
      # we want to start from the leave datasets, such that all discovered
      # dataset can be processed independently
      for dpath in sorted(paths_by_ds.keys(), reverse=True):
          d = Dataset(dpath)
          lgr.debug("Starting to drop %s at %s", what, d)
          for res in _drop_dataset(
              d,
              paths_by_ds[dpath],
              what=what,
              reckless=reckless,
              # recursion from any of the given paths!
              recursive=recursive,
              recursion_limit=recursion_limit,
              jobs=jobs,
          ):
              yield dict(res, **res_props)
          lgr.debug("Finished dropping %s at %s", what, d)
      return
  
imports: import logging
  from itertools import chain
  import warnings
  from datalad.core.local.status import get_paths_by_ds
  from datalad.distribution.dataset import Dataset, EnsureDataset, datasetmethod, require_dataset
  from datalad.interface.base import Interface, build_doc, eval_results
  from datalad.interface.common_opts import jobs_opt, recursion_flag, recursion_limit
  from datalad.interface.results import annexjson2result, results_from_annex_noinfo, success_status_map
  from datalad.runner.exception import CommandError
  from datalad.support.annexrepo import AnnexRepo
  from datalad.support.constraints import EnsureChoice, EnsureNone, EnsureStr
  from datalad.support.exceptions import CapturedException
  from datalad.support.param import Parameter
  from datalad.utils import ensure_list, rmtree
label_desc: Use image node_id 1 for calling the Drop obj's underlying member method code with example usage: obj.__call__(path) without return types