@@ -236,8 +236,42 @@ async def test_update_rows_and_annotations(
236236 entityview = entityview .store (synapse_client = self .syn )
237237 self .schedule_for_cleanup (entityview .id )
238238
239- # SPY on the CSV conversion function to verify different input paths
240- spy_csv_file_conversion = mocker .spy (table_module , "csv_to_pandas_df" )
239+ # Custom wrapper to capture call stack
240+ original_csv_to_pandas_df = table_module .csv_to_pandas_df
241+ call_info = []
242+
243+ def csv_wrapper (* args , ** kwargs ):
244+ import traceback
245+
246+ stack = traceback .extract_stack ()
247+
248+ # Find the calling function (skip the wrapper itself)
249+ calling_function = None
250+ for frame in reversed (stack [:- 1 ]): # Skip current frame
251+ if "_upsert_rows_async" in frame .name :
252+ calling_function = "_upsert_rows_async"
253+ break
254+ elif "query_async" in frame .name :
255+ calling_function = "query_async"
256+ break
257+ else :
258+ pass
259+
260+ call_info .append (
261+ {
262+ "caller" : calling_function ,
263+ "args" : args ,
264+ "kwargs" : kwargs ,
265+ "filepath" : kwargs .get ("filepath" , args [0 ] if args else None ),
266+ }
267+ )
268+
269+ return original_csv_to_pandas_df (* args , ** kwargs )
270+
271+ # Patch the csv_to_pandas_df function to use the wrapper
272+ mock_csv_to_pandas_df = mocker .patch .object (
273+ table_module , "csv_to_pandas_df" , side_effect = csv_wrapper
274+ )
241275
242276 # Create test data for all files
243277 test_data = {
@@ -257,7 +291,7 @@ async def test_update_rows_and_annotations(
257291
258292 for method in update_methods :
259293 # Reset the spy for each method
260- spy_csv_file_conversion . reset_mock ()
294+ call_info . clear ()
261295
262296 # WHEN I update rows using different input types
263297 if method == "csv" :
@@ -276,7 +310,10 @@ async def test_update_rows_and_annotations(
276310 )
277311
278312 # THEN the CSV conversion function should be called
279- spy_csv_file_conversion .assert_called_once ()
313+ _upsert_rows_async_calls = [
314+ call for call in call_info if call ["caller" ] == "_upsert_rows_async"
315+ ]
316+ assert len (_upsert_rows_async_calls ) == 1
280317
281318 elif method == "dataframe" :
282319 # Use DataFrame
@@ -288,7 +325,10 @@ async def test_update_rows_and_annotations(
288325 )
289326
290327 # THEN the CSV conversion function should NOT be called
291- spy_csv_file_conversion .assert_not_called ()
328+ _upsert_rows_async_calls = [
329+ call for call in call_info if call ["caller" ] == "_upsert_rows_async"
330+ ]
331+ assert len (_upsert_rows_async_calls ) == 0
292332
293333 else : # dict
294334 # Use dictionary
@@ -300,7 +340,10 @@ async def test_update_rows_and_annotations(
300340 )
301341
302342 # THEN the CSV conversion function should NOT be called
303- spy_csv_file_conversion .assert_not_called ()
343+ _upsert_rows_async_calls = [
344+ call for call in call_info if call ["caller" ] == "_upsert_rows_async"
345+ ]
346+ assert len (_upsert_rows_async_calls ) == 0
304347
305348 # THEN the columns should exist in the entity view
306349 assert "column_string" in entityview .columns
0 commit comments