@@ -399,6 +399,76 @@ def test_data(self, client):
399399 async_ = True ,
400400 )
401401
402+ # FINISHED with empty results triggers re-poll retry; data arrives on second poll
403+ finished_empty = type (
404+ "R" ,
405+ (),
406+ {
407+ "json" : lambda self : {
408+ "state" : "FINISHED" ,
409+ "results" : [],
410+ "errors" : [],
411+ "links" : [],
412+ },
413+ "status_code" : 200 ,
414+ },
415+ )()
416+ finished_with_data = type (
417+ "R" ,
418+ (),
419+ {
420+ "json" : lambda self : {
421+ "state" : "FINISHED" ,
422+ "results" : [
423+ {
424+ "columns" : [
425+ {
426+ "name" : "default_DOT_hard_hat_DOT_city" ,
427+ "type" : "str" ,
428+ "semantic_type" : "dimension" ,
429+ "semantic_entity" : "default.hard_hat.city" ,
430+ "semantic_name" : "default.hard_hat.city" ,
431+ "node" : "default.hard_hat" ,
432+ },
433+ {
434+ "name" : "default_DOT_avg_repair_price" ,
435+ "type" : "float" ,
436+ "semantic_type" : "metric" ,
437+ "semantic_name" : "default.avg_repair_price" ,
438+ "node" : "default.avg_repair_price" ,
439+ },
440+ ],
441+ "rows" : [["Foo" , 1.0 ], ["Bar" , 2.0 ]],
442+ },
443+ ],
444+ "errors" : [],
445+ "links" : [],
446+ },
447+ "status_code" : 200 ,
448+ },
449+ )()
450+ original_get = client ._session .get
451+ call_count = [0 ]
452+
453+ def mock_get (path , params = None , ** kwargs ):
454+ if "/data/" in str (path ):
455+ call_count [0 ] += 1
456+ if call_count [0 ] == 1 :
457+ return finished_empty
458+ return finished_with_data
459+ return original_get (path , params = params , ** kwargs )
460+
461+ client ._session .get = mock_get
462+ result = client .data (
463+ metrics = ["default.avg_repair_price" ],
464+ dimensions = ["default.hard_hat.city" ],
465+ )
466+ client ._session .get = original_get
467+ assert list (result .columns ) == [
468+ "default.hard_hat.city" ,
469+ "default.avg_repair_price" ,
470+ ]
471+
402472 # Error propagation
403473 # with pytest.raises(DJClientException) as exc_info:
404474 # client.data(
0 commit comments