Example #1
0
def c(code):
    """Execute inline C code respecting scoping rules.

    Parameters
    ----------
    code : str
        C source code to execute.
    """
    frame = sys._getframe().f_back
    entry = frame.f_code, frame.f_lineno
    cache = c._cache
    locals_ = frame.f_locals
    ns = ChainMap(
        locals_,
        {k: v for k, v in frame.f_globals.items() if _notdunder(k)},
    )

    try:
        f = cache[entry]
    except KeyError:
        f = cache[entry] = _make_c_func(code, frame)

    local_keys = locals_.keys()
    locals_.update({k: v for k, v in f(**dict(ns)).items() if k in local_keys})
    pythonapi.PyFrame_LocalsToFast(py_object(frame), c_int(1))
Example #2
0
 def _bind_to_calling_scope(self):
     '''
     Inject the result of a successful match into the calling scope.
     This only works inside of a decorated function; use dict style
     lookup syntax for use in a context manager.
     NOTE: This uses some not-so-nice abuse of stack frames and the
           ctypes API to make this work and as such it will probably
           not run under anything other than cPython.
     '''
     # Grab the stack frame that the caller's code is running in
     frame = _getframe(2)
     # Dump the matched variables and their values into the frame
     frame.f_locals.update(self.map)
     # Force an update of the frame locals from the locals dict
     pythonapi.PyFrame_LocalsToFast(py_object(frame), c_int(0))
Example #3
0
    def true_exec(code, scope):
        """exec() a codeblock in given scope. Used by seapi repl

        scope 0 equals executing in context of caller of true_exec().
        scope 1 equals executing in context of the caller for the caller
        of true_exec().
        """
        parent = sys._getframe(scope + 1)  # +1 escapes true_exec itself
        parent_globals = parent.f_globals
        parent_locals = parent.f_locals
        try:
            exec(code, parent_globals, parent_locals)
        except KeyboardInterrupt:  # emulate ctrl+c if code='input()'
            print("\nKeyboardInterrupt")
        except Exception:  # catch arbitary exceptions from exec
            traceback.print_exc()
        # beware traveller. here lies dark spell of the olden times !
        # the following call forces update to locals()
        # adding new variables is allowed but calling them requires
        # some indirection like using exec() or a placeholder
        # otherwise you will get nameError when calling the variable
        # the magic value 1 stands for ability to introduce new
        # variables. 0 for update-only
        pythonapi.PyFrame_LocalsToFast(py_object(parent), c_int(1))
Example #4
0
def _replace_local_var(source, rel, new):
    source.f_locals[rel] = new
    api.PyFrame_LocalsToFast(ctypes.py_object(source), ctypes.c_int(0))
Example #5
0
 def locals_to_fast(frame, clear: int = 0, **_):  # pylint: disable=missing-function-docstring
     pythonapi.PyFrame_LocalsToFast(py_object(frame), c_int(clear))