Repository: omni-us/jsonargparse
Pull request #475 (2024-03-18 10:05:28)

Feature path std io
<!--
Thank you very much for contributing! If you like this project, please ⭐ star it
https://github.com/omni-us/jsonargparse/
-->

## What does this PR do?

Add support for "-" as value for Path class initialization so that user
can ask to use standard input/output instead of file.

For instance, users who are used to type their input files with Path_fr will now be able to give "-" as input string so that get_content or open (of Path_fr class) will read the standard input stream without having nothing more to do. Same for output.

Note that some code has been added for typehiting so that it does not create conflict with another feature: giving "-" to specify that a list of files is given through the standard input.

## Before submitting

<!--
Use the following list as tasks to be completed before marking a pull request as
"Ready for review". Fill with an "x" all tasks done. Use "n/a" if you think a
task is not relevant or leave empty when in doubt.
-->

- [ X ] Did you read the [contributing guideline](https://github.com/omni-us/jsonargparse/blob/main/CONTRIBUTING.rst)?
- [ X ] Did you update **the documentation**? (readme and public docstrings)
- [ X ] Did you write **unit tests** such that there is 100% coverage on related code? (required for bug fixes and new features)
- [ X ] Did you verify that new and existing **tests pass locally**?
- [ X ] Did you make sure that all changes preserve **backward compatibility**?
- [ X ] Did you update **the CHANGELOG**? (not for typos, docs, test updates, or minor internal changes/refactors)


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=475) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) Report
Attention: Patch coverage is `97.14286%` with `1 lines` in your changes are missing coverage. Please review.
> Project coverage is 99.90%. Comparing base [(`bb83fdc`)](https://app.codecov.io/gh/omni-us/jsonargparse/commit/bb83fdc76546743ad0e4e7012715febd965f34ac?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) to head [(`bfc35c3`)](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us).

| [Files](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | Patch % | Lines |
|---|---|---|
| [jsonargparse/\_util.py](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us#diff-anNvbmFyZ3BhcnNlL191dGlsLnB5) | 96.42% | [1 Missing :warning: ](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475?src=pr&el=tree&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     #475      +/-   ##
===========================================
- Coverage   100.00%   99.90%   -0.10%     
===========================================
  Files           21       21              
  Lines         6008     6023      +15     
===========================================
+ Hits          6008     6017       +9     
- Misses           0        6       +6     
```

| [Flag](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/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/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `88.32% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.10_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.10_pydantic1](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `48.91% <31.42%> (-0.01%)` | :arrow_down: |
| [py3.10_pydantic2](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `48.63% <28.57%> (-0.03%)` | :arrow_down: |
| [py3.10_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.11](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `88.31% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.11_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.11_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.12](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `88.31% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.12_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.12_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `98.63% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.7](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `88.89% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.7_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.39% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.7_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.38% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.8](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `89.04% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.8_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.41% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.8_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.40% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.9](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `88.89% <97.14%> (-0.08%)` | :arrow_down: |
| [py3.9_all](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.28% <97.14%> (-0.10%)` | :arrow_down: |
| [py3.9_types](https://app.codecov.io/gh/omni-us/jsonargparse/pull/475/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=omni-us) | `99.28% <97.14%> (-0.10%)` | :arrow_down: |

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/475?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).

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=475) **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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)


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=475) **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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)


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=475) **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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)


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=475) **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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)


mquillot: I think @mauvilsa you can review a second time. I tried to follow you recommandations as soon as possible. 
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=475) **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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=475&metric=new_accepted_issues&view=list)

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=475&resolved=false&inNewCodePeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/no-data-16px.png '') No data about Coverage  
![](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=475&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=omni-us_jsonargparse&pullRequest=475)



Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 2d4915d..c36826e 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -11,6 +11,13 @@ The semantic versioning only considers the public API as described in
 :ref:`api-ref`. Components not mentioned in :ref:`api-ref` or different import
 paths are considered internals and can change in minor and patch releases.
 
+v4.28.0 (2024-03-??)
+--------------------
+
+Added
+^^^^^
+- Support for "-" as value for Path class initialization so that user
+  can ask to use standard input/output instead of file.
 
 v4.27.7 (2024-03-21)
 --------------------
