How do i get a dictionary of all variables defined in the scope of a function?

68 Views Asked by At

So i want to get every variable from a function as a dictionary. Like this:

from typing import Any

def myfunc():
  var1 = 10
  var2 = 20
  var3 = 30
  var4 = '40'
  var5 = False

x: dict[str, Any] = myfunc.vars
hardtyped_x = { # What i want x to be. Not including parameters
  'var1': 10,
  'var2': 20,
  'var3': 30,
  'var4': '40',
  'var5': False
}

I tried asking tabnine and got something along the lines of:

import inspect

def myfunc():
  var1 = 10
  var2 = 20
  var3 = 30
  var4 = '40'
  var5 = False

x = inspect.currentframe().f_back.f_locals

but this either raises an error (as currentframe() can return None and this raises an error) or i get a long list of dunder methods and other things of the sort

1

There are 1 best solutions below

3
Samuel Svendsen On

i figured out a psuedo way to do it:

from types import FunctionType
import inspect

def getFunctionDefinedVariables(function: FunctionType) -> dict:
    with open("TEMPORARYFILE.py", "w") as f:
        codeblock = inspect.getsource(function)
        codeblock = remove_indents_and_top_line
        f.write(codeblock)
        imported_temp_file = __import__("TEMPORARYFILE.py")
        return {key: val for key, val in imported_temp_file.__dict__.items() if not (key.startswith('__') and key.endswith('__'))}

Will update once im done making the full function

Edit: JK found a different way to do what i wanted

Edit2: JK again i made it anyway for a different project

import inspect
import os

from types import FunctionType
from typing import Any
from textwrap import dedent
from importlib import import_module as imp
from importlib import invalidate_caches as inv
from time import sleep

def getFunctionDefinedVariables(function: FunctionType) -> dict[str, Any]:
    with open("TEMPORARYFILE.py", "w") as f:
        sleep(10.0)
        f.write("\n".join([dedent(string) for string in inspect.getsource(function).split("\n")[1:]]))
    inv()
    try:
        import TEMPORARYFILE as imported_temp_file
    except ImportError:
        raise ImportError("Error making temp.")
    items = imported_temp_file.__dict__.items()
    os.remove("TEMPORARYFILE.py")
    return {key: val for key, val in items if not (key.startswith('__') and key.endswith('__'))}
        
    
def test():
    x = None
    y = 1
    z = "2"

if __name__ == "__main__":
    for key, val in getFunctionDefinedVariables(test).items():
        print(f"{key}: {val}")