MCPcopy Index your code
hub / github.com/ipython/ipython / _exec_in_closure

Method _exec_in_closure

IPython/core/debugger_backport.py:69–154  ·  view source on GitHub ↗

Run source code in closure so code object created within source can find variables in locals correctly returns True if the source is executed, False otherwise

(self, source, globals, locals)

Source from the content-addressed store, hash-verified

67
68class PdbClosureBackport:
69 def _exec_in_closure(self, source, globals, locals): # type: ignore[no-untyped-def]
70 """Run source code in closure so code object created within source
71 can find variables in locals correctly
72 returns True if the source is executed, False otherwise
73 """
74
75 # Determine if the source should be executed in closure. Only when the
76 # source compiled to multiple code objects, we should use this feature.
77 # Otherwise, we can just raise an exception and normal exec will be used.
78
79 code = compile(source, "<string>", "exec")
80 if not any(isinstance(const, CodeType) for const in code.co_consts):
81 return False
82
83 # locals could be a proxy which does not support pop
84 # copy it first to avoid modifying the original locals
85 locals_copy = dict(locals)
86
87 locals_copy["__pdb_eval__"] = {"result": None, "write_back": {}}
88
89 # If the source is an expression, we need to print its value
90 try:
91 compile(source, "<string>", "eval")
92 except SyntaxError:
93 pass
94 else:
95 source = "__pdb_eval__['result'] = " + source
96
97 # Add write-back to update the locals
98 source = (
99 "try:\n"
100 + textwrap.indent(source, " ")
101 + "\n"
102 + "finally:\n"
103 + " __pdb_eval__['write_back'] = locals()"
104 )
105
106 # Build a closure source code with freevars from locals like:
107 # def __pdb_outer():
108 # var = None
109 # def __pdb_scope(): # This is the code object we want to execute
110 # nonlocal var
111 # <source>
112 # return __pdb_scope.__code__
113 source_with_closure = (
114 "def __pdb_outer():\n"
115 + "\n".join(f" {var} = None" for var in locals_copy)
116 + "\n"
117 + " def __pdb_scope():\n"
118 + "\n".join(f" nonlocal {var}" for var in locals_copy)
119 + "\n"
120 + textwrap.indent(source, " ")
121 + "\n"
122 + " return __pdb_scope.__code__"
123 )
124
125 # Get the code object of __pdb_scope()
126 # The exec fills locals_copy with the __pdb_outer() function and we can call

Callers 1

defaultMethod · 0.95

Calls 4

indentMethod · 0.80
getMethod · 0.80
popMethod · 0.80
updateMethod · 0.45

Tested by

no test coverage detected