0

I'm writing a script that will modify the code in the script and rerun it automatically but whichever way I do it, it always goes into repeated output until the kernel restarts and if I keyboard interrupt sometimes I get: ParserError: Error tokenizing data. C error: Calling read(nbytes) on source failed. Try engine='python'. And usually this is a Pandas error, but there's no Pandas. Ideally, I would like to accomplish this without using shell and also be able to set a breakpoint so instead of accessing the current file I can just access everything written up until that point. This is every way I've tried it. I think maybe if there was a way to do introspection from a context manager (like if there is a way to access an object from yield) that would be great to know.


    current_file = clear_me()
    code_to_be = "".join(rf"{e}" for e in current_file)
    #str(clear_me()).strip('[]')
    import parser
    xyyx = parser.suite(code_to_be)
    exec(xyyx.compile())
    
    import os
    
    # path_to_script = os.path.dirname(os.path.abspath(__file__))
    # my_filename = os.path.join(path_to_script, "my_file.py")
    
    # with open(my_filename, "w") as handle:
    #     print(code_to_be, file=handle)
    
    #exec(compile(code_to_be, "<string>", "exec"))
    
    import subprocess
    #subprocess.run(["python", f"{__file__}"])
    #exec(open("my_file.py").read())

def clear_me():
    f = open(rf"{__file__}", 'r')
    takethel = f.readlines()
    return takethel
  • (1) What is `dello`? (2) Do you run this in a Jupyter notebook? – Michael Butscher Jun 22 '23 at 11:51
  • Oh sorry, I meant to change the var names from nonsense. So dello = code_to_be. It's from file.read_lines() converted back into a string. And no, I'm using Spyder IDE. – Literalomicus Jun 22 '23 at 12:06
  • 1
    Assuming that both code snippets are actually in one file, the code loads and executes itself which loads and executes itself which... and so on until stack or memory overflow. – Michael Butscher Jun 22 '23 at 12:16
  • Yeah I haven't tried using file.close with a context manager because it would just reopen and close still. When I wrote it, I was hoping it would just write/read itself once and exit. I would rather not access the file itself, I think the solution has something to do with AST but I still don't know how I would get something to work like a breakpoint (read all the code up until a certain point) -- well, without altering the code before it because I know I could just wrap everything as a string and then compile but that's not what I want. – Literalomicus Jun 22 '23 at 12:26
  • 1
    `exec` allows to specify a global dictionary. You can add a variable in it so that the code can check for the existence of the variable to know if code is executed inside the `exec` call or regularly outside of `exec` and react accordingly. – Michael Butscher Jun 22 '23 at 12:53

1 Answers1

0

This is a tentative solution based on Michael Butscher's suggestions. It works to prevent the stack overflow, which was the point of the question. But I don't yet if I'll be able to rewrite the script how I wanted yet. And for extra detail, using the suite object's compile method as the object argument for exec gave me TypeError: <module 'builtins' (built-in)> is a built-in module. That's why I changed it.


    current_file = clear_me()
    global_env = {"fun": True}
    local_env = {}
    code_to_be = str(clear_me()).strip('[]')
    this_script = compile(code_to_be, "<string>", "exec")
    try:
        globals()["fun"]
    except KeyError:
        exec(this_script, global_env, local_env)