liveConsole 1.7.2__py3-none-any.whl → 1.7.3__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.

Potentially problematic release.


This version of liveConsole might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: liveConsole
3
- Version: 1.7.2
3
+ Version: 1.7.3
4
4
  Summary: An IDLE-like debugger to allow for real-time command injection for debugging and testing python code
5
5
  Author-email: Tzur Soffer <tzur.soffer@gmail.com>
6
6
  License: MIT
@@ -1,18 +1,18 @@
1
- liveconsole-1.7.2.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
1
+ liveconsole-1.7.3.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
2
2
  pysole/__init__.py,sha256=SfaSBmFVSmhyf55UedBCqhi2Ss6Tre-BCKtZb3bSr2k,60
3
3
  pysole/__main__.py,sha256=QvVFH8J2yzgQaF9MosQ6ajCW67uiRbYliePsTEUCIAg,82
4
4
  pysole/commandHistory.py,sha256=xJtWbJ_vgJo2QGgaZJsApTOi_Hm8Yz0V9_zqQUCItj8,1084
5
5
  pysole/helpTab.py,sha256=o0uSY-8sw7FuuBrt0FQwcgK6ljNVx3IgRnW7heZ6GvY,2454
6
6
  pysole/liveConsole.py,sha256=lzS3dphAQ1i8pQC4E2FY-FyMMSKi-dAN0xr6XUgrNmo,168
7
- pysole/mainConsole.py,sha256=AzAUSP5W1jUhYnnGUNOG8LUGPkRW8jOqOHlk-pJC_V4,15053
8
- pysole/pysole.py,sha256=Y65Sxn3knI6O5qWf_SemhNqYq_a_9j8UmFN_in3MkPo,12096
9
- pysole/settings.json,sha256=oFguWetRe_vGXUrqWSFUvY3JmGIArUZYpSiA8YZgRU8,722
7
+ pysole/mainConsole.py,sha256=t_ijaSm2rTxM5CrLqjxT5Oq_OFwxk7JsPOAXxo9dbdE,15357
8
+ pysole/pysole.py,sha256=OdENWPZnchn_DbYGdcb7WULumYM1NxQmwe9DJzPb0xY,12707
9
+ pysole/settings.json,sha256=cmOtIhRDWHMwmQMESuykWuzJd_jG6iT2tJ-uhSps_3U,722
10
10
  pysole/styledTextbox.py,sha256=qWnwGAKjl7R2HYPXQOr8GrGYIr4JC8PzmeioOCH7hGo,2236
11
11
  pysole/suggestionManager.py,sha256=EUFeCQoZnLS8EjPPNuZpzjY0BR07m2KP5TloyaMDVGY,6457
12
- pysole/themes.json,sha256=wv56r5XOV-ao7dY4_5Yjsio9VvJ58vHOI9nT7MEbXKY,2525
12
+ pysole/themes.json,sha256=2KvEfxm-eDsfVKIdBhWk-Qd93wYQub3YwkxbS6CGKH0,2525
13
13
  pysole/utils.py,sha256=-mGHAp0MkbMPQ9eYzPmo5AGHDLuQ9NfPio_2_iaiCuY,294
14
- liveconsole-1.7.2.dist-info/METADATA,sha256=wHbOWU78adzKUY7jBr-NuF73_0CHAeiiXrmTGjzw1QM,4955
15
- liveconsole-1.7.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- liveconsole-1.7.2.dist-info/entry_points.txt,sha256=qtvuJHcex4QqM97x_UawFWJYnfhQRl0jhqLcWRpnAGo,84
17
- liveconsole-1.7.2.dist-info/top_level.txt,sha256=DlpA93ScJbRZcF8kGSc5YoO8Ntu1ib1_MEZMb4xea_Q,7
18
- liveconsole-1.7.2.dist-info/RECORD,,
14
+ liveconsole-1.7.3.dist-info/METADATA,sha256=6AmM8rq7hHfgfxzn7353PwDLSBgVs2JoX2tNWvUdhMM,4955
15
+ liveconsole-1.7.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ liveconsole-1.7.3.dist-info/entry_points.txt,sha256=qtvuJHcex4QqM97x_UawFWJYnfhQRl0jhqLcWRpnAGo,84
17
+ liveconsole-1.7.3.dist-info/top_level.txt,sha256=DlpA93ScJbRZcF8kGSc5YoO8Ntu1ib1_MEZMb4xea_Q,7
18
+ liveconsole-1.7.3.dist-info/RECORD,,
pysole/mainConsole.py CHANGED
@@ -50,6 +50,10 @@ class InteractiveConsoleText(StyledTextWindow):
50
50
  self.bind("<Up>", self.onUp)
