1import os
2
3from thonny.plugins.cpython.cpython_backend import (
4    get_backend,
5    Executor,
6    return_execution_result,
7    prepare_hooks,
8)
9
10
11def _cmd_Birdseye(cmd):
12    backend = get_backend()
13    backend.switch_env_to_script_mode(cmd)
14    return backend._execute_file(cmd, BirdsEyeRunner)
15
16
17class BirdsEyeRunner(Executor):
18    @return_execution_result
19    @prepare_hooks
20    def execute_source(self, source, filename, mode, ast_postprocessors):
21        import webbrowser
22
23        assert mode == "exec"
24        # ignore ast_postprocessors, because birdseye requires source
25
26        if isinstance(source, bytes):
27            source = source.decode("utf-8")
28
29        import __main__  # @UnresolvedImport
30
31        global_vars = __main__.__dict__
32
33        # Following is a trick, which allows importing birdseye in the backends,
34        # which doesn't have it installed (provided it is installed for frontend Python)
35        from birdseye.bird import eye
36
37        eye.exec_string(source, filename, globs=global_vars, locs=global_vars, deep=True)
38        port = os.environ.get("BIRDSEYE_PORT", "7777")
39        webbrowser.open_new_tab("http://localhost:%s/ipython_call/" % port + eye._last_call_id)
40
41
42def load_plugin():
43    try:
44        os.environ["OUTDATED_IGNORE"] = "1"
45        # TODO: it would be good to do this here, but it's slow
46        # import birdseye.bird  # need to import at plugin load time, because later it may not be in path
47    except ImportError:
48        pass
49    get_backend().add_command("Birdseye", _cmd_Birdseye)
50