Repository: omni-us/jsonargparse

Issue:
Argument linking doesn't work for deep-level targets
Example file:

```python
import jsonargparse
from jsonargparse import ActionConfigFile


class D:
    pass


class A:
    def __init__(self, d: D) -> None:
        self.d = d


class BSuper:
    pass


class BSub(BSuper):
    def __init__(self, a: A) -> None:
        self.a = a


class C:
    def fn(self) -> D:
        return D()


if __name__ == '__main__':
    import a  # Otherwise the superclass namespace would be `__main__` instead of `a` and `issubclass` check would fail.
    # See https://stackoverflow.com/a/38477315/1165181
    parser = jsonargparse.ArgumentParser()
    parser.add_argument("--config", action=ActionConfigFile)
    parser.add_subclass_arguments(a.BSuper, nested_key="b", required=True)
    parser.add_class_arguments(C, nested_key="c")
    parser.link_arguments("c", "b.init_args.a.d", compute_fn=C.fn, apply_on="instantiate")

    args = parser.parse_args(["--config", "a.yml"])
```

`a.yml`:

```yml
b:
  class_path: a.BSub
  init_args:
    a:
      class_path: a.A
c:
```

Discussion:
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list)


mauvilsa: > It's a different issue, but it feels like the parser created in `adapt_class_type` should get some things from the action's parser such as `logger`. For it, this method (and `adapt_typehints`) could be converted into `ActionTypeHint` class methods, get its parser and pass the property, along with potential others.
>
> Finally, this PR also _tries_ to add support for linked targets that are inside dicts, **but I didn't test it**. Still, wanted to get feedback on it. Maybe this part can be for another PR. Also, feels like other paths apart from dicts could be supported, such as lists, as I only added code for it in one of the `if` conditions but not the rest.