51
51
  self.bind("<Down>", self.onDown)
52
52
 
53
+ def getPromptPosition(self):
54
+ """Get the position right after the prompt on current command line."""
55
+ return(f"{self.currentCommandLine}.{self.PROMPT_LENGTH}")
56
+
53
57
  def getCurrentLineNumber(self):
54
58
  """Get the line number where current command starts."""
55
59
  return(int(self.index("end-1c").split(".")[0]))
@@ -60,30 +64,35 @@ class InteractiveConsoleText(StyledTextWindow):
60
64
  def getCommandStartPosition(self):
61
65
  """Get the starting position of the current command."""
62
66
  return(f"{self.currentCommandLine}.0")
67
+
68
+ def writeToPrompt(self, text):
69
+ """Write text to the prompt of the console"""
70
+ if self.isExecuting:
71
+ return
72
+
73
+ if text:
74
+ self.insert("end", text)
75
+ self.mark_set("insert", "end")
76
+ self.see("end")
77
+ self.updateStyling(start=self.getPromptPosition()) #< Ensure styling/lexer applied after programmatic change:
63
78
 
64
79
  def replaceCurrentCommand(self, newCommand):
65
80
  """Replace the current command with new text."""
66
- if self.isExecuting:
67
- return
68
-
69
81
  start = self.getPromptPosition()
70
82
  end = "end-1c"
71
-
72
83
  self.delete(start, end)
73
- if newCommand:
74
- self.insert(start, newCommand)
75
- self.mark_set("insert", "end")
76
- self.see("end")
77
- # Ensure styling/lexer applied after programmatic change:
78
- self.updateStyling(start=self.getPromptPosition())
84
+ self.writeToPrompt(newCommand)
79
85
 
80
- def runCommand(self, command, printCommand=False):
86
+ def runCommand(self, command, printCommand=False, clearPrompt=True):
81
87
  """Insert code into the console prompt and execute it as if Enter was pressed."""
82
88
  if self.isExecuting:
83
89
  return(False)
84
90
  if printCommand:
85
- self.replaceCurrentCommand(command) #< Replace current command with the new code
86
- self.onEnter(None) #< Simulate pressing Enter to run the command
91
+ if clearPrompt:
92
+ self.replaceCurrentCommand(command) #< Replace current command with the new code
93
+ else:
94
+ self.writeToPrompt(command)
95
+ self.onEnter(None, insertWhitespace=False) #< Simulate pressing Enter to run the command
87
96
  else:
88
97
  self.executeCommandThreaded(command, addPrompt=False)
89
98
 
@@ -98,7 +107,7 @@ class InteractiveConsoleText(StyledTextWindow):
98
107
  return((cursorLine >= self.currentCommandLine and
99
108
  (cursorLine > self.currentCommandLine or cursorCol >= self.PROMPT_LENGTH)))
100
109
 
101
- def onEnter(self, event):
110
+ def onEnter(self, event, insertWhitespace=True):
102
111
  """Handle Enter key - execute command."""
103
112
  self.suggestionManager.hideSuggestions()
104
113
 
@@ -119,9 +128,8 @@ class InteractiveConsoleText(StyledTextWindow):
119
128
  return("break")
120
129
 
121
130
  # Check if statement is incomplete
122
- if self.isIncompleteStatement(command):
131
+ if self.isIncompleteStatement(command) and insertWhitespace:
123
132
  return(self.onShiftEnter(event))
