File: context.py

package info (click to toggle)
cadabra2 2.4.3.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 78,796 kB
  • sloc: ansic: 133,450; cpp: 92,064; python: 1,530; javascript: 203; sh: 184; xml: 182; objc: 53; makefile: 51
file content (55 lines) | stat: -rw-r--r-- 1,693 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from io import StringIO
import sys, os
import cadabra2

from cadabra2_jupyter import SITE_PATH

# super important
__cdbkernel__ = cadabra2.__cdbkernel__

#  setup stdout, stderr hook
class _StdCatch:
    def __init__(self, kernel):
        self._kernel = kernel

    def __enter__(self):
        sys.stdout = self.stdout = StringIO()
        sys.stderr = self.stderr = StringIO()

    def __exit__(self, exc_type, exc_val, exc_traceback):
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__

        for line in self.stdout.getvalue().splitlines():
            # insert missing newline
            self._kernel._send_code(line + "\n")

        # ignore exc_type reporting, since it always gives 'JSON serializable'
        # error, echoing the same message as provided by the __stderr__ catch
        for line in self.stderr.getvalue().splitlines():
            # insert missing newline
            self._kernel._send_error(line + "\n")


class SandboxContext:
    def __init__(self, kernel):
        self._sandbox = {
            "server": kernel._cdb_server,
            "__cdbkernel__": cadabra2.__cdbkernel__,
        }
        with open(os.path.join(SITE_PATH, "cadabra2_defaults.py")) as f:
            code = compile(f.read(), "cadabra2_defaults.py", "exec")
        exec(code, self._sandbox)

        self._kernel = kernel
        self._context = _StdCatch(kernel)

    def __call__(self, code):
        # redefine, as is catastrophic if accidentally overwritten
        self._sandbox["server"] = self._kernel._cdb_server
        with self._context:
            exec(code, self._sandbox)

    @property
    def namespace(self):
        return self._sandbox.keys()