Please do split. It seems you have several ideas and it would be easier if things are kept separate. This pull request focus it only on deep targets.

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; ![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=omni-us_jsonargparse&pullRequest=75&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=omni-us_jsonargparse&pullRequest=75&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 078309f..7863e93 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 3.19.2
+current_version = 3.19.3
 commit = True
 tag = True
 tag_name = v{new_version}
diff --git a/.sonarcloud.properties b/.sonarcloud.properties
index ecea699..e2d2a90 100644
--- a/.sonarcloud.properties
+++ b/.sonarcloud.properties
@@ -1,2 +1,2 @@
 sonar.sources=jsonargparse
-sonar.projectVersion=3.19.2
+sonar.projectVersion=3.19.3
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index c195ae2..d86c091 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -10,6 +10,22 @@ only be introduced in major versions with advance notice in the **Deprecated**
 section of releases.
 
 
+v3.19.4 (2021-??-??)
+--------------------
+
+Fixed
+^^^^^
+- self.logger undefined on SignatureArguments #92.
+
+
+v3.19.3 (2021-09-16)
+--------------------
+
+Fixed
+^^^^^
+- add_subclass_arguments with required=False failing on instantiation #83.
+
+
 v3.19.2 (2021-09-09)
 --------------------
 
diff --git a/jsonargparse/__init__.py b/jsonargparse/__init__.py
index dbd4a11..084975c 100644
--- a/jsonargparse/__init__.py
+++ b/jsonargparse/__init__.py
@@ -22,4 +22,4 @@ from .typehints import *
 from .util import *
 
 
-__version__ = '3.19.2'
+__version__ = '3.19.3'
diff --git a/jsonargparse/core.py b/jsonargparse/core.py
index 5c83054..74e6d92 100644
--- a/jsonargparse/core.py
+++ b/jsonargparse/core.py
@@ -77,7 +77,7 @@ default_dump_json_kwargs = {
 }
 
 
-class _ActionsContainer(SignatureArguments, argparse._ActionsContainer):
+class _ActionsContainer(SignatureArguments, argparse._ActionsContainer, LoggerProperty):
     """Extension of argparse._ActionsContainer to support additional functionalities."""
 
     def __init__(self, *args, **kwargs):
@@ -166,7 +166,7 @@ class _ArgumentGroup(_ActionsContainer, argparse._ArgumentGroup):
     parser = None  # type: Union[ArgumentParser, None]
 
 
-class ArgumentParser(_ActionsContainer, argparse.ArgumentParser, LoggerProperty):
+class ArgumentParser(_ActionsContainer, argparse.ArgumentParser):
     """Parser for command line, yaml/jsonnet files and environment variables."""
 
     groups = None  # type: Dict[str, argparse._ArgumentGroup]
diff --git a/jsonargparse/signatures.py b/jsonargparse/signatures.py
index ba936c6..d0e509a 100644
--- a/jsonargparse/signatures.py
+++ b/jsonargparse/signatures.py
@@ -2,7 +2,7 @@
 
 import inspect
 import re
-from argparse import Namespace
+from argparse import Namespace, SUPPRESS
 from functools import wraps
 from typing import Any, Callable, List, Optional, Set, Tuple, Type, Union
 
@@ -491,7 +491,7 @@ class SignatureArguments:
             {},
             added_args,
             skip,
-            default={},
+            default=SUPPRESS,
             sub_configs=True,
             instantiate=instantiate,
             **kwargs
diff --git a/jsonargparse/typehints.py b/jsonargparse/typehints.py
index 387f644..eaf84fe 100644
--- a/jsonargparse/typehints.py
+++ b/jsonargparse/typehints.py
@@ -1,5 +1,5 @@
 """Action to support type hints."""
-
+import copy
 import inspect
 import os
 import re
@@ -345,7 +345,8 @@ def adapt_typehints(val, typehint, serialize=False, instantiate_classes=False, s
             if isinstance(val, typehint):
                 val = val.name
             else:
-                typehint[val]
+                if val not in typehint:
+                    raise ValueError('Value "'+str(val)+'" is not a valid member name for the enum "'+str(typehint)+'"')
         elif not serialize and not isinstance(val, typehint):
             val = typehint[val]
 
@@ -410,7 +411,16 @@ def adapt_typehints(val, typehint, serialize=False, instantiate_classes=False, s
                 cast = str if serialize else int
                 val = {cast(k): v for k, v in val.items()}
             for k, v in val.items():
-                val[k] = adapt_typehints(v, subtypehints[1], **adapt_kwargs)
+                if "linked_targets" in adapt_kwargs["sub_add_kwargs"]:
+                    kwargs = copy.deepcopy(adapt_kwargs)
+                    sub_add_kwargs = kwargs["sub_add_kwargs"]
+                    sub_add_kwargs["linked_targets"] = {t[len(k + "."):] for t in sub_add_kwargs["linked_targets"]
+                                                        if t.startswith(k + ".")}
+                    sub_add_kwargs["linked_targets"] = {t[len("init_args."):] if t.startswith("init_args.") else t
+                                                        for t in sub_add_kwargs["linked_targets"]}
+                else:
+                    kwargs = adapt_kwargs
+                val[k] = adapt_typehints(v, subtypehints[1], **kwargs)
 
     # Final class
     elif is_final_class(typehint):
@@ -462,6 +472,23 @@ def adapt_class_type(val_class, init_args, serialize, instantiate_classes, sub_a
     from .core import ArgumentParser
     parser = ArgumentParser(error_handler=None, parse_as_dict=True)
     parser.add_class_arguments(val_class, **sub_add_kwargs)
+
+    # No need to re-create the linked arg but just "inform" the corresponding parser actions that it exists upstream.
+    for target in sub_add_kwargs.get('linked_targets', []):
+        split_index = target.find(".")
+        if split_index != -1:
+            split = ".init_args." if target[split_index:].startswith(".init_args.") else "."
+
+            parent_key, key = target.split(split, maxsplit=1)
+
+            action = next(a for a in parser._actions if a.dest == parent_key)
+
+            sub_add_kwargs = getattr(action, 'sub_add_kwargs')
+            sub_add_kwargs.setdefault('linked_targets', set())
+            sub_add_kwargs['linked_targets'].add(key)
+
+            break
+
     if instantiate_classes:
         init_args = parser.instantiate_subclasses(init_args)
         if not sub_add_kwargs.get('instantiate', True):
diff --git a/setup.cfg b/setup.cfg
index 5d0e02a..c868b28 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -57,7 +57,7 @@ doc =
 
 [metadata]
 name = jsonargparse
-version = 3.19.2
+version = 3.19.3
 description = Parsing of command line options, yaml/jsonnet config files and/or environment variables based on argparse.
 long_description_content_type = text/x-rst
 author = Mauricio Villegas


Test patch:
diff --git a/jsonargparse_tests/signatures_tests.py b/jsonargparse_tests/signatures_tests.py
index 87a55d4..757d37e 100755
--- a/jsonargparse_tests/signatures_tests.py
+++ b/jsonargparse_tests/signatures_tests.py
@@ -386,7 +386,9 @@ class SignaturesTests(unittest.TestCase):
         parser = ArgumentParser(parse_as_dict=True, error_handler=None)
         parser.add_subclass_arguments(calendar.Calendar, 'cal', required=False)
         cfg = parser.parse_args([])
-        self.assertEqual(cfg, {'cal': {}})
+        self.assertEqual(cfg, {})
+        cfg_init = parser.instantiate_classes(cfg)
+        self.assertEqual(cfg_init, {})
 
 
     def test_invalid_type(self):
diff --git a/jsonargparse_tests/typehints_tests.py b/jsonargparse_tests/typehints_tests.py
index 4bd0b10..ffb7d23 100755
--- a/jsonargparse_tests/typehints_tests.py
+++ b/jsonargparse_tests/typehints_tests.py
@@ -9,7 +9,7 @@ import yaml
 from calendar import Calendar
 from datetime import datetime
 from enum import Enum
-from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Type, Union
+from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Type, Union
 from jsonargparse_tests.base import *
 from jsonargparse.typehints import is_optional, Literal
 
@@ -467,6 +467,116 @@ class TypeHintsTmpdirTests(TempDirTestCase):
         self.assertIn('firstweekday: 3\n', cfg)
 
 
+    def test_linking_deep_targets(self):
+        class D:
+            pass
+
+        class A:
+            def __init__(self, d: D) -> None:
+                self.d = d
+
+        class BSuper:
+            pass
+
+        class BSub(BSuper):
+            def __init__(self, a: A) -> None:
+                self.a = a
+
+        class C:
+            def fn(self) -> D:
+                return D()
+
+        config = {
+            "b": {
+                "class_path": "jsonargparse_tests.BSub",
+                "init_args": {
+                    "a": {
+                        "class_path": "jsonargparse_tests.A",
+                    },
+                },
+            },
+            "c": {},
+        }
+        config_path = os.path.join(self.tmpdir, 'config.yaml')
+        with open(config_path, 'w') as f:
+            yaml.safe_dump(config, f)
+
+        import jsonargparse_tests
+        setattr(jsonargparse_tests, 'D', D)
+        setattr(jsonargparse_tests, 'A', A)
+        setattr(jsonargparse_tests, 'BSuper', BSuper)
+        setattr(jsonargparse_tests, 'BSub', BSub)
+        setattr(jsonargparse_tests, 'C', C)
+
+        parser = ArgumentParser()
+        parser.add_argument("--config", action=ActionConfigFile)
+        parser.add_subclass_arguments(BSuper, nested_key="b", required=True)
+        parser.add_class_arguments(C, nested_key="c")
+        parser.link_arguments("c", "b.init_args.a.init_args.d", compute_fn=C.fn, apply_on="instantiate")
+
+        args = parser.parse_args(["--config", config_path])
+
+        config = parser.instantiate_classes(args)
+
+        assert isinstance(config["b"].a.d, D)
+
+
+    def test_linking_deep_targets_mapping(self):
+        class D:
+            pass
+
+        class A:
+            def __init__(self, d: D) -> None:
+                self.d = d
+
+        class BSuper:
+            pass
+
+        class BSub(BSuper):
+            def __init__(self, a_map: Mapping[str, A]) -> None:
+                self.a_map = a_map
+
+        class C:
+            def fn(self) -> D:
+                return D()
+
+        config = {
+            "b": {
+                "class_path": "jsonargparse_tests.BSub",
+                "init_args": {
+                    "a_map": {
+                        "name": {
+                            "class_path": "jsonargparse_tests.A",
+                        },
+                    },
+                },
+            },
+            "c": {},
+        }
+        config_path = os.path.join(self.tmpdir, 'config.yaml')
+        with open(config_path, 'w') as f:
+            yaml.safe_dump(config, f)
+
+        import jsonargparse_tests
+        setattr(jsonargparse_tests, 'D', D)
+        setattr(jsonargparse_tests, 'A', A)
+        setattr(jsonargparse_tests, 'BSuper', BSuper)
+        setattr(jsonargparse_tests, 'BSub', BSub)
+        setattr(jsonargparse_tests, 'C', C)
+
+        parser = ArgumentParser()
+        parser.add_argument("--config", action=ActionConfigFile)
+        parser.add_subclass_arguments(BSuper, nested_key="b", required=True)
+        parser.add_class_arguments(C, nested_key="c")
+        parser.link_arguments("c", "b.init_args.a_map.name.init_args.d", compute_fn=C.fn, apply_on="instantiate")
+
+        args = parser.parse_args(["--config", config_path])
+
+        config = parser.instantiate_classes(args)
+
+        assert isinstance(config["b"].a_map["name"].d, D)
+
+
 class OtherTests(unittest.TestCase):
 
     def test_is_optional(self):