File: utils.py

package info (click to toggle)
jupyter-client 8.6.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,600 kB
  • sloc: python: 9,025; makefile: 168; sh: 33
file content (229 lines) | stat: -rw-r--r-- 6,677 bytes parent folder | download
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""Testing utils for jupyter_client tests

"""
import json
import os
import sys
from typing import Dict

import pytest

from jupyter_client import (
    AsyncKernelManager,
    AsyncMultiKernelManager,
    KernelManager,
    MultiKernelManager,
)

pjoin = os.path.join

skip_win32 = pytest.mark.skipif(sys.platform.startswith("win"), reason="Windows")


sample_kernel_json = {
    "argv": ["cat", "{connection_file}"],
    "display_name": "Test kernel",
}


def install_kernel(kernels_dir, argv=None, name="test", display_name=None):
    """install a kernel in a kernels directory"""
    kernel_dir = pjoin(kernels_dir, name)
    os.makedirs(kernel_dir)
    kernel_json = {
        "argv": argv or sample_kernel_json["argv"],
        "display_name": display_name or sample_kernel_json["display_name"],
    }
    json_file = pjoin(kernel_dir, "kernel.json")
    with open(json_file, "w") as f:
        json.dump(kernel_json, f)
    return kernel_dir


class RecordCallMixin:
    method_calls: Dict[str, int]

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.method_calls = {}

    def record(self, method_name: str) -> None:
        if method_name not in self.method_calls:
            self.method_calls[method_name] = 0
        self.method_calls[method_name] += 1

    def call_count(self, method_name: str) -> int:
        if method_name not in self.method_calls:
            self.method_calls[method_name] = 0
        return self.method_calls[method_name]

    def reset_counts(self) -> None:
        for record in self.method_calls:
            self.method_calls[record] = 0


def subclass_recorder(f):
    def wrapped(self, *args, **kwargs):
        # record this call
        self.record(f.__name__)
        method = getattr(self._superclass, f.__name__)
        # call the superclass method
        r = method(self, *args, **kwargs)
        # call anything defined in the actual class method
        f(self, *args, **kwargs)
        return r

    return wrapped


class KMSubclass(RecordCallMixin):
    @subclass_recorder
    def start_kernel(self, **kw):
        """Record call and defer to superclass"""

    @subclass_recorder
    def shutdown_kernel(self, now=False, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_shutdown_kernel(self, now=False, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def restart_kernel(self, now=False, **kw):
        """Record call and defer to superclass"""

    @subclass_recorder
    def interrupt_kernel(self):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_interrupt_kernel(self):
        """Record call and defer to superclass"""

    @subclass_recorder
    def request_shutdown(self, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def finish_shutdown(self, waittime=None, pollinterval=0.1, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_launch_kernel(self, kernel_cmd, **kw):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_kill_kernel(self):
        """Record call and defer to superclass"""

    @subclass_recorder
    def cleanup_resources(self, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_cleanup_resources(self, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def signal_kernel(self, signum):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_signal_kernel(self, signum):
        """Record call and defer to superclass"""

    @subclass_recorder
    def is_alive(self):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_is_alive(self):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_send_kernel_sigterm(self, restart=False):
        """Record call and defer to superclass"""


class SyncKMSubclass(KMSubclass, KernelManager):
    """Used to test subclass hierarchies to ensure methods are called when expected."""

    _superclass = KernelManager


class AsyncKMSubclass(KMSubclass, AsyncKernelManager):
    """Used to test subclass hierarchies to ensure methods are called when expected."""

    _superclass = AsyncKernelManager


class MKMSubclass(RecordCallMixin):
    def _kernel_manager_class_default(self):
        return "tests.utils.SyncKMSubclass"

    @subclass_recorder
    def get_kernel(self, kernel_id):
        """Record call and defer to superclass"""

    @subclass_recorder
    def remove_kernel(self, kernel_id):
        """Record call and defer to superclass"""

    @subclass_recorder
    def start_kernel(self, *, kernel_name=None, **kwargs):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_start_kernel(self, *, kernel_name=None, **kwargs):
        """Record call and defer to superclass"""

    @subclass_recorder
    def shutdown_kernel(self, kernel_id, now=False, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def restart_kernel(self, kernel_id, now=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def interrupt_kernel(self, kernel_id):
        """Record call and defer to superclass"""

    @subclass_recorder
    def request_shutdown(self, kernel_id, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_request_shutdown(self, kernel_id, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def finish_shutdown(self, kernel_id, waittime=None, pollinterval=0.1, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def _async_finish_shutdown(self, kernel_id, waittime=None, pollinterval=0.1, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def cleanup_resources(self, kernel_id, restart=False):
        """Record call and defer to superclass"""

    @subclass_recorder
    def shutdown_all(self, now=False):
        """Record call and defer to superclass"""


class SyncMKMSubclass(MKMSubclass, MultiKernelManager):
    _superclass = MultiKernelManager

    def _kernel_manager_class_default(self):
        return "tests.utils.SyncKMSubclass"


class AsyncMKMSubclass(MKMSubclass, AsyncMultiKernelManager):
    _superclass = AsyncMultiKernelManager

    def _kernel_manager_class_default(self):
        return "tests.utils.AsyncKMSubclass"