omni-us / jsonargparse

Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables
https://jsonargparse.readthedocs.io
MIT License
302 stars 41 forks source link

jsonargparse._util._parse_value_or_config #516

Closed antolu closed 1 month ago

antolu commented 1 month ago

🐛 Bug report

I'm using LightningCLI, and not sure if this is due to Lightning or jsonargparse, but...

Specifying the value of a variable as the path to a .csv file loads the content of the csv file when parsing arguments instead of giving the path as a string.

To reproduce

minimal_lightning.py

from __future__ import annotations

import os
import os.path

import lightning as L
import numpy as np
import torch
from lightning.pytorch.cli import LightningCLI

class MinimalModel(L.LightningModule):
    def __init__(self):
        super().__init__()
        self.layer = torch.nn.Linear(1, 1)

class MinimalDataModule(L.LightningDataModule):
    def __init__(self, data: np.ndarray | os.PathLike | str):
        super().__init__()
        if isinstance(data, os.PathLike | str):
            self.data = torch.load(data)

        elif isinstance(data, np.ndarray):
            self.data = torch.from_numpy(data)

        self.targets = torch.zeros_like(self.data)

def main() -> None:
    LightningCLI(
        MinimalModel,
        MinimalDataModule,
    )

if __name__ == "__main__":
    main()

minimal_lightning.yml

data:
  data: "~/code/transformertf/minimal_lightning.csv"

minimal_lightning.csv

1
2
3
4

Run as python lightning_minimal.py fit -c minimal_lightning.yml

Expected behavior

The classes should be instantiated by LightningCLI/jsonargparse and the data argument to the DataModule should be a path, and not the loaded and give

Traceback (most recent call last):
  File "/home/anton/code/transformertf/minimal_lightning.py", line 42, in <module>
    main()
  File "/home/anton/code/transformertf/minimal_lightning.py", line 35, in main
    LightningCLI(
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/lightning/pytorch/cli.py", line 385, in __init__
    self.instantiate_classes()
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/lightning/pytorch/cli.py", line 535, in instantiate_classes
    self.config_init = self.parser.instantiate_classes(self.config)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_deprecated.py", line 141, in patched_instantiate_classes
    cfg = self._unpatched_instantiate_classes(cfg, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_core.py", line 1191, in instantiate_classes
    cfg[subcommand] = subparser.instantiate_classes(cfg[subcommand], instantiate_groups=instantiate_groups)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_deprecated.py", line 141, in patched_instantiate_classes
    cfg = self._unpatched_instantiate_classes(cfg, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_core.py", line 1185, in instantiate_classes
    component.instantiate_class(component, cfg)
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_signatures.py", line 588, in group_instantiate_class
    parent[key] = instantiator_fn(group.group_class, **value)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/jsonargparse/_common.py", line 148, in default_class_instantiator
    return class_type(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/code/transformertf/minimal_lightning.py", line 22, in __init__
    self.data = torch.load(data)
                ^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/torch/serialization.py", line 997, in load
    with _open_file_like(f, 'rb') as opened_file:
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/torch/serialization.py", line 444, in _open_file_like
    return _open_file(name_or_buffer, mode)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/anton/.conda/envs/acc-py/lib/python3.11/site-packages/torch/serialization.py", line 425, in __init__
    super().__init__(open(name, mode))
                     ^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '1\n2\n3\n4\n'

Environment

jsonargparse: 4.29.0, installed with lightning[pytorch-extra] omegaconf: 2.3.0 lightning: 2.2.4 torch: 2.3.0 Python: 3.11.5

Arch Linux

mauvilsa commented 1 month ago

Thank you for reporting! I will look at it.

mauvilsa commented 1 month ago

This should be fixed with #518. Though please do test and comment if not working as expected.