jsonargparse icon indicating copy to clipboard operation
jsonargparse copied to clipboard

Change relative path in config from command line

Open AlejandroBaron opened this issue 1 year ago • 1 comments

🚀 Feature request

change relative path in config from command line

Motivation

I have a set of objects defined in individual yamls and I'd like to be able to change them from command line

Pitch

Let my config.yaml be

my_object: my_objects/my_object1.yaml

And then, a bunch of MyObjects defined in the my_objects/ directory

my_objects/
  - my_object1.yaml
  - my_object2.yaml
  - my_object3.yaml

I'd like to be able to change my_object field as follows

python main.py --config config.yaml --my_object my_objects/my_object2.yaml

AlejandroBaron avatar Jun 15 '24 09:06 AlejandroBaron

Thank you for proposing a feature! Unfortunately it is not clear to me exactly what is the idea. You might need to provide a complete runnable example.

Also, note that relative paths within configs and command line are already supported with the path types. For example, with the following existing files in the current directory:

main.py
subdir1/
  file1.txt
  file2.txt
  config.yaml
subdir2/
  file3.txt

and main.py:

#!/usr/bin/env python3

from jsonargparse import ArgumentParser, ActionConfigFile
from jsonargparse.typing import Path_fr

parser = ArgumentParser()
parser.add_argument("--files", type=list[Path_fr])
parser.add_argument("--config", action=ActionConfigFile)
cfg = parser.parse_args()
for file in cfg.files:
    print(f"{file}\t\t{file.absolute}")

and config.yaml:

files:
- file1.txt
- ../subdir1/file2.txt

The following outputs are obtained:

$ ./main.py --config subdir1/config.yaml | sed "s|$PWD/||" | column -t
file1.txt             subdir1/file1.txt
../subdir1/file2.txt  subdir1/../subdir1/file2.txt

$ ./main.py --config subdir1/config.yaml --files+=subdir2/file3.txt | sed "s|$PWD/||" | column -t
file1.txt             subdir1/file1.txt
../subdir1/file2.txt  subdir1/../subdir1/file2.txt
subdir2/file3.txt     subdir2/file3.txt

Relative paths inside config.yaml are validated with respect to the location of the config subdir1/. And paths given from command line are validated with respect to the directory from which the command is run ./.

If a parser includes subclass types (instantiatible objects) which have a path parameter, e.g.:

class MyObject:
    def __init__(self, file: Path_fr):
        ...

parser.add_subclass_arguments(MyObject, "object")  # supports --object path/to/object.yaml
parser.add_argument("--object", type=MyObject, enable_path=True)  # also supports --object path/to/object.yaml

the same relative path parsing already works inside configs and command line.

mauvilsa avatar Jun 15 '24 17:06 mauvilsa

The feature request wasn't clear and there was no clarification. From my point of view this feature already exists, so closing this for now.

mauvilsa avatar Apr 21 '25 20:04 mauvilsa