@@ -513,3 +513,66 @@ def f2():
513513
514514 assert aggregated () is False
515515 assert "return" not in inspect .get_annotations (aggregated )
516+
517+
518+ def test_concatenate_functions_invalid_return_type_raises () -> None :
519+ with pytest .raises (DagsError , match = "Invalid return type" ):
520+ concatenate_functions (
521+ functions = [_leisure , _consumption ],
522+ targets = ["_leisure" , "_consumption" ],
523+ return_type = "set" , # type: ignore[arg-type]
524+ )
525+
526+
527+ def test_get_ancestors_include_targets () -> None :
528+ calculated = get_ancestors (
529+ functions = [_utility , _unrelated , _leisure , _consumption ],
530+ targets = "_utility" ,
531+ include_targets = True ,
532+ )
533+ expected = {
534+ "_utility" ,
535+ "_consumption" ,
536+ "_leisure" ,
537+ "working_hours" ,
538+ "wage" ,
539+ "leisure_weight" ,
540+ }
541+ assert calculated == expected
542+
543+
544+ def test_concatenate_functions_non_string_targets () -> None :
545+ with pytest .raises (DagsError , match = "Targets must be strings" ):
546+ concatenate_functions (
547+ functions = {"f" : lambda : 1 },
548+ targets = [1 ], # type: ignore[list-item]
549+ )
550+
551+
552+ def test_aggregator_exception_in_get_annotations () -> None :
553+ """Test that an aggregator whose annotations cause an exception is handled."""
554+
555+ def f1 () -> int :
556+ return 1
557+
558+ def f2 () -> int :
559+ return 2
560+
561+ # Create an object that is callable but raises on get_annotations
562+ class BadAggregator :
563+ def __call__ (self , a : int , b : int ) -> int :
564+ return a + b
565+
566+ @property
567+ def __annotations__ (self ) -> dict [str , Any ]:
568+ msg = "bad annotations"
569+ raise TypeError (msg )
570+
571+ aggregator = BadAggregator ()
572+ result = concatenate_functions (
573+ functions = {"f1" : f1 , "f2" : f2 },
574+ targets = ["f1" , "f2" ],
575+ aggregator = aggregator ,
576+ set_annotations = True ,
577+ )
578+ assert result () == 3
0 commit comments