(Dataset-specific) path resolution
If a command operates on an item on the file system that is identified by its
path, and can (optionally) operate in the context of a specific dataset, this
is achieved with two arguments: dataset, and path. It can be the case
that only one of these parameters is needed (and occasionally even neither one
is required) for a specific command invocation, hence they are typically both
used with None default values.
The following parameter preprocessor setup for @datalad_command can be used
to guarantee that the function body of a command will always receive:
a
pathlibpath object instance via thepathargumenta
Datasetinstance via thedatasetargument from which an (optional) dataset context can be identified.>>> from datalad_core.commands import ( ... EnsureDataset, ... JointParamProcessor, ... ) >>> from datalad_core.constraints import EnsurePath >>> preproc=JointParamProcessor( ... { ... 'dataset': EnsureDataset(), ... 'path': EnsurePath() ... }, ... proc_defaults={'dataset', 'path'}, ... tailor_for_dataset={ ... 'path': 'dataset', ... } ... ),
The above pattern takes care of resolving any path given to path
(including None) to an actual path. This path is adequately determined,
also considering the value of any dataset parameter. This follows
the conventions of path resolution in DataLad:
any absolute path is taken as-is
any relative path is interpreted as relative to CWD, unless there is a dataset context based on a
Worktreeinstance. Only in the latter case a relative path is interpreted as relative to the worktree root
Technically, this pattern works, because
even
Nonedefaults will be processed fordatasetandpaththe
tailored_for_datasetmapping causes thedatasetargument to be resolved first (beforepath)and the
EnsurePathconstraint is tailored to anyDatasetgiven todataset, by generating a matchingEnsureDatasetPathconstraint for thepathparameter internally
Taken together, this pattern simplifies command implementation, because
a number of checks are factored out into common implementation following
accepted conventions. Command implementations can inspect the specifics
of a user-provided dataset context via Dataset.pristine_spec.