Is it possible to get locals() and globals() from an upper stack frame?

Luis Masuelli

If I eval something in Python:

eval("a + b")

This will evaluate the expression using the current scope (both locals and globals).

What I am developing requires that an expression be evaluated "later". Such word implies that I want to keep the current scope (i.e. locals() and globals()). But I want to pass such values... transparently, or fetch them from an upper stack frame. Consider this implementation (actually, this one exists):

def __eval(self, expr):
    if isinstance(expr, (list, tuple, set, frozenset, dict, Expression)):
        return Expression.eval(expr, self)
    elif callable(expr):
        try:
            return expr(self)
        except (AttributeError, IndexError, KeyError, TypeError):
            return UNDEFINED
    else:
        try:
            return eval(expr, {}, {'self': self})
        except (AttributeError, IndexError, KeyError, TypeError):
            return UNDEFINED

This implementation is explained as follows:

  • If I use an expression object (I actually developed such object), then I evaluate such expression using the current object (after all, this function is a method). This part needs not help, it is fully developed.
  • If I use a callable, I execute the callable (e.g. a lambda expression).
  • If I use a string, that will be a python expression, and I want such evaluation be performed using the call-time locals() and globals().

I know I could explicitly call:

o._O__eval("self.a + self.b", globals(), locals())
#THIS WOULD REQUIRE to alter the method to allow two additional dict parameters
#NO, I will not call this function directly, but lets follow the example

But I'd like to get such globals() and locals without the user passing it explicitly and make use of such values in the eval.

Question: Is it possible to get the locals() and globals() from an upper stack frame?

Martijn Pieters

You should really consider just passing in globals() and locals():

def __eval(self, expr, eval_globals=None, eval_locals=None):
    if eval_globals is None:
        eval_globals = globals()
    if eval_locals is None:
        eval_locals = eval_globals()

If that is not an option for you, you can access the parent frame with the sys._getframe() function, and the locals and globals are attributes on that frame:

def __eval(self, expr, eval_globals=None, eval_locals=None):
    call_frame = sys._getframe(1)
    eval_globals, eval_locals = call_frame.f_globals, call_frame.f_locals

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

locals() and globals() in stack trace on exception (Python)

Is it possible to extract locals and their values from a stack trace in Ruby?

Globals and Locals

Access the locals available in the previous stack frame

locals() vs globals() in function

ASM Get exact value from stack frame

scope of globals, locals, use with exec()

How to get the globals from a module namespace?

Get an R Shiny Server from .globals

Get globals() dict from other module

Get locals from calling namespace in Python

Lua: Get Locals Outside of Function From A Function

Getting a variable from the caller's globals. What is a frame object?

eval globals and locals argument do not work as expected

about pandasql locals() and globals() method issue

What's the difference between globals(), locals(), and vars()?

How to execute a callable in a given context (locals and globals)?

difference between locals() and globals() and dir() in python

Python3 globals() and locals() contents

python quits unexpectedly when using locals() or globals()

Destruction order between globals and static function locals

How can I force update the Python locals() dictionary of a different stack frame?

Is it possible to access exec-provided globals dictionary from within a function?

gdb: info locals on a selected frame

Get upper triangular matrix from nonsymmetric matrix

globals(), locals(), vars() do not work as expected in a function of python

Using a list comprehension to look up variables works with globals() but not locals(). Why?

Is there are any way make locals() and globals() defaultdict-like

C++ - Different concurrent behavious when using locals and globals