Skip to content

Combination of forward references, and changing objects __module__ attribute leads to odd bug #609

@EthanMarx

Description

@EthanMarx

🐛 Bug report

I found an interesting edge case when trying to build out a CLI for the ray.tune.Tuner.

Not sure if this should be considered a bug on the jsonargparse side, or an odd (mis?)use of python flexibility by Ray.

The issue stems when trying to build a CLI for the ray.train.RunConfig. It is the combination of the following that leads to problems:

  1. The the actual RunConfig class definition lives in ray.air.config
  2. ray changes the __module__ attribute of the ray.train.RunConfig import to be ray.train.
  3. The actual RunConfig class uses ForwardRefs (e.g. for the SyncConfig)

Due to the above, the following parser isn't able to add any forward referenced arguments in RunConfig

# test.py
from jsonargparse import ArgumentParser
from ray.train import RunConfig

parser = ArgumentParser()
parser.add_class_arguments(RunConfig, "run_config")

if __name__ == "__main__":
     parser.parse_args()

Specifically, the SyncConfig and other attributes that use forward references aren't able to be resolved, and thus aren't added to the parser:

python test.py --help

usage: test.py [-h] [--test CONFIG] [--test.name NAME] [--test.storage_path STORAGE_PATH]
               [--test.storage_filesystem.help CLASS_PATH_OR_NAME] [--test.storage_filesystem STORAGE_FILESYSTEM]
               [--test.failure_config FAILURE_CONFIG] [--test.checkpoint_config CHECKPOINT_CONFIG] [--test.verbose VERBOSE]
               [--test.stop STOP] [--test.log_to_file LOG_TO_FILE] [--test.local_dir LOCAL_DIR] [--print_shtab {bash,zsh,tcsh}]

options:
  -h, --help            Show this help message and exit.
  --print_shtab {bash,zsh,tcsh}
                        Print shtab shell completion script.

Runtime configuration for training and tuning runs:
  --test CONFIG         Path to a configuration file.
  --test.name NAME      Name of the trial or experiment. If not provided, will be deduced from the Trainable. (type:
                        Optional[str], default: null)
  --test.storage_path STORAGE_PATH
                        [Beta] Path where all results and checkpoints are persisted. Can be a local directory or a destination on
                        cloud storage. For multi-node training/tuning runs, this must be set to a shared storage location (e.g.,
                        S3, NFS). This defaults to the local ``~/ray_results`` directory. (type: Optional[str], default: null)
  --test.storage_filesystem.help CLASS_PATH_OR_NAME
                        Show the help for the given subclass of FileSystem and exit.
  --test.storage_filesystem STORAGE_FILESYSTEM
                        [Beta] A custom filesystem to use for storage. If this is provided, `storage_path` should be a path with
                        its prefix stripped (e.g., `s3://bucket/path` -> `bucket/path`). (type: Optional[FileSystem], default:
                        null)
  --test.failure_config FAILURE_CONFIG
                        Failure mode configuration. (type: Optional[FailureConfig], default: null)
  --test.checkpoint_config CHECKPOINT_CONFIG
                        Checkpointing configuration. (type: Optional[CheckpointConfig], default: null)
  --test.verbose VERBOSE
                        0, 1, or 2. Verbosity mode. 0 = silent, 1 = default, 2 = verbose. Defaults to 1. If the
                        ``RAY_AIR_NEW_OUTPUT=1`` environment variable is set, uses the old verbosity settings: 0 = silent, 1 =
                        only status updates, 2 = status and brief results, 3 = status and detailed results. (type: Optional[int],
                        default: null)
  --test.stop STOP      Stop conditions to consider. Refer to ray.tune.stopper.Stopper for more info. Stoppers should be
                        serializable. (type: Union[Mapping, Callable[[str, Mapping], bool], null], default: null)
  --test.log_to_file LOG_TO_FILE
                        [DeveloperAPI] Log stdout and stderr to files in trial directories. If this is `False` (default), no
                        files are written. If `true`, outputs are written to `trialdir/stdout` and `trialdir/stderr`,
                        respectively. If this is a single string, this is interpreted as a file relative to the trialdir, to
                        which both streams are written. If this is a Sequence (e.g. a Tuple), it has to have length 2 and the
                        elements indicate the files to which stdout and stderr are written, respectively. (type: Union[bool, str,
                        Tuple[str, str]], default: False)
  --test.local_dir LOCAL_DIR
                        (type: Optional[str], default: null)

After some debugging, the main issue is that, since the __module__ attribute has been changed by ray, jsonargparse can't import the proper objects here when resolving references.

Environment

  • jsonargparse version: 4.33.2
  • Python version: 3.10
  • How jsonargparse was installed: pip
  • OS: liux

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions