|
32 | 32 | is_optional, |
33 | 33 | is_subclass_container_typehint, |
34 | 34 | not_required_types, |
35 | | - replace_unresolved_forward_refs, |
| 35 | + replace_unvalidatable_typehints, |
36 | 36 | sequence_origin_types, |
37 | 37 | strip_required_typehint, |
38 | 38 | ) |
39 | 39 | from ._util import NoneType, get_import_path, get_private_kwargs, get_typehint_origin, iter_to_set_str |
40 | | -from .typing import _LazyInitBaseClass, register_pydantic_type |
| 40 | +from .typing import _LazyInitBaseClass, register_pydantic_types |
41 | 41 |
|
42 | 42 | kinds = inspect._ParameterKind |
43 | 43 | inspect_empty = inspect._empty |
@@ -341,15 +341,17 @@ def _add_signature_parameter( |
341 | 341 | name = param.name |
342 | 342 | kind = param.kind |
343 | 343 | annotation = param.annotation |
344 | | - unresolved_replaced = replace_unresolved_forward_refs(annotation) |
345 | | - if unresolved_replaced is not annotation: |
| 344 | + register_pydantic_types(annotation) # before the check of what can be validated |
| 345 | + unvalidated: list = [] |
| 346 | + unvalidatable_replaced = replace_unvalidatable_typehints(annotation, unvalidated) |
| 347 | + if unvalidated: |
| 348 | + reasons = " ".join(f"{u.name}: {u.reason}." for u in unvalidated) |
346 | 349 | self.logger.debug( |
347 | | - f'Unable to resolve the type of parameter "{name}" from ' |
348 | | - f'"{get_parameter_origins(param.component, param.parent)}": {annotation}. ' |
349 | | - "The unresolved parts are shown in the help as Unresolved<...> and accept " |
350 | | - "any value, so the parameter is accepted but its value is not validated." |
| 350 | + f'Parameter "{name}" from "{get_parameter_origins(param.component, param.parent)}" has ' |
| 351 | + f"a type that can't be fully validated: {annotation}. {reasons} These parts are shown " |
| 352 | + "in the help as Unvalidated<...> and accept any value without validation." |
351 | 353 | ) |
352 | | - annotation = unresolved_replaced |
| 354 | + annotation = unvalidatable_replaced |
353 | 355 | if default == inspect_empty: |
354 | 356 | default = param.default |
355 | 357 | if default == inspect_empty: |
@@ -437,35 +439,31 @@ def _add_signature_parameter( |
437 | 439 | ) |
438 | 440 | if annotation in {str, int, float, bool} or is_subclass(annotation, (str, int, float)) or subclasses_disabled: |
439 | 441 | kwargs["type"] = annotation |
440 | | - register_pydantic_type(annotation) |
441 | 442 | elif annotation != inspect_empty: |
442 | | - try: |
443 | | - is_subclass_typehint = ActionTypeHint.is_subclass_typehint(annotation, all_subtypes=False) |
444 | | - is_return_subclass_typehint = ActionTypeHint.is_return_subclass_typehint(annotation) |
445 | | - kwargs["type"] = annotation |
446 | | - sub_add_kwargs: dict = {"fail_untyped": fail_untyped, "sub_configs": sub_configs} |
447 | | - if is_subclass_typehint or is_return_subclass_typehint: |
448 | | - prefix = f"{name}.init_args." |
449 | | - nested_skip = {s[len(prefix) :] for s in skip or [] if s.startswith(prefix)} |
450 | | - sub_add_kwargs["skip"] = nested_skip |
451 | | - else: |
452 | | - register_pydantic_type(annotation) |
453 | | - enable_path = sub_configs and ( |
454 | | - is_subclass_typehint |
455 | | - or is_return_subclass_typehint |
456 | | - or is_list_pathlike(annotation) |
457 | | - or is_subclass_container_typehint(annotation) |
458 | | - ) |
459 | | - args = ActionTypeHint.prepare_add_argument( |
460 | | - args=args, |
461 | | - kwargs=kwargs, |
462 | | - enable_path=enable_path, |
463 | | - container=container, |
464 | | - logger=self.logger, |
465 | | - sub_add_kwargs=sub_add_kwargs, |
466 | | - ) |
467 | | - except ValueError as ex: |
468 | | - self.logger.debug(skip_message + str(ex)) |
| 443 | + # No need to handle unsupported types here, since replace_unvalidatable_typehints |
| 444 | + # already replaced them by a type that accepts any value without validation. |
| 445 | + is_subclass_typehint = ActionTypeHint.is_subclass_typehint(annotation, all_subtypes=False) |
| 446 | + is_return_subclass_typehint = ActionTypeHint.is_return_subclass_typehint(annotation) |
| 447 | + kwargs["type"] = annotation |
| 448 | + sub_add_kwargs: dict = {"fail_untyped": fail_untyped, "sub_configs": sub_configs} |
| 449 | + if is_subclass_typehint or is_return_subclass_typehint: |
| 450 | + prefix = f"{name}.init_args." |
| 451 | + nested_skip = {s[len(prefix) :] for s in skip or [] if s.startswith(prefix)} |
| 452 | + sub_add_kwargs["skip"] = nested_skip |
| 453 | + enable_path = sub_configs and ( |
| 454 | + is_subclass_typehint |
| 455 | + or is_return_subclass_typehint |
| 456 | + or is_list_pathlike(annotation) |
| 457 | + or is_subclass_container_typehint(annotation) |
| 458 | + ) |
| 459 | + args = ActionTypeHint.prepare_add_argument( |
| 460 | + args=args, |
| 461 | + kwargs=kwargs, |
| 462 | + enable_path=enable_path, |
| 463 | + container=container, |
| 464 | + logger=self.logger, |
| 465 | + sub_add_kwargs=sub_add_kwargs, |
| 466 | + ) |
469 | 467 | if "type" in kwargs or "action" in kwargs: |
470 | 468 | sub_add_kwargs = { |
471 | 469 | "fail_untyped": fail_untyped, |
|
0 commit comments