@@ -282,3 +282,100 @@ def test_convert_to_long_pathname():
282282 from ipykernel .compiler import _convert_to_long_pathname
283283
284284 _convert_to_long_pathname (__file__ )
285+
286+
287+ def test_copy_to_globals (kernel_with_debug ):
288+ local_var_name = "var"
289+ global_var_name = "var_copy"
290+ code = f"""from IPython.core.display import HTML
291+ def my_test():
292+ { local_var_name } = HTML('<p>test content</p>')
293+ pass
294+ a = 2
295+ my_test()"""
296+
297+ # Init debugger and set breakpoint
298+ r = wait_for_debug_request (kernel_with_debug , "dumpCell" , {"code" : code })
299+ source = r ["body" ]["sourcePath" ]
300+
301+ wait_for_debug_request (
302+ kernel_with_debug ,
303+ "setBreakpoints" ,
304+ {
305+ "breakpoints" : [{"line" : 4 }],
306+ "source" : {"path" : source },
307+ "sourceModified" : False ,
308+ },
309+ )
310+
311+ wait_for_debug_request (kernel_with_debug , "debugInfo" )
312+
313+ wait_for_debug_request (kernel_with_debug , "configurationDone" )
314+
315+ # Execute code
316+ kernel_with_debug .execute (code )
317+
318+ # Wait for stop on breakpoint
319+ msg : dict = {"msg_type" : "" , "content" : {}}
320+ while msg .get ("msg_type" ) != "debug_event" or msg ["content" ].get ("event" ) != "stopped" :
321+ msg = kernel_with_debug .get_iopub_msg (timeout = TIMEOUT )
322+
323+ stacks = wait_for_debug_request (kernel_with_debug , "stackTrace" , {"threadId" : 1 })["body" ][
324+ "stackFrames"
325+ ]
326+
327+ # Get local frame id
328+ frame_id = stacks [0 ]["id" ]
329+
330+ # Copy the variable
331+ wait_for_debug_request (
332+ kernel_with_debug ,
333+ "copyToGlobals" ,
334+ {
335+ "srcVariableName" : local_var_name ,
336+ "dstVariableName" : global_var_name ,
337+ "srcFrameId" : frame_id ,
338+ },
339+ )
340+
341+ # Get the scopes
342+ scopes = wait_for_debug_request (kernel_with_debug , "scopes" , {"frameId" : frame_id })["body" ][
343+ "scopes"
344+ ]
345+
346+ # Get the local variable
347+ locals_ = wait_for_debug_request (
348+ kernel_with_debug ,
349+ "variables" ,
350+ {
351+ "variablesReference" : next (filter (lambda s : s ["name" ] == "Locals" , scopes ))[
352+ "variablesReference"
353+ ]
354+ },
355+ )["body" ]["variables" ]
356+
357+ local_var = None
358+ for variable in locals_ :
359+ if local_var_name in variable ["evaluateName" ]:
360+ local_var = variable
361+ assert local_var is not None
362+
363+ # Get the global variable (copy of the local variable)
364+ globals_ = wait_for_debug_request (
365+ kernel_with_debug ,
366+ "variables" ,
367+ {
368+ "variablesReference" : next (filter (lambda s : s ["name" ] == "Globals" , scopes ))[
369+ "variablesReference"
370+ ]
371+ },
372+ )["body" ]["variables" ]
373+
374+ global_var = None
375+ for variable in globals_ :
376+ if global_var_name in variable ["evaluateName" ]:
377+ global_var = variable
378+ assert global_var is not None
379+
380+ # Compare local and global variable
381+ assert global_var ["value" ] == local_var ["value" ] and global_var ["type" ] == local_var ["type" ]
0 commit comments