@@ -384,7 +384,7 @@ impl ScopeContext {
384384 let stripped_owned = stripped. to_path_buf ( ) ;
385385 let better = match & best_match {
386386 Some ( ( _, current) ) => {
387- stripped_owned. components ( ) . count ( ) >= current. components ( ) . count ( )
387+ stripped_owned. components ( ) . count ( ) < current. components ( ) . count ( )
388388 }
389389 None => true ,
390390 } ;
@@ -622,6 +622,54 @@ mod tests {
622622 } )
623623 }
624624
625+ #[ test]
626+ fn project_filter_beats_builtin_source_selection ( ) -> RecorderResult < ( ) > {
627+ const BUILTIN_LABEL : & str = "builtin-default" ;
628+ const BUILTIN_FILTER : & str =
629+ include_str ! ( "../../resources/trace_filters/builtin_default.toml" ) ;
630+
631+ let project = tempdir ( ) . expect ( "project" ) ;
632+ let filters_dir = project. path ( ) . join ( ".codetracer" ) ;
633+ fs:: create_dir_all ( & filters_dir) . unwrap ( ) ;
634+ let filter_path = filters_dir. join ( "trace-filter.toml" ) ;
635+ write_filter (
636+ & filter_path,
637+ r#"
638+ [scope]
639+ default_exec = "skip"
640+ default_value_action = "allow"
641+
642+ [[scope.rules]]
643+ selector = "pkg:my_app.sec"
644+ exec = "trace"
645+ "# ,
646+ ) ;
647+
648+ let code_path = project. path ( ) . join ( "my_app" ) . join ( "sec.py" ) ;
649+ fs:: create_dir_all ( code_path. parent ( ) . unwrap ( ) ) . unwrap ( ) ;
650+ fs:: File :: create ( & code_path) . unwrap ( ) ;
651+ let code_path = code_path. to_string_lossy ( ) . to_string ( ) ;
652+
653+ let config = TraceFilterConfig :: from_inline_and_paths (
654+ & [ ( BUILTIN_LABEL , BUILTIN_FILTER ) ] ,
655+ & [ filter_path. clone ( ) ] ,
656+ ) ?;
657+
658+ Python :: with_gil ( |py| -> RecorderResult < ( ) > {
659+ let module = load_module ( py, "my_app.sec" , & code_path, "def sec():\n return 1\n " ) ?;
660+ let code_obj = get_code ( & module, "sec" ) ?;
661+ let wrapper = CodeObjectWrapper :: new ( py, & code_obj) ;
662+
663+ let engine = TraceFilterEngine :: new ( config. clone ( ) ) ;
664+ let resolution = engine. resolve ( py, & wrapper) ?;
665+
666+ assert_eq ! ( resolution. exec( ) , ExecDecision :: Trace ) ;
667+ assert_eq ! ( resolution. module_name( ) , Some ( "my_app.sec" ) ) ;
668+ assert_eq ! ( resolution. relative_path( ) , Some ( "my_app/sec.py" ) ) ;
669+ Ok ( ( ) )
670+ } )
671+ }
672+
625673 #[ test]
626674 fn caches_resolution_and_applies_value_patterns ( ) -> RecorderResult < ( ) > {
627675 let ( config, file_path) = filter_with_pkg_rule (
0 commit comments