@@ -140,6 +140,11 @@ class DIWiringWarning(RuntimeWarning):
140140 """Base class for all warnings raised by the wiring module."""
141141
142142
143+ class UnresolvedMarkerWarning (DIWiringWarning ):
144+ """Warning raised for markers (Provide, Provider, Closing) with string
145+ identifiers that cannot be resolved against current container."""
146+
147+
143148class PatchedRegistry :
144149
145150 def __init__ (self ) -> None :
@@ -434,6 +439,7 @@ def wire( # noqa: C901
434439 modules : Optional [Iterable [ModuleType ]] = None ,
435440 packages : Optional [Iterable [ModuleType ]] = None ,
436441 keep_cache : bool = False ,
442+ warn_unresolved : bool = False ,
437443) -> None :
438444 """Wire container providers with provided packages and modules."""
439445 modules = [* modules ] if modules else []
@@ -450,9 +456,23 @@ def wire( # noqa: C901
450456 continue
451457
452458 if _is_marker (member ):
453- _patch_attribute (module , member_name , member , providers_map )
459+ _patch_attribute (
460+ module ,
461+ member_name ,
462+ member ,
463+ providers_map ,
464+ warn_unresolved = warn_unresolved ,
465+ warn_unresolved_stacklevel = 1 ,
466+ )
454467 elif inspect .isfunction (member ):
455- _patch_fn (module , member_name , member , providers_map )
468+ _patch_fn (
469+ module ,
470+ member_name ,
471+ member ,
472+ providers_map ,
473+ warn_unresolved = warn_unresolved ,
474+ warn_unresolved_stacklevel = 1 ,
475+ )
456476 elif inspect .isclass (member ):
457477 cls = member
458478 try :
@@ -464,15 +484,30 @@ def wire( # noqa: C901
464484 for cls_member_name , cls_member in cls_members :
465485 if _is_marker (cls_member ):
466486 _patch_attribute (
467- cls , cls_member_name , cls_member , providers_map
487+ cls ,
488+ cls_member_name ,
489+ cls_member ,
490+ providers_map ,
491+ warn_unresolved = warn_unresolved ,
492+ warn_unresolved_stacklevel = 1 ,
468493 )
469494 elif _is_method (cls_member ):
470495 _patch_method (
471- cls , cls_member_name , cls_member , providers_map
496+ cls ,
497+ cls_member_name ,
498+ cls_member ,
499+ providers_map ,
500+ warn_unresolved = warn_unresolved ,
501+ warn_unresolved_stacklevel = 1 ,
472502 )
473503
474504 for patched in _patched_registry .get_callables_from_module (module ):
475- _bind_injections (patched , providers_map )
505+ _bind_injections (
506+ patched ,
507+ providers_map ,
508+ warn_unresolved = warn_unresolved ,
509+ warn_unresolved_stacklevel = 1 ,
510+ )
476511
477512 if not keep_cache :
478513 clear_cache ()
@@ -525,14 +560,21 @@ def _patch_fn(
525560 name : str ,
526561 fn : Callable [..., Any ],
527562 providers_map : ProvidersMap ,
563+ warn_unresolved : bool = False ,
564+ warn_unresolved_stacklevel : int = 0 ,
528565) -> None :
529566 if not _is_patched (fn ):
530567 reference_injections , reference_closing = _fetch_reference_injections (fn )
531568 if not reference_injections :
532569 return
533570 fn = _get_patched (fn , reference_injections , reference_closing )
534571
535- _bind_injections (fn , providers_map )
572+ _bind_injections (
573+ fn ,
574+ providers_map ,
575+ warn_unresolved = warn_unresolved ,
576+ warn_unresolved_stacklevel = warn_unresolved_stacklevel + 1 ,
577+ )
536578
537579 setattr (module , name , fn )
538580
@@ -542,6 +584,8 @@ def _patch_method(
542584 name : str ,
543585 method : Callable [..., Any ],
544586 providers_map : ProvidersMap ,
587+ warn_unresolved : bool = False ,
588+ warn_unresolved_stacklevel : int = 0 ,
545589) -> None :
546590 if (
547591 hasattr (cls , "__dict__" )
@@ -559,7 +603,12 @@ def _patch_method(
559603 return
560604 fn = _get_patched (fn , reference_injections , reference_closing )
561605
562- _bind_injections (fn , providers_map )
606+ _bind_injections (
607+ fn ,
608+ providers_map ,
609+ warn_unresolved = warn_unresolved ,
610+ warn_unresolved_stacklevel = warn_unresolved_stacklevel + 1 ,
611+ )
563612
564613 if fn is method :
565614 # Hotfix, see: https://github.com/ets-labs/python-dependency-injector/issues/884
@@ -595,9 +644,17 @@ def _patch_attribute(
595644 name : str ,
596645 marker : "_Marker" ,
597646 providers_map : ProvidersMap ,
647+ warn_unresolved : bool = False ,
648+ warn_unresolved_stacklevel : int = 0 ,
598649) -> None :
599650 provider = providers_map .resolve_provider (marker .provider , marker .modifier )
600651 if provider is None :
652+ if warn_unresolved :
653+ warn (
654+ f"Unresolved marker { name } in { member !r} " ,
655+ UnresolvedMarkerWarning ,
656+ stacklevel = warn_unresolved_stacklevel + 2 ,
657+ )
601658 return
602659
603660 _patched_registry .register_attribute (PatchedAttribute (member , name , marker ))
@@ -674,7 +731,12 @@ def _fetch_reference_injections( # noqa: C901
674731 return injections , closing
675732
676733
677- def _bind_injections (fn : Callable [..., Any ], providers_map : ProvidersMap ) -> None :
734+ def _bind_injections (
735+ fn : Callable [..., Any ],
736+ providers_map : ProvidersMap ,
737+ warn_unresolved : bool = False ,
738+ warn_unresolved_stacklevel : int = 0 ,
739+ ) -> None :
678740 patched_callable = _patched_registry .get_callable (fn )
679741 if patched_callable is None :
680742 return
@@ -683,6 +745,12 @@ def _bind_injections(fn: Callable[..., Any], providers_map: ProvidersMap) -> Non
683745 provider = providers_map .resolve_provider (marker .provider , marker .modifier )
684746
685747 if provider is None :
748+ if warn_unresolved :
749+ warn (
750+ f"Unresolved marker { injection } in { fn .__qualname__ } " ,
751+ UnresolvedMarkerWarning ,
752+ stacklevel = warn_unresolved_stacklevel + 2 ,
753+ )
686754 continue
687755
688756 if isinstance (marker , Provide ):
0 commit comments