task: metadata: install: pip install -e .[dev]
patch: diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 5172ae0..1f93c04 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -23,6 +23,12 @@ Added
   (`lightning#13613
   <https://github.com/Lightning-AI/pytorch-lightning/discussions/13613>`__)
 
+Fixed
+^^^^^
+- Parsing incorrectly provides file content when type is a union with a
+  subclass, PathLike and string (`#516
+  <https://github.com/omni-us/jsonargparse/issues/516>`__).
+
 
 v4.29.0 (2024-05-24)
 --------------------
diff --git a/jsonargparse/_typehints.py b/jsonargparse/_typehints.py
index 1e28eca..fee45a7 100644
--- a/jsonargparse/_typehints.py
+++ b/jsonargparse/_typehints.py
@@ -198,7 +198,7 @@ class ActionTypeHint(Action):
                     subtypes = tuple(t for t, s in zip(typehint.__args__, subtype_supported) if s)
                     typehint = Union[subtypes]  # type: ignore[assignment]
             self._typehint = typehint
-            self._enable_path = False if is_optional(typehint, Path) else enable_path
+            self._enable_path = False if is_pathlike(typehint) else enable_path
         elif "_typehint" not in kwargs:
             raise ValueError("Expected typehint keyword argument.")
         else:
@@ -647,6 +647,12 @@ class ActionTypeHint(Action):
             return argcomplete_warn_redraw_prompt(prefix, msg)
 
 
+def is_pathlike(typehint) -> bool:
+    if get_typehint_origin(typehint) == Union:
+        return any(is_pathlike(t) for t in typehint.__args__)
+    return is_subclass(typehint, os.PathLike)
+
+
 def raise_unexpected_value(message: str, val: Any = inspect._empty, exception: Optional[Exception] = None) -> NoReturn:
     if val is not inspect._empty:
         message += f". Got value: {val}"

problem_statement: jsonargparse._util._parse_value_or_config
<!-- If you like this project, please ⭐ star it https://github.com/omni-us/jsonargparse/ -->

## 🐛 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
```python
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
```yaml
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

<!-- Fill in the list below. -->

- jsonargparse version (e.g., 4.8.0):
- Python version (e.g., 3.9):
- How jsonargparse was installed (e.g. `pip install jsonargparse[all]`):
- OS (e.g., Linux):

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

repo: omni-us/jsonargparse
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/jsonargparse_tests/test_paths.py b/jsonargparse_tests/test_paths.py
index 81adecd..614267f 100644
--- a/jsonargparse_tests/test_paths.py
+++ b/jsonargparse_tests/test_paths.py
@@ -4,7 +4,7 @@ import json
 import os
 from calendar import Calendar
 from pathlib import Path
-from typing import Any, Dict, List, Optional
+from typing import Any, Dict, List, Optional, Union
 
 import pytest
 
@@ -237,17 +237,44 @@ def test_enable_path_list_path_fr_default_stdin(parser, tmp_cwd, mock_stdin, sub
         assert ["file1", "file2"] == [str(x) for x in cfg.list]
 
 
-class Data:
+class DataOptionalPath:
     def __init__(self, path: Optional[os.PathLike] = None):
         pass
 
 
-def test_enable_path_os_pathlike_subclass_parameter(parser, tmp_cwd):
+def test_enable_path_optional_pathlike_subclass_parameter(parser, tmp_cwd):
     data_path = Path("data.json")
     data_path.write_text('{"a": 1}')
 
-    parser.add_argument("--data", type=Data, enable_path=True)
+    parser.add_argument("--data", type=DataOptionalPath, enable_path=True)
 
-    cfg = parser.parse_args([f"--data={__name__}.Data", f"--data.path={data_path}"])
-    assert cfg.data.class_path == f"{__name__}.Data"
+    cfg = parser.parse_args([f"--data={__name__}.DataOptionalPath", f"--data.path={data_path}"])
+    assert cfg.data.class_path == f"{__name__}.DataOptionalPath"
     assert cfg.data.init_args == Namespace(path=str(data_path))
+
+
+class Base:
+    pass
+
+
+class DataUnionPath:
+    def __init__(self, path: Union[Base, os.PathLike, str] = ""):
+        pass
+
+
+def test_sub_configs_union_subclass_and_pathlike(parser, tmp_cwd):
+    data_path = Path("data.csv")
+    data_path.write_text("x\ny\n")
+    config = {
+        "data": {
+            "path": "data.csv",
+        }
+    }
+    config_path = Path("config.json")
+    config_path.write_text(json.dumps(config))
+
+    parser.add_class_arguments(DataUnionPath, "data", sub_configs=True)
+    parser.add_argument("--cfg", action="config")
+
+    cfg = parser.parse_args([f"--cfg={config_path}"])
+    assert cfg.data.path == str(data_path)