Repository: omni-us/jsonargparse

Issue:
Shtab complete: the action.complete of Classes, methods and functions should be `shtab.FILE`
## 🐛 Bug report

Currently, the `action.complete` for `shtab` is `FILE` only when it is `ActionConfigFile` or `Pathlike` for `ActionTypeHint`, however, these doesn't cover the action of `_ActionConfigLoad`.

https://github.com/omni-us/jsonargparse/blob/f5f24221ff6d44f97310e72d808b748da1d30978/jsonargparse/_completions.py#L144-L162

### To reproduce

#### Simple Example

```python
# cli.py
from jsonargparse import ArgumentParser
from calendar import Calendar

class MyClass:
     def __init__(self, calendar: Calendar):
         self.calendar = calendar

parser = ArgumentParser()
parser.add_class_arguments(MyClass, "myclass", sub_configs=True)
cfg = parser.parse_args()
```

```console
λ python cli.py --print_shtab=zsh
...
"--myclass[Path to a configuration file.]:myclass:"
...
```
Expected:
```console
λ python cli.py --print_shtab=zsh
...
"--myclass[Path to a configuration file.]:myclass:_files"
...
```
since the following command work:
```console
python cli.py --myclass test.yaml
```

with `test.yaml`:
```yaml
calendar:
  class_path: calendar.Calendar
  init_args:
    firstweekday: 1
```

### Environment

<!-- Fill in the list below. -->

- jsonargparse version: 4.32.0
- Python version: 3.12
- How jsonargparse was installed: pip
- OS: Ubuntu 22.04


Discussion:
sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=562) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=562&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=562&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=562)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=562) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=562&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=562&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=562&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=562)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.96%. Comparing base [(`f7aa49f`)](https://app.codecov.io/gh/omni-us/jsonargparse/commit/f7aa49f434115f721a16a373c598d5fb9aaa2d5f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) to head [(`80a8f7e`)](https://app.codecov.io/gh/omni-us/jsonargparse/commit/80a8f7e935fb6790fafb6646455aea63e123e138?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us).

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##              main     #562      +/-   ##
===========================================
- Coverage   100.00%   99.96%   -0.04%     
===========================================
  Files           22       22              
  Lines         6445     6445              
===========================================
- Hits          6445     6443       -2     
- Misses           0        2       +2     
```

| [Flag](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | Coverage Δ | |
|---|---|---|
| [py3.10](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `?` | |
| [py3.10_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `?` | |
| [py3.10_pydantic1](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `?` | |
| [py3.10_pydantic2](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `48.51% <50.00%> (ø)` | |
| [py3.10_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `?` | |
| [py3.11](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `85.72% <50.00%> (ø)` | |
| [py3.11_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.69% <100.00%> (ø)` | |
| [py3.11_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.71% <100.00%> (ø)` | |
| [py3.12](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `85.86% <50.00%> (ø)` | |
| [py3.12_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.69% <100.00%> (ø)` | |
| [py3.12_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.71% <100.00%> (ø)` | |
| [py3.7](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `86.17% <50.00%> (ø)` | |
| [py3.7_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.20% <100.00%> (?)` | |
| [py3.7_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.24% <100.00%> (ø)` | |
| [py3.8](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `86.37% <50.00%> (ø)` | |
| [py3.8_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.36% <100.00%> (ø)` | |
| [py3.8_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.39% <100.00%> (ø)` | |
| [py3.9](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `86.26% <50.00%> (?)` | |
| [py3.9_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.28% <100.00%> (ø)` | |
| [py3.9_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.30% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/omni-us/jsonargparse/pull/562?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us).


Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7fc944c..28d4c38 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -21,6 +21,8 @@ Fixed
   (`#559 <https://github.com/omni-us/jsonargparse/pull/559>`__).
 - ``List`` type incorrectly using defaults from previous item (`#560
   <https://github.com/omni-us/jsonargparse/pull/560>`__).
+- ``--print_shtab`` not adding file completer for ``_ActionConfigLoad`` (`#562
+  <https://github.com/omni-us/jsonargparse/pull/562>`__).
 
 
 v4.32.0 (2024-07-19)
diff --git a/jsonargparse/_completions.py b/jsonargparse/_completions.py
index ee722e5..15e6b36 100644
--- a/jsonargparse/_completions.py
+++ b/jsonargparse/_completions.py
@@ -12,7 +12,7 @@ from importlib.util import find_spec
 from subprocess import PIPE, Popen
 from typing import List, Union
 
-from ._actions import ActionConfigFile, _ActionHelpClassPath, remove_actions
+from ._actions import ActionConfigFile, _ActionConfigLoad, _ActionHelpClassPath, remove_actions
 from ._parameter_resolvers import get_signature_parameters
 from ._typehints import (
     ActionTypeHint,
@@ -142,7 +142,7 @@ def shtab_prepare_action(action, parser) -> None:
         return
 
     complete = None
-    if isinstance(action, ActionConfigFile):
+    if isinstance(action, (ActionConfigFile, _ActionConfigLoad)):
         complete = shtab.FILE
     elif isinstance(action, ActionTypeHint):
         typehint = action._typehint


Test patch:
diff --git a/jsonargparse_tests/test_shtab.py b/jsonargparse_tests/test_shtab.py
index ae463a9..9802357 100644
--- a/jsonargparse_tests/test_shtab.py
+++ b/jsonargparse_tests/test_shtab.py
@@ -194,6 +194,12 @@ class Base:
         pass
 
 
+def test_bash_class_config(parser):
+    parser.add_class_arguments(Base, "class")
+    shtab_script = get_shtab_script(parser, "bash")
+    assert "_class_COMPGEN=_shtab_compgen_files" in shtab_script
+
+
 class SubA(Base):
     def __init__(self, p1: int, p2: AXEnum):
         pass