kalong 0.5.0__py3-none-any.whl → 0.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kalong/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """A new take on debugging"""
2
2
 
3
- __version__ = "0.5.0"
3
+ __version__ = "0.5.2"
4
4
  import os
5
5
  import sys
6
6
  from pathlib import Path
kalong/communication.py CHANGED
@@ -32,17 +32,15 @@ basicConfig(level=config.log_level)
32
32
 
33
33
 
34
34
  def exception_handler(loop, context):
35
- exception = context["exception"]
36
- message = context["message"]
37
- logging.error(f"Task failed, msg={message}, exception={exception}")
35
+ logging.error(f"Loop exit: {context}")
38
36
 
39
37
 
40
- def communicate(frame, event, arg):
38
+ def communicate(frame, event, arg, pending=None):
41
39
  loop = get_loop()
42
40
 
43
41
  loop.set_exception_handler(exception_handler)
44
42
  try:
45
- loop.run_until_complete(communication_loop(frame, event, arg))
43
+ loop.run_until_complete(communication_loop(frame, event, arg, pending))
46
44
  except asyncio.CancelledError:
47
45
  log.info("Loop got cancelled")
48
46
  die()
@@ -62,6 +60,7 @@ async def init(ws, frame, event, arg):
62
60
 
63
61
 
64
62
  async def handle_message(ws, data, frame, event, arg):
63
+ tb = arg[2] if event == "exception" else None
65
64
  if data["type"] == "HELLO":
66
65
  await init(ws, frame, event, arg)
67
66
  response = {
@@ -83,6 +82,7 @@ async def handle_message(ws, data, frame, event, arg):
83
82
 
84
83
  elif data["type"] == "SET_PROMPT" or data["type"] == "REFRESH_PROMPT":
85
84
  try:
85
+ step_frame = get_frame(frame, data.get("frame"), tb)
86
86
  eval_fun = (
87
87
  serialize_inspect_eval
88
88
  if data.get("command") == "inspect"
@@ -94,16 +94,27 @@ async def handle_message(ws, data, frame, event, arg):
94
94
  if data.get("command") == "recursive_debug"
95
95
  else serialize_answer
96
96
  )
97
- response = {
98
- "type": "SET_ANSWER",
99
- "key": data["key"],
100
- "command": data.get("command"),
101
- "frame": data.get("frame"),
102
- **eval_fun(
103
- data["prompt"],
104
- get_frame(frame, data.get("frame")),
105
- ),
106
- }
97
+
98
+ def get_response():
99
+ return {
100
+ "type": "SET_ANSWER",
101
+ "key": data["key"],
102
+ "command": data.get("command"),
103
+ "frame": data.get("frame"),
104
+ **eval_fun(data["prompt"], step_frame),
105
+ }
106
+
107
+ if data.get("command") == "condition":
108
+ add_step("continue", step_frame, condition=get_response)
109
+ response = {
110
+ "type": "DO_COMMAND",
111
+ "command": "continue",
112
+ "frame": data.get("frame"),
113
+ "stop": True,
114
+ }
115
+ else:
116
+ response = get_response()
117
+
107
118
  except SetFrameError as e:
108
119
  frame = e.frame
109
120
  event = e.event
@@ -137,7 +148,7 @@ async def handle_message(ws, data, frame, event, arg):
137
148
  data["from"],
138
149
  data["to"],
139
150
  data["cursor"],
140
- get_frame(frame, data.get("frame")),
151
+ get_frame(frame, data.get("frame"), tb),
141
152
  ),
142
153
  }
143
154
 
@@ -152,7 +163,7 @@ async def handle_message(ws, data, frame, event, arg):
152
163
  stop_trace(frame)
153
164
  die()
154
165
  else:
155
- step_frame = get_frame(frame, data.get("frame"))
166
+ step_frame = get_frame(frame, data.get("frame"), tb)
156
167
  add_step(command, step_frame)
157
168
  response["stop"] = True
158
169
 
@@ -161,7 +172,7 @@ async def handle_message(ws, data, frame, event, arg):
161
172
  return response
162
173
 
163
174
 
164
- async def communication_loop(frame_, event_, arg_):
175
+ async def communication_loop(frame_, event_, arg_, pending=None):
165
176
  frame = frame_
166
177
  event = event_
167
178
  arg = arg_
@@ -177,6 +188,9 @@ async def communication_loop(frame_, event_, arg_):
177
188
  if existing:
178
189
  # If the socket is already opened we need to update client state
179
190
  await init(ws, frame, event, arg)
191
+ if pending:
192
+ # Start by sending pending message
193
+ await ws.send_json(pending)
180
194
  # Otherwise if it's new, just wait for HELLO to answer current state
181
195
 
182
196
  stop = False
@@ -189,7 +203,7 @@ async def communication_loop(frame_, event_, arg_):
189
203
  log.error(f"Error handling message {data}", exc_info=e)
190
204
  response = {
191
205
  "type": "SET_ANSWER",
192
- "prompt": data["prompt"].strip(),
206
+ "prompt": data.get("prompt", "?").strip(),
193
207
  "key": data["key"],
194
208
  "command": data.get("command"),
195
209
  "frame": data.get("frame"),
kalong/config.py CHANGED
@@ -90,6 +90,9 @@ class Config:
90
90
  if value:
91
91
  setattr(self, name, type(name)(value))
92
92
 
93
+ if os.getenv("KALONG_PORT") and not os.getenv("KALONG_FRONT_PORT"):
94
+ self.front_port = self.port
95
+
93
96
  def get_args_for_server(self):
94
97
  yield "--server"
95
98
 
kalong/debugger.py CHANGED
@@ -24,7 +24,7 @@ from jedi import Interpreter
24
24
  from .errors import SetFrameError
25
25
  from .utils import cutter_mock, dedent, discompile, universal_travel
26
26
  from .utils.io import capture_display, capture_exception, capture_std
27
- from .utils.iterators import force_iterable, iter_cause, iter_frame, iter_stack
27
+ from .utils.iterators import force_iterable, iter_cause, iter_stack
28
28
  from .utils.obj import (
29
29
  get_code,
30
30
  get_infos,
@@ -59,11 +59,11 @@ def get_title(frame, event, arg):
59
59
  return "???"
60
60
 
61
61
 
62
- def get_frame(frame, key):
62
+ def get_frame(frame, key, tb=None):
63
63
  if not key:
64
64
  return frame
65
65
 
66
- for f in iter_frame(frame):
66
+ for f, _lno in iter_stack(frame, tb):
67
67
  if id(f) == key:
68
68
  return f
69
69
  log.warning(f"Frame {key} not found")
kalong/server.py CHANGED
@@ -109,6 +109,10 @@ async def websocket(request):
109
109
  return ws
110
110
 
111
111
 
112
+ def exception_handler(loop, context):
113
+ logging.error(f"Loop exit: {context}")
114
+
115
+
112
116
  def serve():
113
117
  app = web.Application()
114
118
  app["front"] = {}
@@ -116,4 +120,6 @@ def serve():
116
120
  app.on_shutdown.append(shutdown)
117
121
  app.router.add_get(r"/{side:(front|back)}/{origin}", websocket)
118
122
  app.router.add_static("/assets/", Path(__file__).parent / "static" / "assets")
119
- web.run_app(app, host=config.host, port=config.port, print=False)
123
+ loop = asyncio.get_event_loop()
124
+ loop.set_exception_handler(exception_handler)
125
+ web.run_app(app, host=config.host, port=config.port, print=False, loop=loop)