@@ -1654,89 +1654,176 @@ def test_binder_has_implicit_binding_for_implicitly_bound_type():
16541654 assert not injector .binder .has_explicit_binding_for (int )
16551655
16561656
1657- def test_get_bindings () :
1658- def function1 (a : int ) -> None :
1657+ def test_gets_no_bindings_without_injection () -> None :
1658+ def function (a : int ) -> None :
16591659 pass
16601660
1661- assert get_bindings (function1 ) == {}
1661+ assert get_bindings (function ) == {}
16621662
1663+
1664+ def test_gets_bindings_with_inject_decorator () -> None :
16631665 @inject
1664- def function2 (a : int ) -> None :
1666+ def function (a : int ) -> None :
16651667 pass
16661668
1667- assert get_bindings (function2 ) == {'a' : int }
1669+ assert get_bindings (function ) == {'a' : int }
1670+
16681671
1672+ def test_gets_multiple_bindings_with_inject_decorator () -> None :
16691673 @inject
1670- @noninjectable ('b' )
1671- def function3 (a : int , b : str ) -> None :
1674+ def function (a : int , b : str ) -> None :
16721675 pass
16731676
1674- assert get_bindings (function3 ) == {'a' : int }
1677+ assert get_bindings (function ) == {'a' : int , 'b' : str }
1678+
1679+
1680+ def test_only_gets_injectable_bindings_without_noninjectable_decorator () -> None :
1681+ @inject
1682+ @noninjectable ('b' )
1683+ def function1 (a : int , b : str ) -> None :
1684+ pass
16751685
16761686 # Let's verify that the inject/noninjectable ordering doesn't matter
16771687 @noninjectable ('b' )
16781688 @inject
1679- def function3b (a : int , b : str ) -> None :
1689+ def function2 (a : int , b : str ) -> None :
16801690 pass
16811691
1682- assert get_bindings (function3b ) == {'a' : int }
1692+ assert get_bindings (function1 ) == {'a' : int } == get_bindings (function2 )
1693+
16831694
1684- # The simple case of no @inject but injection requested with Inject[...]
1685- def function4 (a : Inject [int ], b : str ) -> None :
1695+ def test_gets_bindings_with_inject_annotation () -> None :
1696+ def function (a : Inject [int ], b : str ) -> None :
16861697 pass
16871698
1688- assert get_bindings (function4 ) == {'a' : int }
1699+ assert get_bindings (function ) == {'a' : int }
1700+
1701+
1702+ def test_gets_multiple_bindings_with_inject_annotation () -> None :
1703+ def function (a : Inject [int ], b : Inject [str ]) -> None :
1704+ pass
1705+
1706+ assert get_bindings (function ) == {'a' : int , 'b' : str }
1707+
16891708
1690- # Using @inject with Inject is redundant but it should not break anything
1709+ def test_gets_bindings_inject_with_redundant_inject_annotation () -> None :
16911710 @inject
1692- def function5 (a : Inject [int ], b : str ) -> None :
1711+ def function (a : Inject [int ], b : str ) -> None :
16931712 pass
16941713
1695- assert get_bindings (function5 ) == {'a' : int , 'b' : str }
1714+ assert get_bindings (function ) == {'a' : int , 'b' : str }
16961715
1697- # We need to be able to exclude a parameter from injection with NoInject
1716+
1717+ def test_only_gets_bindings_without_noinject_annotation () -> None :
16981718 @inject
1699- def function6 (a : int , b : NoInject [str ]) -> None :
1719+ def function (a : int , b : NoInject [str ]) -> None :
17001720 pass
17011721
1702- assert get_bindings (function6 ) == {'a' : int }
1722+ assert get_bindings (function ) == {'a' : int }
1723+
17031724
1704- # The presence of NoInject should not trigger anything on its own
1705- def function7 (a : int , b : NoInject [str ]) -> None :
1725+ def test_gets_no_bindings_for_noinject_annotation_only () -> None :
1726+ def function (a : int , b : NoInject [str ]) -> None :
17061727 pass
17071728
1708- assert get_bindings (function7 ) == {}
1729+ assert get_bindings (function ) == {}
17091730
1731+
1732+ def test_gets_no_bindings_for_multiple_noinject_annotations () -> None :
17101733 # There was a bug where in case of multiple NoInject-decorated parameters only the first one was
17111734 # actually made noninjectable and we tried to inject something we couldn't possibly provide
17121735 # into the second one.
17131736 @inject
1714- def function8 (a : NoInject [int ], b : NoInject [int ]) -> None :
1737+ def function (a : NoInject [int ], b : NoInject [int ]) -> None :
17151738 pass
17161739
1717- assert get_bindings (function8 ) == {}
1740+ assert get_bindings (function ) == {}
1741+
17181742
1719- # Default arguments to NoInject annotations should behave the same as noninjectable decorator w.r.t ' None'
1743+ def test_get_bindings_noinject_with_default_should_behave_identically () -> None :
17201744 @inject
17211745 @noninjectable ('b' )
1722- def function9 (self , a : int , b : Optional [str ] = None ):
1746+ def function1 (self , a : int , b : Optional [str ] = None ) -> None :
17231747 pass
17241748
17251749 @inject
1726- def function10 (self , a : int , b : NoInject [Optional [str ]] = None ):
1727- # b: s type is Union[NoInject[Union[str, None]], None]
1750+ def function2 (self , a : int , b : NoInject [Optional [str ]] = None ) -> None :
1751+ # b' s type is Union[NoInject[Union[str, None]], None]
17281752 pass
17291753
1730- assert get_bindings (function9 ) == {'a' : int } == get_bindings (function10 )
1754+ assert get_bindings (function1 ) == {'a' : int } == get_bindings (function2 )
17311755
1756+
1757+ def test_get_bindings_with_an_invalid_forward_reference_return_type () -> None :
17321758 # If there's a return type annottion that contains an a forward reference that can't be
17331759 # resolved (for whatever reason) we don't want that to break things for us – return types
17341760 # don't matter for the purpose of dependency injection.
17351761 @inject
1736- def function11 (a : int ) -> 'InvalidForwardReference' :
1762+ def function (a : int ) -> 'InvalidForwardReference' :
1763+ pass
1764+
1765+ assert get_bindings (function ) == {'a' : int }
1766+
1767+
1768+ def test_gets_bindings_for_annotated_type_with_inject_decorator () -> None :
1769+ UserID = Annotated [int , 'user_id' ]
1770+
1771+ @inject
1772+ def function (a : UserID , b : str ) -> None :
1773+ pass
1774+
1775+ assert get_bindings (function ) == {'a' : UserID , 'b' : str }
1776+
1777+
1778+ def test_gets_bindings_of_annotated_type_with_inject_annotation () -> None :
1779+ UserID = Annotated [int , 'user_id' ]
1780+
1781+ def function (a : Inject [UserID ], b : Inject [str ]) -> None :
1782+ pass
1783+
1784+ assert get_bindings (function ) == {'a' : UserID , 'b' : str }
1785+
1786+
1787+ def test_gets_bindings_of_new_type_with_inject_annotation () -> None :
1788+ Name = NewType ('Name' , str )
1789+
1790+ @inject
1791+ def function (a : Name , b : str ) -> None :
1792+ pass
1793+
1794+ assert get_bindings (function ) == {'a' : Name , 'b' : str }
1795+
1796+
1797+ def test_gets_bindings_of_inject_annotation_with_new_type () -> None :
1798+ def function (a : Inject [Name ], b : str ) -> None :
1799+ pass
1800+
1801+ assert get_bindings (function ) == {'a' : Name }
1802+
1803+
1804+ def test_get_bindings_of_nested_noinject_inject_annotation () -> None :
1805+ # This is not how this is intended to be used
1806+ def function (a : Inject [NoInject [int ]], b : NoInject [Inject [str ]]) -> None :
1807+ pass
1808+
1809+ assert get_bindings (function ) == {}
1810+
1811+
1812+ def test_get_bindings_of_nested_noinject_inject_annotation_and_inject_decorator () -> None :
1813+ # This is not how this is intended to be used
1814+ @inject
1815+ def function (a : Inject [NoInject [int ]], b : NoInject [Inject [str ]]) -> None :
17371816 pass
17381817
1739- assert get_bindings (function11 ) == {'a' : int }
1818+ assert get_bindings (function ) == {}
1819+
1820+
1821+ def test_get_bindings_of_nested_inject_annotations () -> None :
1822+ # This is not how this is intended to be used
1823+ def function (a : Inject [Inject [int ]]) -> None :
1824+ pass
1825+
1826+ assert get_bindings (function ) == {'a' : int }
17401827
17411828
17421829# Tests https://github.com/alecthomas/injector/issues/202
@@ -1824,19 +1911,78 @@ def configure(binder):
18241911
18251912def test_annotated_integration_with_annotated ():
18261913 UserID = Annotated [int , 'user_id' ]
1914+ UserAge = Annotated [int , 'user_age' ]
18271915
18281916 @inject
18291917 class TestClass :
1830- def __init__ (self , user_id : UserID ):
1918+ def __init__ (self , user_id : UserID , user_age : UserAge ):
18311919 self .user_id = user_id
1920+ self .user_age = user_age
18321921
18331922 def configure (binder ):
18341923 binder .bind (UserID , to = 123 )
1924+ binder .bind (UserAge , to = 32 )
18351925
18361926 injector = Injector ([configure ])
18371927
18381928 test_class = injector .get (TestClass )
18391929 assert test_class .user_id == 123
1930+ assert test_class .user_age == 32
1931+
1932+
1933+ def test_inject_annotation_with_annotated_type ():
1934+ UserID = Annotated [int , 'user_id' ]
1935+ UserAge = Annotated [int , 'user_age' ]
1936+
1937+ class TestClass :
1938+ def __init__ (self , user_id : Inject [UserID ], user_age : Inject [UserAge ]):
1939+ self .user_id = user_id
1940+ self .user_age = user_age
1941+
1942+ def configure (binder ):
1943+ binder .bind (UserID , to = 123 )
1944+ binder .bind (UserAge , to = 32 )
1945+ binder .bind (int , to = 456 )
1946+
1947+ injector = Injector ([configure ])
1948+
1949+ test_class = injector .get (TestClass )
1950+ assert test_class .user_id == 123
1951+ assert test_class .user_age == 32
1952+
1953+
1954+ def test_inject_annotation_with_nested_annotated_type ():
1955+ UserID = Annotated [int , 'user_id' ]
1956+ SpecialUserID = Annotated [UserID , 'special_user_id' ]
1957+
1958+ class TestClass :
1959+ def __init__ (self , user_id : Inject [SpecialUserID ]):
1960+ self .user_id = user_id
1961+
1962+ def configure (binder ):
1963+ binder .bind (SpecialUserID , to = 123 )
1964+
1965+ injector = Injector ([configure ])
1966+
1967+ test_class = injector .get (TestClass )
1968+ assert test_class .user_id == 123
1969+
1970+
1971+ def test_noinject_annotation_with_annotated_type ():
1972+ UserID = Annotated [int , 'user_id' ]
1973+
1974+ @inject
1975+ class TestClass :
1976+ def __init__ (self , user_id : NoInject [UserID ] = None ):
1977+ self .user_id = user_id
1978+
1979+ def configure (binder ):
1980+ binder .bind (UserID , to = 123 )
1981+
1982+ injector = Injector ([configure ])
1983+
1984+ test_class = injector .get (TestClass )
1985+ assert test_class .user_id is None
18401986
18411987
18421988def test_newtype_integration_with_annotated ():
@@ -1856,6 +2002,22 @@ def configure(binder):
18562002 assert test_class .user_id == 123
18572003
18582004
2005+ def test_newtype_with_injection_annotation ():
2006+ UserID = NewType ('UserID' , int )
2007+
2008+ class TestClass :
2009+ def __init__ (self , user_id : Inject [UserID ]):
2010+ self .user_id = user_id
2011+
2012+ def configure (binder ):
2013+ binder .bind (UserID , to = 123 )
2014+
2015+ injector = Injector ([configure ])
2016+
2017+ test_class = injector .get (TestClass )
2018+ assert test_class .user_id == 123
2019+
2020+
18592021def test_dataclass_annotated_parameter ():
18602022 Foo = Annotated [int , object ()]
18612023
0 commit comments