liveConsole 1.7.6__tar.gz → 1.7.7__tar.gz

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.
Files changed (26) hide show
  1. {liveconsole-1.7.6/src/liveConsole.egg-info → liveconsole-1.7.7}/PKG-INFO +1 -1
  2. {liveconsole-1.7.6 → liveconsole-1.7.7}/pyproject.toml +1 -1
  3. {liveconsole-1.7.6 → liveconsole-1.7.7/src/liveConsole.egg-info}/PKG-INFO +1 -1
  4. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/pysole.py +25 -14
  5. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/suggestionManager.py +5 -2
  6. liveconsole-1.7.7/src/pysole/utils.py +45 -0
  7. liveconsole-1.7.6/src/pysole/utils.py +0 -13
  8. {liveconsole-1.7.6 → liveconsole-1.7.7}/LICENSE +0 -0
  9. {liveconsole-1.7.6 → liveconsole-1.7.7}/MANIFEST.in +0 -0
  10. {liveconsole-1.7.6 → liveconsole-1.7.7}/README.md +0 -0
  11. {liveconsole-1.7.6 → liveconsole-1.7.7}/setup.cfg +0 -0
  12. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole/__init__.py +0 -0
  13. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole.egg-info/SOURCES.txt +0 -0
  14. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole.egg-info/dependency_links.txt +0 -0
  15. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole.egg-info/entry_points.txt +0 -0
  16. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole.egg-info/requires.txt +0 -0
  17. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/liveConsole.egg-info/top_level.txt +0 -0
  18. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/__init__.py +0 -0
  19. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/__main__.py +0 -0
  20. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/commandHistory.py +0 -0
  21. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/helpTab.py +0 -0
  22. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/liveConsole.py +0 -0
  23. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/mainConsole.py +0 -0
  24. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/settings.json +0 -0
  25. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/styledTextbox.py +0 -0
  26. {liveconsole-1.7.6 → liveconsole-1.7.7}/src/pysole/themes.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: liveConsole
3
- Version: 1.7.6
3
+ Version: 1.7.7
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,6 +1,6 @@
1
1
  [project]
2
2
  name = "liveConsole"
3
- version = "1.7.6"
3
+ version = "1.7.7"
4
4
  description = "An IDLE-like debugger to allow for real-time command injection for debugging and testing python code"
5
5
  authors = [{ name="Tzur Soffer", email="tzur.soffer@gmail.com" }]