124
-
125
133
  # Execute the command
126
134
  self.history.add(command)
127
135
  self.mark_set("insert", "end")
@@ -351,10 +359,6 @@ class InteractiveConsoleText(StyledTextWindow):
351
359
  """Insert a newline at the end."""
352
360
  self.writeOutput("")
353
361
 
354
- def getPromptPosition(self):
355
- """Get the position right after the prompt on current command line."""
356
- return(f"{self.currentCommandLine}.{self.PROMPT_LENGTH}")
357
-
358
362
  def getCurrentCommand(self):
359
363
  """Extract the current command text (without prompt)."""
360
364
  start = self.getPromptPosition()
pysole/pysole.py CHANGED
@@ -86,7 +86,6 @@ class InteractiveConsole(ctk.CTk):
86
86
 
87
87
  self.runRemainingCode = runRemainingCode
88
88
  self.printStartupCode = printStartupCode
89
- self.leadingWhitespaceLen = 0
90
89
  self.removeWaterMark = removeWaterMark
91
90
  self.startupCode = ()
92
91
  if runRemainingCode:
@@ -99,8 +98,9 @@ class InteractiveConsole(ctk.CTk):
99
98
 
100
99
  startLineIndex = callerFrame.f_lineno
101
100
  startLine = lines[startLineIndex - 1]
102
- self.leadingWhitespaceLen = len(startLine) - len(startLine.lstrip())
101
+ leadingWhitespaceLen = len(startLine) - len(startLine.lstrip())
103
102
  self.startupCode = lines[startLineIndex:]
103
+ self.startupCode = [line.rstrip()[leadingWhitespaceLen:] for line in self.startupCode]
104
104
 
105
105
  def _createMenu(self):
106
106
  """Create a menu bar using CTkOptionMenu."""
@@ -260,42 +260,70 @@ class InteractiveConsole(ctk.CTk):
260
260
  sys.stdout = sys.__stdout__
261
261
  sys.stderr = sys.__stderr__
262
262
  self.destroy()
263
+
264
+ def _printWaterMark(self):
265
+ m = (
266
+ "Welcome to Pysole, if you find me useful, please star me on GitHub:\n"
267
+ "https://github.com/TzurSoffer/Pysole"
268
+ )
269
+ stdPrint(m)
270
+ self.console.newline()
271
+ self.console.writeOutput(m, "instruction")
272
+ time.sleep(0.1)
273
+ if self.runRemainingCode:
274
+ if self.printStartupCode:
275
+ self.console.addPrompt()
276
+ else:
277
+ self.console.newline()
278
+ else:
279
+ self.console.addPrompt()
280
+
281
+ def _splitCodeIntoChunks(self):
282
+ codeChunks = []
283
+ currentChunk = []
284
+
285
+ for line in self.startupCode:
286
+ strippedLine = line.lstrip()
287
+ indentLevel = len(line) - len(strippedLine)
288
+
289
+ if not strippedLine: #< Blank line, keep it in current chunk
290
+ currentChunk.append(line)
291
+ continue
292
+
293
+ if indentLevel != 0:
294
+ currentChunk.append(line)
295
+ else:
296
+ codeChunks.append(currentChunk)
297
+ currentChunk = [line]
298
+
299
+ if currentChunk:
300
+ codeChunks.append(currentChunk)
301
+
302
+ return(["\n".join(chunk).strip() for chunk in codeChunks if any(line.strip() for line in chunk)])
303
+
304
+
305
+ def _runStartup(self):
306
+ if self.removeWaterMark == False:
307
+ self._printWaterMark()
308
+
309
+ if self.runRemainingCode == False:
310
+ return
311
+
312
+ if self.printStartupCode == False:
313
+ self.console.newline()
314
+ code = "\n".join(self.startupCode)
315
+ self.console.executeCommandThreaded(code, addPrompt=True)
316
+ return
317
+
318
+ chunks = self._splitCodeIntoChunks()
319
+ for chunk in chunks:
320
+ while self.console.isExecuting:
321
+ time.sleep(0.01)
322
+ self.console.runCommand(chunk, printCommand=True, clearPrompt=True)
263
323
 