diff --git a/jsonargparse/_typehints.py b/jsonargparse/_typehints.py
index 6dab180..1c87980 100644
--- a/jsonargparse/_typehints.py
+++ b/jsonargparse/_typehints.py
@@ -41,7 +41,14 @@ from ._actions import (
     _is_action_value_list,
     remove_actions,
 )
-from ._common import get_class_instantiator, is_dataclass_like, is_subclass, nested_links, parent_parser, parser_context
+from ._common import (
+    get_class_instantiator,
+    is_dataclass_like,
+    is_subclass,
+    nested_links,
+    parent_parser,
+    parser_context,
+)
 from ._loaders_dumpers import (
     get_loader_exceptions,
     load_value,
@@ -70,7 +77,6 @@ from ._util import (
     iter_to_set_str,
     object_path_serializer,
     parse_value_or_config,
-    read_stdin,
     warning,
 )
 from .typing import get_registered_type, is_pydantic_type
@@ -501,6 +507,8 @@ class ActionTypeHint(Action):
                         val = adapt_typehints(val, self._typehint, **kwargs)
                 except ValueError as ex:
                     assert ex  # needed due to ruff bug that removes " as ex"
+                    if orig_val == "-":
+                        raise ex
                     try:
                         if isinstance(orig_val, str):
                             with change_to_path_dir(config_path):
@@ -757,14 +765,11 @@ def adapt_typehints(
             val = prev_val + (val if val_is_list else [val])
             prev_val = prev_val + [None] * (len(val) - len(prev_val) if val_is_list else 1)
         if enable_path and type(val) is str:
-            if val == "-":
-                val = read_stdin().splitlines()
-            else:
-                with suppress(TypeError):
-                    from ._optionals import get_config_read_mode
+            with suppress(TypeError):
+                from ._optionals import get_config_read_mode
 
-                    list_path = Path(val, mode=get_config_read_mode())
-                    val = list_path.get_content().splitlines()
+                list_path = Path(val, mode=get_config_read_mode())
+                val = list_path.get_content().splitlines()
         if isinstance(val, NestedArg) and subtypehints is not None:
             val = (prev_val[:-1] if isinstance(prev_val, list) else []) + [val]
         elif isinstance(val, Iterable) and not isinstance(val, (list, str)) and type(val) not in mapping_origin_types:
diff --git a/jsonargparse/_util.py b/jsonargparse/_util.py
index 170451c..726117f 100644
--- a/jsonargparse/_util.py
+++ b/jsonargparse/_util.py
@@ -29,7 +29,13 @@ from typing import (
     get_type_hints,
 )
 
-from ._common import ClassType, get_generic_origin, is_subclass, parser_capture, parser_context
+from ._common import (
+    ClassType,
+    get_generic_origin,
+    is_subclass,
+    parser_capture,
+    parser_context,
+)
 from ._deprecated import PathDeprecations
 from ._loaders_dumpers import json_dump, load_value
 from ._optionals import (
@@ -127,7 +133,7 @@ def parse_value_or_config(
         nested_arg = value
         value = nested_arg.val
     cfg_path = None
-    if enable_path and type(value) is str:
+    if enable_path and type(value) is str and value != "-":
         try:
             cfg_path = Path(value, mode=get_config_read_mode())
         except TypeError:
@@ -150,14 +156,6 @@ class CachedStdin(StringIO):
     """Used to allow reading sys.stdin multiple times."""
 
 
-def read_stdin() -> str:
-    if not isinstance(sys.stdin, CachedStdin):
-        sys.stdin = CachedStdin(sys.stdin.read())
-    value = sys.stdin.read()
-    sys.stdin.seek(0)
-    return value
-
-
 def import_object(name: str):
     """Returns an object in a module given its dot import path."""
     if not isinstance(name, str) or "." not in name:
@@ -451,6 +449,11 @@ class Path(PathDeprecations):
     The creatable flag "c" can be given one or two times. If give once, the
     parent directory must exist and be writeable. If given twice, the parent
     directory does not have to exist, but should be allowed to create.
+
+    An instance of Path class can also refer to the standard input or output.
+    To do that, path must be set with the value "-"; it is a common practice.
+    Then, getting the content or opening it will automatically be done on
+    standard input or output.
     """
 
     _url_data: Optional[UrlData]
@@ -476,10 +479,12 @@ class Path(PathDeprecations):
         """
         self._deprecated_kwargs(kwargs)
         self._check_mode(mode)
+        self._std_io = False
 
         is_url = False
         is_fsspec = False
         if isinstance(path, Path):
+            self.std_io = path._std_io
             is_url = path.is_url
             is_fsspec = path.is_fsspec
             url_data = path._url_data
@@ -487,6 +492,8 @@ class Path(PathDeprecations):
             abs_path = path._absolute
             path = path._relative
         elif isinstance(path, (str, os.PathLike)):
+            if path == "-":
+                self._std_io = True
             path = os.fspath(path)
             cwd = os.fspath(cwd) if cwd else None
             abs_path = os.path.expanduser(path)
@@ -533,7 +540,7 @@ class Path(PathDeprecations):
                     raise TypeError(f"Path does not exist: {abs_path!r}") from ex
                 except PermissionError as ex:
                     raise TypeError(f"Path exists but no permission to access: {abs_path!r}") from ex
-        elif not self._skip_check:
+        elif not self._skip_check and not self._std_io:
             ptype = "Directory" if "d" in mode else "File"
             if "c" in mode:
                 pdir = os.path.realpath(os.path.join(abs_path, ".."))
@@ -557,6 +564,7 @@ class Path(PathDeprecations):
                     raise TypeError(f"Path is not a directory: {abs_path!r}")
                 if "f" in mode and not (os.path.isfile(abs_path) or stat.S_ISFIFO(os.stat(abs_path).st_mode)):
                     raise TypeError(f"Path is not a file: {abs_path!r}")
+
             if "r" in mode and not os.access(abs_path, os.R_OK):
                 raise TypeError(f"{ptype} is not readable: {abs_path!r}")
             if "w" in mode and not os.access(abs_path, os.W_OK):
@@ -635,7 +643,9 @@ class Path(PathDeprecations):
 
     def get_content(self, mode: str = "r") -> str:
         """Returns the contents of the file or the remote path."""
-        if self._is_url:
+        if self._std_io:
+            return sys.stdin.read()
+        elif self._is_url:
             assert mode == "r"
             requests = import_requests("Path.get_content")
             response = requests.get(self._absolute)
@@ -653,7 +663,12 @@ class Path(PathDeprecations):
     @contextmanager
     def open(self, mode: str = "r") -> Iterator[IO]:
         """Return an opened file object for the path."""
-        if self._is_url:
+        if self._std_io:
+            if "r" in mode:
+                yield sys.stdin
+            elif "w" in mode:
+                yield sys.stdout
+        elif self._is_url:
             yield StringIO(self.get_content())
         elif self._is_fsspec:
             fsspec = import_fsspec("Path.open")


Test patch:
diff --git a/jsonargparse_tests/test_util.py b/jsonargparse_tests/test_util.py
index 14c9326..3c0aef3 100644
--- a/jsonargparse_tests/test_util.py
+++ b/jsonargparse_tests/test_util.py
@@ -7,6 +7,7 @@ import stat
 import zipfile
 from calendar import Calendar
 from importlib import import_module
+from io import StringIO
 from random import Random
 from unittest.mock import patch
 
@@ -216,6 +217,30 @@ def test_path_tilde_home(paths):
         assert path() == os.path.join(paths.tmp_path, paths.file_rw)
 
 
+def test_std_input_path():
+    input_text_to_test = "a text here\n"
+
+    with patch("sys.stdin", StringIO(input_text_to_test)):
+        path = Path("-", mode="fr")
+        assert path == "-"
+        assert input_text_to_test == path.get_content("r")
+
+    with patch("sys.stdin", StringIO(input_text_to_test)):
+        path = Path("-", mode="fr")
+        with path.open("r") as std_input:
+            assert input_text_to_test == "".join([line for line in std_input])
+
+
+def test_std_output_path():
+    path = Path("-", mode="fw")
+    assert path == "-"
+    output = StringIO("")
+    with patch("sys.stdout", output):
+        with path.open("w") as std_output:
+            std_output.write("test\n")
+    assert output.getvalue() == "test\n"
+
+
 # url tests