6
6
  license = {text = "MIT"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: liveConsole
3
- Version: 1.7.6
3
+ Version: 1.7.7
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
@@ -8,7 +8,7 @@ import sys
8
8
  import io
9
9
  import json
10
10
 
11
- from .utils import settingsPath, themesPath, stdPrint
11
+ from .utils import settingsPath, themesPath, stdPrint, normalizeWhitespace, findUnindentedLine
12
12
  from .helpTab import HelpTab
13
13
  from .mainConsole import InteractiveConsoleText
14
14
 
@@ -73,6 +73,7 @@ class InteractiveConsole(ctk.CTk):
73
73
  if userLocals is None:
74
74
  userLocals = callerFrame.f_locals
75
75
 
76
+ self.callerFrame = callerFrame
76
77
  self.userGlobals = userGlobals
77
78
  self.userLocals = userLocals
78
79
 
@@ -87,20 +88,30 @@ class InteractiveConsole(ctk.CTk):
87
88
  self.runRemainingCode = runRemainingCode
88
89
  self.printStartupCode = printStartupCode
89
90
  self.removeWaterMark = removeWaterMark
90
- self.startupCode = ()
91
+ self.startupCode = []
91
92
  if runRemainingCode:
92
- code_obj = callerFrame.f_code
93
- filename = code_obj.co_filename
94
-
95
- # Read the rest of the file after the call to probe()
96
- with open(filename, "r", encoding="utf-8") as f:
97
- lines = f.readlines()
98
-
99
- startLineIndex = callerFrame.f_lineno
100
- startLine = lines[startLineIndex - 1]
101
- leadingWhitespaceLen = len(startLine) - len(startLine.lstrip())
102
- self.startupCode = lines[startLineIndex:]
103
- self.startupCode = [line.rstrip()[leadingWhitespaceLen:] for line in self.startupCode]
93
+ self.startupCode = self._getStartupCode()
94
+
95
+ def _getStartupCode(self):
96
+ code_obj = self.callerFrame.f_code
97
+ callStartLineIndex = inspect.getframeinfo(self.callerFrame).positions.lineno #< start of the probe call
98
+ callEndLineIndex = inspect.getframeinfo(self.callerFrame).positions.end_lineno #< end of the probe call
99
+ filename = code_obj.co_filename
100
+
101
+ # Read the rest of the file after the call to probe()
102
+ with open(filename, "r", encoding="utf-8") as f:
103
+ lines = f.readlines()
104
+
105
+ startLine = lines[callStartLineIndex-1]
106
+ for line in lines[callStartLineIndex:callEndLineIndex]:
107
+ startLine += line.strip()
108
+
109
+ startupCode = normalizeWhitespace(lines[callEndLineIndex:]) #< ensure the code is not indented too much (egg if in __name__ == "__main__")
110
+ firstUnindentedLine = findUnindentedLine(startupCode)
111
+ while firstUnindentedLine != 0 and firstUnindentedLine != None: #< handle if probe is inside a loop/if/etc by simply unindenting the call (while is for nested calls)
112
+ startupCode[:firstUnindentedLine] = normalizeWhitespace(startupCode[:firstUnindentedLine])
113
+ firstUnindentedLine = findUnindentedLine(startupCode)
114
+ return(startupCode)
104
115
 
105
116
  def _createMenu(self):
106
117
  """Create a menu bar using CTkOptionMenu."""
@@ -107,8 +107,11 @@ class CodeSuggestionManager:
107
107
  self.suggestionListbox.selection_set(0)
108
108
 
109
109
  # Position window near cursor
110
- self._positionSuggestionWindow()
111
- self.suggestionWindow.deiconify()
110
+ try: #< some weird errors idk
111
+ self._positionSuggestionWindow()
112
+ self.suggestionWindow.deiconify()
113
+ except:
114
+ pass
112
115
 
113
116
  def _createSuggestionWindow(self):
114
117
  """Create the suggestion popup window."""
@@ -0,0 +1,45 @@
1
+ import os
2
+ import sys
3
+ import re
4
+
5
+ settingsPath = os.path.join(os.path.dirname(__file__), "settings.json")
6
+ themesPath = os.path.join(os.path.dirname(__file__), "themes.json")
7
+
8
+ def stdPrint(text):
9
+ """Print text to the terminal."""
10
+ try:
11
+ sys.__stdout__.write(f"{text}\n")
12
+ sys.__stdout__.flush()
13
+ except:
14
+ pass
15
+
16
+ def normalizeWhitespace(lines):
17
+ """
18
+ Normalize leading whitespace across a list of code lines.
19
+ Removes common leading indentation and trims excess on over-indented lines.
20
+ """
21
+
22
+ if type(lines) == str:
23
+ lines = lines.split('\n')
24
+
25
+ # Remove empty lines and preserve original line endings
26
+ strippedLines = [line.rstrip('\n') for line in lines if line.strip()]
27
+ if not strippedLines:
28
+ return []
29
+
30
+ # Find minimum indentation across non-empty lines
31
+ indentLevels = [
32
+ len(re.match(r'^[ \t]*', line).group())
33
+ for line in strippedLines
34
+ ]
35
+ minIndent = min(indentLevels)
36
+
37
+
38
+ normalized = [line[minIndent:] if len(line) >= minIndent else line for line in lines] #< Normalize by removing minIndent from each line
39
+ return(normalized)
40
+
41
+ def findUnindentedLine(lines):
42
+ for i, line in enumerate(lines):
43
+ if re.match(r'^\S', line): # Line starts with non-whitespace
44
+ return(i)
45
+ return(None)
@@ -1,13 +0,0 @@
1
- import os
2
- import sys
3
-
4
- settingsPath = os.path.join(os.path.dirname(__file__), "settings.json")
5
- themesPath = os.path.join(os.path.dirname(__file__), "themes.json")
6
-
7
- def stdPrint(text):
8
- """Print text to the terminal."""
9
- try:
10
- sys.__stdout__.write(f"{text}\n")
11
- sys.__stdout__.flush()
12
- except:
13
- pass
File without changes
File without changes
File without changes
File without changes