@@ -496,3 +496,33 @@ def test_bool_modulo_declines_like_pandas():
496496 # bool + int still computes in parity (not over-declined)
497497 got = g .gfql ("MATCH (n) RETURN n.flag + 2 AS r" , engine = "polars" )._nodes ["r" ].to_list ()
498498 assert got == [3 , 2 , 3 ]
499+
500+
501+ class TestAutoEngineRoutesPolarsNative :
502+ """engine=auto on polars-frame graphs must run the native polars path (frames in = frames
503+ out), not the silent pandas bridge (~13x on point queries); polars-NIE shapes still answer
504+ via the legacy AUTO fallback since the user did not pin an engine."""
505+
506+ def _graph (self ):
507+ nodes = pl .DataFrame ({"id" : [0 , 1 , 2 , 3 ], "label__Person" : [True ] * 4 })
508+ edges = pl .DataFrame ({"s" : [0 , 1 , 2 ], "d" : [1 , 2 , 3 ], "type" : ["KNOWS" ] * 3 })
509+ return graphistry .nodes (nodes , "id" ).edges (edges , "s" , "d" )
510+
511+ def test_auto_returns_polars_frames_and_matches_explicit (self ):
512+ g = self ._graph ()
513+ q = "MATCH (a:Person {id: 0})-[:KNOWS]->(b) RETURN b.id AS bid ORDER BY bid"
514+ r_auto = g .gfql (q )._nodes
515+ r_expl = g .gfql (q , engine = "polars" )._nodes
516+ assert "polars" in type (r_auto ).__module__ , "auto must not bridge polars graphs to pandas"
517+ from polars .testing import assert_frame_equal
518+ assert_frame_equal (r_auto , r_expl )
519+
520+ def test_auto_falls_back_on_polars_nie (self ):
521+ g = self ._graph ()
522+ q = ("MATCH p = shortestPath((a:Person {id: 0})-[:KNOWS*]-(b:Person {id: 3})) "
523+ "RETURN length(p) AS l" )
524+ with pytest .raises (NotImplementedError ):
525+ g .gfql (q , engine = "polars" ) # pinned engine: honest NIE
526+ out = g .gfql (q )._nodes # auto: answers via fallback
527+ rows = out .to_dict ("records" ) if hasattr (out , "to_dict" ) else out .to_pandas ().to_dict ("records" )
528+ assert rows == [{"l" : 3 }]
0 commit comments