264
324
  def probe(self, *args, **kwargs):
265
325
  """Start the console main loop."""
266
- def runStartup():
267
- if not self.removeWaterMark:
268
- m = (
269
- "Welcome to Pysole, if you find me useful, please star me on GitHub:\n"
270
- "https://github.com/TzurSoffer/Pysole"
271
- )
272
- stdPrint(m)
273
- self.console.newline()
274
- self.console.writeOutput(m, "instruction")
275
- time.sleep(0.1)
276
- if self.runRemainingCode:
277
- if self.printStartupCode:
278
- self.console.addPrompt()
279
- else:
280
- self.console.newline()
281
- else:
282
- self.console.addPrompt()
283
- elif self.runRemainingCode == True and self.printStartupCode == False:
284
- self.console.newline()
285
-
286
- for line in self.startupCode:
287
- line = line.rstrip()[self.leadingWhitespaceLen:]
288
- while self.console.isExecuting:
289
- time.sleep(0.01)
290
- if self.printStartupCode:
291
- self.console.runCommand(line, printCommand=True)
292
- else:
293
- self.console.runCommand(line, printCommand=False)
294
-
295
- if self.runRemainingCode == True and self.printStartupCode == False:
296
- self.console.resetCurrentLineNumber()
297
- self.console.addPrompt()
298
- threading.Thread(target=runStartup).start()
326
+ self.after(0, threading.Thread(target=self._runStartup).start)
299
327
  self.mainloop(*args, **kwargs)
300
328
 
301
329
  def probe(userGlobals=None, userLocals=None, callerFrame=None,
pysole/settings.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "OUTPUT": "#ffffff",
12
12
  "ERROR": "#ff0000",
13
13
  "RESULT": "#66ccff",
14
- "INSTRUCTION": "#ffff00",
14
+ "INSTRUCTION": "#ffccdd",
15
15
  "SUGGESTION_BOX_BG": "#2d2d2d",
16
16
  "SUGGESTION_BOX_SELECTION_BG": "#0066cc",
17
17
  "FONT": {
pysole/themes.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "OUTPUT": "#ffffff",
12
12
  "ERROR": "#ff0000",
13
13
  "RESULT": "#66ccff",
14
- "INSTRUCTION": "#ffff00",
14
+ "INSTRUCTION": "#ffccdd",
15
15
  "SUGGESTION_BOX_BG": "#2d2d2d",
16
16
  "SUGGESTION_BOX_SELECTION_BG": "#0066cc",
17
17
  "FONT": {
@@ -31,7 +31,7 @@
31
31
  "OUTPUT": "#000000",
32
32
  "ERROR": "#ff0000",
33
33
  "RESULT": "#0066cc",
34
- "INSTRUCTION": "#ffff00",
34
+ "INSTRUCTION": "#ffccdd",
35
35
  "SUGGESTION_BOX_BG": "#f0f0f0",
36
36
  "SUGGESTION_BOX_SELECTION_BG": "#cce6ff",
37
37
  "FONT": {
@@ -51,7 +51,7 @@
51
51
  "OUTPUT": "#586e75",
52
52
  "ERROR": "#dc322f",
53
53
  "RESULT": "#2aa198",
54
- "INSTRUCTION": "#ffff00",
54
+ "INSTRUCTION": "#ffccdd",
55
55
  "SUGGESTION_BOX_BG": "#eee8d5",
56
56
  "SUGGESTION_BOX_SELECTION_BG": "#b58900",
57
57
  "FONT": {
@@ -71,7 +71,7 @@
71
71
  "OUTPUT": "#f8f8f2",
72
72
  "ERROR": "#ff5555",
73
73
  "RESULT": "#8be9fd",
74
- "INSTRUCTION": "#ffff00",
74
+ "INSTRUCTION": "#ffccdd",
75
75
  "SUGGESTION_BOX_BG": "#44475a",
76
76
  "SUGGESTION_BOX_SELECTION_BG": "#6272a4",
77
77
  "FONT": {