mwxlib 0.92.0__py3-none-any.whl → 0.92.4__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 mwxlib might be problematic. Click here for more details.

mwx/bookshelf.py CHANGED
@@ -123,9 +123,9 @@ class EditorTreeCtrl(wx.TreeCtrl, CtrlInterface, TreeList):
123
123
  data = rest[0]
124
124
  data._itemId = item
125
125
  self.SetItemData(item, data)
126
- if (buf := data.buffer):
127
- self.SetItemText(item, buf.caption_prefix + buf.name)
128
- except Exception:
126
+ buf = data.buffer
127
+ self.SetItemText(item, buf.caption_prefix + buf.name)
128
+ except AttributeError:
129
129
  pass
130
130
  for branch in branches:
131
131
  self._set_item(item, *branch)
mwx/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.92.0"
4
+ __version__ = "0.92.4"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from functools import wraps, partial
@@ -491,7 +491,7 @@ def pack(self, items, orient=wx.HORIZONTAL, style=None, label=None):
491
491
  traceback.print_exc()
492
492
  bmp = wx.StaticBitmap(self,
493
493
  bitmap=wx.ArtProvider.GetBitmap(wx.ART_ERROR))
494
- bmp.SetToolTip("Pack failure\n{}".format(e))
494
+ bmp.SetToolTip(str(e))
495
495
  sizer.Add(bmp, 0, wx.EXPAND | wx.ALL, 0)
496
496
  wx.Bell()
497
497
  return sizer
@@ -852,8 +852,9 @@ class AuiNotebook(aui.AuiNotebook):
852
852
  wnd = wx.Window.FindFocus() # original focus
853
853
  org = self.CurrentPage
854
854
  if j != self.Selection:
855
- self.Selection = j # the focus is moved
856
- if wnd and wnd is not org: # restore focus other window
855
+ self.Selection = j # focus moved if shown
856
+ self.CurrentPage.SetFocus() # reset focus
857
+ if wnd and wnd is not org: # restore focus other window
857
858
  wnd.SetFocus()
858
859
 
859
860
  def get_caption(self, win):
@@ -962,7 +963,7 @@ class AuiNotebook(aui.AuiNotebook):
962
963
  self._mgr.LoadPerspective(frames)
963
964
  self._mgr.Update()
964
965
  except Exception as e:
965
- print("- Failed to load perspective: {}".format(e))
966
+ print(f"- Failed to load perspective: {e}")
966
967
  pass
967
968
  finally:
968
969
  self.Parent.Thaw()
@@ -1060,7 +1061,7 @@ class ShellFrame(MiniFrame):
1060
1061
  self.__standalone = bool(ensureClose)
1061
1062
 
1062
1063
  ## Initialize self-specific builtins.
1063
- ## Note: This should be called before creating rootshell.
1064
+ ## Note: This should be called before creating root shell.
1064
1065
  self.Init()
1065
1066
 
1066
1067
  from .nutshell import Nautilus, EditorBook
@@ -1107,8 +1108,8 @@ class ShellFrame(MiniFrame):
1107
1108
 
1108
1109
  self.ghost = AuiNotebook(self, size=(600,400))
1109
1110
  self.ghost.AddPage(self.Scratch, "Scratch")
1110
- self.ghost.AddPage(self.Log, "Log")
1111
- self.ghost.AddPage(self.Help, "Help")
1111
+ self.ghost.AddPage(self.Log, "Log")
1112
+ self.ghost.AddPage(self.Help, "Help")
1112
1113
  self.ghost.Name = "ghost"
1113
1114
 
1114
1115
  self.Bookshelf = EditorTreeCtrl(self, name="Bookshelf",
@@ -1248,12 +1249,9 @@ class ShellFrame(MiniFrame):
1248
1249
  self.Log.set_attributes(ReadOnly=True)
1249
1250
  self.Help.set_attributes(ReadOnly=True)
1250
1251
 
1251
- msg = "#! Opened: <{}>\r\n".format(datetime.datetime.now())
1252
- self.add_log(msg)
1253
-
1254
1252
  self.load_session(
1255
1253
  os.path.abspath(debrc) if debrc else self.SESSION_FILE)
1256
-
1254
+
1257
1255
  SESSION_FILE = get_rootpath(".debrc")
1258
1256
  SCRATCH_FILE = get_rootpath("scratch.py")
1259
1257
  LOGGING_FILE = get_rootpath("deb-logging.log")
@@ -1271,7 +1269,10 @@ class ShellFrame(MiniFrame):
1271
1269
 
1272
1270
  if flush:
1273
1271
  for book in self.all_books:
1274
- book.delete_all_buffers()
1272
+ book.delete_all_buffers() # Note: *log* is also flushed.
1273
+
1274
+ msg = "#! Opened: <{}>\r\n".format(datetime.datetime.now())
1275
+ self.add_log(msg)
1275
1276
 
1276
1277
  def _fload(editor, filename):
1277
1278
  try:
@@ -1317,7 +1318,7 @@ class ShellFrame(MiniFrame):
1317
1318
  pass
1318
1319
 
1319
1320
  _fsave(self.Scratch, self.SCRATCH_FILE) # save scratch
1320
- _fsave(self.Log, self.LOGGING_FILE)
1321
+ _fsave(self.Log, self.LOGGING_FILE) # save log
1321
1322
 
1322
1323
  with open(self.SESSION_FILE, 'w', encoding='utf-8', newline='') as o:
1323
1324
  o.write("#! Session file (This file is generated automatically)\n")
@@ -1365,10 +1366,7 @@ class ShellFrame(MiniFrame):
1365
1366
 
1366
1367
  def Destroy(self):
1367
1368
  try:
1368
- self.timer.Stop()
1369
- self.save_session()
1370
-
1371
- ## Remove built-in methods
1369
+ ## Remove built-in self methods
1372
1370
  del builtins.info
1373
1371
  del builtins.help
1374
1372
  del builtins.load
@@ -1378,6 +1376,11 @@ class ShellFrame(MiniFrame):
1378
1376
  del builtins.timeit
1379
1377
  del builtins.profile
1380
1378
  del builtins.highlight
1379
+ except AttributeError:
1380
+ pass
1381
+ try:
1382
+ self.timer.Stop()
1383
+ self.save_session()
1381
1384
  finally:
1382
1385
  self._mgr.UnInit()
1383
1386
  return MiniFrame.Destroy(self)
@@ -1514,15 +1517,13 @@ class ShellFrame(MiniFrame):
1514
1517
  "Version: {!s}".format(__version__),
1515
1518
  self.__class__.__doc__,
1516
1519
  self.rootshell.__class__.__doc__,
1517
-
1518
- # Thanks to wx.py.shell.
1520
+ ## Thanks to wx.py.shell.
1519
1521
  "#{!r}".format(wx.py),
1520
1522
  "Author: {!r}".format(wx.py.version.__author__),
1521
1523
  "Version: {!s}".format(wx.py.version.VERSION),
1522
1524
  wx.py.shell.Shell.__doc__,
1523
1525
  textwrap.indent("*original" + wx.py.shell.HELP_TEXT, ' '*4),
1524
-
1525
- # Thanks are also due to wxWidgets.
1526
+ ## Thanks are also due to wx.
1526
1527
  "#{!r}".format(wx),
1527
1528
  "To show the credit, press C-M-Mbutton.\n",
1528
1529
  ))
@@ -1684,39 +1685,35 @@ class ShellFrame(MiniFrame):
1684
1685
  ## Note: history に余計な文字列が入らないようにする
1685
1686
  @postcall
1686
1687
  def debug(self, obj, *args, **kwargs):
1687
- if isinstance(obj, type(print)):
1688
- wx.MessageBox("Unable to debug builtin functions.\n\n"
1689
- "Target must be callable or wx.Object.",
1690
- style=wx.ICON_ERROR)
1691
- elif callable(obj):
1692
- try:
1693
- shell = self.debugger.interactive_shell
1694
- self.debugger.interactive_shell = self.current_shell
1695
- self.debugger.editor = self.Log # set default logger
1688
+ shell = self.debugger.interactive_shell
1689
+ self.debugger.interactive_shell = self.current_shell
1690
+ try:
1691
+ if isinstance(obj, type(print)):
1692
+ wx.MessageBox("Unable to debug builtin functions.\n\n"
1693
+ "Target must be callable or wx.Object.",
1694
+ style=wx.ICON_ERROR)
1695
+ elif callable(obj):
1696
1696
  self.debugger.debug(obj, *args, **kwargs)
1697
- finally:
1698
- self.debugger.interactive_shell = shell
1699
- elif isinstance(obj, str):
1700
- try:
1701
- shell = self.debugger.interactive_shell
1702
- self.debugger.interactive_shell = self.current_shell
1703
- self.debugger.editor = self.Log # set default logger
1697
+ elif isinstance(obj, str):
1704
1698
  filename = "<string>"
1705
- buf = self.Log.find_buffer(filename) or self.Log.create_buffer(filename)
1699
+ buf = self.Scratch.find_buffer(filename)\
1700
+ or self.Scratch.create_buffer(filename)
1706
1701
  with buf.off_readonly():
1707
1702
  buf.Text = obj
1708
- self.debugger.run(obj)
1709
- finally:
1710
- self.debugger.interactive_shell = shell
1711
- elif isinstance(obj, wx.Object):
1712
- self.watch(obj)
1713
- else:
1714
- wx.MessageBox("Unable to debug non-callable objects.\n\n"
1715
- "Target must be callable or wx.Object.",
1716
- style=wx.ICON_ERROR)
1703
+ self.debugger.run(obj, filename)
1704
+ elif isinstance(obj, wx.Object):
1705
+ self.watch(obj)
1706
+ else:
1707
+ wx.MessageBox("Unable to debug non-callable objects.\n\n"
1708
+ "Target must be callable or wx.Object.",
1709
+ style=wx.ICON_ERROR)
1710
+ finally:
1711
+ self.debugger.interactive_shell = shell
1717
1712
 
1718
1713
  def on_debug_begin(self, frame):
1719
1714
  """Called before set_trace."""
1715
+ if not self:
1716
+ return
1720
1717
  shell = self.debugger.interactive_shell
1721
1718
  shell.write("#<-- Enter [n]ext to continue.\n", -1)
1722
1719
  shell.prompt()
@@ -1729,6 +1726,8 @@ class ShellFrame(MiniFrame):
1729
1726
 
1730
1727
  def on_debug_next(self, frame):
1731
1728
  """Called from cmdloop."""
1729
+ if not self:
1730
+ return
1732
1731
  shell = self.debugger.interactive_shell
1733
1732
  shell.globals = gs = frame.f_globals
1734
1733
  shell.locals = ls = frame.f_locals
@@ -1748,6 +1747,8 @@ class ShellFrame(MiniFrame):
1748
1747
 
1749
1748
  def on_debug_end(self, frame):
1750
1749
  """Called after set_quit."""
1750
+ if not self:
1751
+ return
1751
1752
  shell = self.debugger.interactive_shell
1752
1753
  shell.write("#--> Debugger closed successfully.\n", -1)
1753
1754
  shell.prompt()
@@ -1830,9 +1831,10 @@ class ShellFrame(MiniFrame):
1830
1831
  ## Set a marker on the current line.
1831
1832
  buf.add_marker(buf.cline, 1 if noerr else 2) # 1:white 2:red-arrow
1832
1833
  return
1834
+
1833
1835
  ## Logging text every step in case of crash.
1834
- with open(self.LOGGING_FILE, 'a', encoding='utf-8', newline='') as o:
1835
- o.write(text)
1836
+ ## with open(self.LOGGING_FILE, 'a', encoding='utf-8', newline='') as o:
1837
+ ## o.write(text)
1836
1838
 
1837
1839
  def add_help(self, text):
1838
1840
  """Add text to the help buffer."""
@@ -1841,7 +1843,6 @@ class ShellFrame(MiniFrame):
1841
1843
  buf.SetText(text)
1842
1844
  ## Overwrite text and popup the window.
1843
1845
  self.popup_window(self.Help, focus=0)
1844
- self.Help.swap_page(buf)
1845
1846
 
1846
1847
  def clone_shell(self, target):
1847
1848
  if not hasattr(target, '__dict__'):
@@ -1860,6 +1861,10 @@ class ShellFrame(MiniFrame):
1860
1861
  if shell is self.rootshell:
1861
1862
  ## self.message("- Don't close the root shell.")
1862
1863
  return
1864
+ if self.debugger.busy and shell is self.debugger.interactive_shell:
1865
+ wx.MessageBox("The debugger is running.\n\n"
1866
+ "Enter [q]uit to exit before closing.")
1867
+ return
1863
1868
  j = self.console.GetPageIndex(shell)
1864
1869
  if j != -1:
1865
1870
  self.console.DeletePage(j) # Destroy the window
@@ -1873,10 +1878,15 @@ class ShellFrame(MiniFrame):
1873
1878
  yield from self.console.get_pages(type)
1874
1879
  yield from self.ghost.get_pages(type)
1875
1880
 
1881
+ @property
1882
+ def all_shells(self):
1883
+ """Yields all books in the notebooks."""
1884
+ yield from self.console.get_pages(type(self.rootshell))
1885
+
1876
1886
  @property
1877
1887
  def all_books(self):
1878
1888
  """Yields all books in the notebooks."""
1879
- yield from self.get_all_pages(type(self.Log))
1889
+ yield from self.ghost.get_pages(type(self.Log))
1880
1890
 
1881
1891
  @property
1882
1892
  def current_shell(self):
mwx/graphman.py CHANGED
@@ -274,31 +274,29 @@ class LayerInterface(CtrlInterface):
274
274
  self.__artists = []
275
275
 
276
276
  def attach_artists(self, axes, *artists):
277
- """Attach artists (e.g., patches) to the given axes.
278
- If axes is None, they will be removed from the axes.
279
- """
280
- if not artists:
281
- artists = self.Arts[:]
282
- if axes:
283
- for art in artists:
284
- if art.axes and art.axes is not axes:
285
- art.remove()
286
- art._transformSet = False
287
- axes.add_artist(art)
288
- if art not in self.Arts:
289
- self.Arts.append(art)
290
- else:
291
- for art in artists:
292
- if art.axes:
293
- art.remove()
294
- art._transformSet = False
295
- self.Arts.remove(art)
277
+ """Attach artists (e.g., patches) to the given axes."""
278
+ for art in artists:
279
+ if art.axes and art.axes is not axes:
280
+ art.remove()
281
+ art._transformSet = False
282
+ axes.add_artist(art)
283
+ if art not in self.__artists:
284
+ self.__artists.append(art)
285
+
286
+ def detach_artists(self, *artists):
287
+ """Detach artists (e.g., patches) from their axes."""
288
+ for art in artists:
289
+ if art.axes:
290
+ art.remove()
291
+ art._transformSet = False
292
+ self.__artists.remove(art)
296
293
 
297
294
  def __init__(self, parent, session=None):
298
295
  CtrlInterface.__init__(self)
299
296
 
300
297
  self.parent = parent
301
298
  self.__artists = []
299
+
302
300
  self.parameters = None # => reset
303
301
 
304
302
  def copy_params(**kwargs):
@@ -1172,7 +1170,7 @@ class Frame(mwx.Frame):
1172
1170
  except (AttributeError, NameError) as e:
1173
1171
  traceback.print_exc()
1174
1172
  wx.CallAfter(wx.MessageBox,
1175
- "{}\n\n{}".format(e, traceback.format_exc()),
1173
+ "{}\n\n".format(e) + traceback.format_exc(),
1176
1174
  "Error in loading {!r}".format(module.__name__),
1177
1175
  style=wx.ICON_ERROR)
1178
1176
  return False
@@ -1189,7 +1187,7 @@ class Frame(mwx.Frame):
1189
1187
  except Exception as e:
1190
1188
  traceback.print_exc()
1191
1189
  wx.CallAfter(wx.MessageBox,
1192
- "{}\n\n{}".format(e, traceback.format_exc()),
1190
+ "{}\n\n".format(e) + traceback.format_exc(),
1193
1191
  "Error in loading {!r}".format(name),
1194
1192
  style=wx.ICON_ERROR)
1195
1193
  return False
@@ -1302,7 +1300,7 @@ class Frame(mwx.Frame):
1302
1300
  except Exception as e:
1303
1301
  traceback.print_exc()
1304
1302
  wx.CallAfter(wx.MessageBox,
1305
- "{}\n\n{}".format(e, traceback.format_exc()),
1303
+ "{}\n\n".format(e) + traceback.format_exc(),
1306
1304
  "Error in unloading {!r}".format(name),
1307
1305
  style=wx.ICON_ERROR)
1308
1306
  return False
@@ -1609,7 +1607,8 @@ class Frame(mwx.Frame):
1609
1607
  for j in range(n):
1610
1608
  self.message("Loading {!r} [{} of {} pages]...".format(fn, j+1, n))
1611
1609
  buf.seek(j)
1612
- frame = view.load(buf, f"{j:0{d}}-{fn}", show=0)
1610
+ name = "{:0{d}}-{}".format(j, fn, d=d)
1611
+ frame = view.load(buf, name, show=0)
1613
1612
  else:
1614
1613
  frame = view.load(buf, fn, show=0, pathname=path, **info)
1615
1614
  frames.append(frame)
mwx/matplot2g.py CHANGED
@@ -943,7 +943,7 @@ class GraphPlot(MatplotPanel):
943
943
  xo, yo = min(nx), min(ny) # top-left
944
944
  xr, yr = max(nx), max(ny) # bottom-right
945
945
  self.message("[Region] "
946
- "crop={0}:{1}:{2}:{3}".format(xr-xo, yr-yo, xo, yo)) # (W:H:left:top)
946
+ "crop={}:{}:{}:{}".format(xr-xo, yr-yo, xo, yo)) # (W:H:left:top)
947
947
  else:
948
948
  return self.trace_point(x[[0,-1]], y[[0,-1]], type)
949
949
 
mwx/nutshell.py CHANGED
@@ -245,7 +245,7 @@ class EditorInterface(CtrlInterface):
245
245
  self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_VLINE, *v)
246
246
  self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_VLINE, *v)
247
247
 
248
- ## Custom indicator [0,1] for filter_text
248
+ ## Custom indicator (0,1) for filter_text
249
249
  ## if wx.VERSION >= (4,1,0):
250
250
  try:
251
251
  self.IndicatorSetStyle(0, stc.STC_INDIC_TEXTFORE)
@@ -260,7 +260,7 @@ class EditorInterface(CtrlInterface):
260
260
  self.IndicatorSetForeground(0, "red")
261
261
  self.IndicatorSetForeground(1, "yellow")
262
262
 
263
- ## Custom indicator [2] for match_paren
263
+ ## Custom indicator (2) for URL (buffer_modified)
264
264
  self.IndicatorSetStyle(2, stc.STC_INDIC_DOTS)
265
265
  self.IndicatorSetForeground(2, "light gray")
266
266
  try:
@@ -269,6 +269,10 @@ class EditorInterface(CtrlInterface):
269
269
  except AttributeError:
270
270
  pass
271
271
 
272
+ ## Custom indicator (3) for match_paren
273
+ self.IndicatorSetStyle(3, stc.STC_INDIC_DOTS)
274
+ self.IndicatorSetForeground(3, "light gray")
275
+
272
276
  ## Custom annotation
273
277
  self.AnnotationSetVisible(stc.STC_ANNOTATION_BOXED)
274
278
 
@@ -283,6 +287,7 @@ class EditorInterface(CtrlInterface):
283
287
  self.IndentationGuides = stc.STC_IV_LOOKFORWARD
284
288
 
285
289
  self.__mark = -1
290
+ self.__stylus = {}
286
291
 
287
292
  ## Custom constants embedded in stc
288
293
  stc.STC_P_WORD3 = 20
@@ -768,12 +773,17 @@ class EditorInterface(CtrlInterface):
768
773
  ## Preferences / Appearance
769
774
  ## --------------------------------
770
775
 
771
- def set_style(self, spec=None, **kwargs):
776
+ def get_stylus(self):
777
+ return self.__stylus
778
+
779
+ def set_stylus(self, spec=None, **kwargs):
772
780
  spec = spec and spec.copy() or {}
773
781
  spec.update(kwargs)
774
782
  if not spec:
775
783
  return
776
784
 
785
+ self.__stylus.update(spec)
786
+
777
787
  def _map(sc):
778
788
  return dict(kv.partition(':')[::2] for kv in sc.split(',') if kv)
779
789
 
@@ -815,7 +825,7 @@ class EditorInterface(CtrlInterface):
815
825
  if 'bold' in item:
816
826
  self.SetCaretStyle(stc.STC_CARETSTYLE_BLOCK)
817
827
 
818
- ## Custom indicator for search-word
828
+ ## Custom indicator (0,1) for filter_text
819
829
  item = _map(spec.pop(stc.STC_P_WORD3, ''))
820
830
  if item:
821
831
  self.IndicatorSetForeground(0, item.get('fore') or "red")
@@ -826,14 +836,14 @@ class EditorInterface(CtrlInterface):
826
836
  self.StyleSetSpec(key, value)
827
837
 
828
838
  def match_paren(self):
829
- ## self.SetIndicatorCurrent(2)
830
- ## self.IndicatorClearRange(0, self.TextLength)
839
+ self.SetIndicatorCurrent(3)
840
+ self.IndicatorClearRange(0, self.TextLength)
831
841
  p = self.cpos
832
842
  if self.get_char(p-1) in ")}]>":
833
843
  q = self.BraceMatch(p-1)
834
844
  if q != -1:
835
845
  self.BraceHighlight(q, p-1) # matched the preceding char
836
- ## self.IndicatorFillRange(q, p-q)
846
+ self.IndicatorFillRange(q, p-q)
837
847
  return q
838
848
  else:
839
849
  self.BraceBadLight(p-1)
@@ -841,7 +851,7 @@ class EditorInterface(CtrlInterface):
841
851
  q = self.BraceMatch(p)
842
852
  if q != -1:
843
853
  self.BraceHighlight(p, q) # matched the following char
844
- ## self.IndicatorFillRange(p, q-p+1)
854
+ self.IndicatorFillRange(p, q-p+1)
845
855
  return q
846
856
  else:
847
857
  self.BraceBadLight(p)
@@ -1044,7 +1054,6 @@ class EditorInterface(CtrlInterface):
1044
1054
  self.Bind(stc.EVT_STC_AUTOCOMP_SELECTION, self.on_itext_selection)
1045
1055
 
1046
1056
  self.StyleSetSize(stc.STC_STYLE_DEFAULT, pts)
1047
-
1048
1057
 
1049
1058
  def on_itext_exit(self, evt):
1050
1059
  """Called when exiting filter_text mode."""
@@ -1179,6 +1188,7 @@ class EditorInterface(CtrlInterface):
1179
1188
 
1180
1189
  @contextmanager
1181
1190
  def save_excursion(self):
1191
+ """Save buffer excursion."""
1182
1192
  try:
1183
1193
  p = self.cpos
1184
1194
  q = self.anchor
@@ -1193,6 +1203,7 @@ class EditorInterface(CtrlInterface):
1193
1203
 
1194
1204
  @contextmanager
1195
1205
  def pre_selection(self):
1206
+ """Save buffer cpos and anchor."""
1196
1207
  try:
1197
1208
  p = self.cpos
1198
1209
  q = self.anchor
@@ -1205,13 +1216,26 @@ class EditorInterface(CtrlInterface):
1205
1216
 
1206
1217
  @contextmanager
1207
1218
  def off_readonly(self):
1219
+ """Set buffer to be writable (ReadOnly=False) temporarily."""
1220
+ r = self.ReadOnly
1208
1221
  try:
1209
- r = self.ReadOnly
1210
1222
  self.ReadOnly = 0
1211
- yield self
1223
+ yield
1212
1224
  finally:
1213
1225
  self.ReadOnly = r
1214
1226
 
1227
+ @contextmanager
1228
+ def save_attributes(self, **kwargs):
1229
+ """Save buffer attributes (e.g. ReadOnly=False)."""
1230
+ for k, v in kwargs.items():
1231
+ kwargs[k] = getattr(self, k)
1232
+ setattr(self, k, v)
1233
+ try:
1234
+ yield
1235
+ finally:
1236
+ for k, v in kwargs.items():
1237
+ setattr(self, k, v)
1238
+
1215
1239
  ## --------------------------------
1216
1240
  ## Edit: comment / insert / kill
1217
1241
  ## --------------------------------
@@ -1501,7 +1525,7 @@ class Buffer(EditWindow, EditorInterface):
1501
1525
  })
1502
1526
 
1503
1527
  self.show_folder()
1504
- self.set_style(self.STYLE)
1528
+ self.set_stylus(self.STYLE)
1505
1529
 
1506
1530
  def __contains__(self, code):
1507
1531
  if inspect.iscode(code) and self.code:
@@ -1792,7 +1816,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1792
1816
  buf : a buffer to apply (if None, applies to all buffers).
1793
1817
  **kwargs : default style.
1794
1818
 
1795
- Style = Buffer.STYLE => set_style
1819
+ Style = Buffer.STYLE
1796
1820
  ReadOnly = False
1797
1821
  UseTabs = False
1798
1822
  ViewEOL = False
@@ -1806,7 +1830,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1806
1830
  def _setattribute(buf, attr):
1807
1831
  for k, v in attr.items():
1808
1832
  if k == 'Style':
1809
- buf.set_style(v)
1833
+ buf.set_stylus(v)
1810
1834
  setattr(buf, k, v)
1811
1835
  if buf:
1812
1836
  _setattribute(buf, kwargs)
@@ -2616,7 +2640,7 @@ class Nautilus(Shell, EditorInterface):
2616
2640
 
2617
2641
  self.wrap(0)
2618
2642
  self.show_folder()
2619
- self.set_style(self.STYLE)
2643
+ self.set_stylus(self.STYLE)
2620
2644
 
2621
2645
  ## delete unnecessary arrows at startup
2622
2646
  del self.white_arrow
@@ -3230,12 +3254,6 @@ class Nautilus(Shell, EditorInterface):
3230
3254
  ]
3231
3255
  Shell.CallTipShow(self, pos, '\n'.join(lines))
3232
3256
 
3233
- def gen_autocomp(self, offset, words, sep=' '):
3234
- """Call AutoCompShow for the specified words and sep."""
3235
- if words:
3236
- self.AutoCompSetSeparator(ord(sep))
3237
- self.AutoCompShow(offset, sep.join(words))
3238
-
3239
3257
  def eval_line(self, evt):
3240
3258
  """Evaluate the selected word or line.
3241
3259
  """
@@ -3358,6 +3376,25 @@ class Nautilus(Shell, EditorInterface):
3358
3376
  except IndexError:
3359
3377
  self.message("No completion words")
3360
3378
 
3379
+ def _gen_autocomp(self, j, hint, words, sep=' '):
3380
+ """Call AutoCompShow for the specified words and sep."""
3381
+ ## Prepare on_completion_forward/backward
3382
+ self.__comp_ind = j
3383
+ self.__comp_hint = hint
3384
+ self.__comp_words = words
3385
+ if words:
3386
+ self.AutoCompSetSeparator(ord(sep))
3387
+ self.AutoCompShow(len(hint), sep.join(words))
3388
+
3389
+ @staticmethod
3390
+ def _get_last_hint(cmdl):
3391
+ return re.search(r"[\w.]*$", cmdl).group(0) # or ''
3392
+
3393
+ @staticmethod
3394
+ def _get_words_hint(cmdl):
3395
+ text = next(split_words(cmdl, reverse=1), '')
3396
+ return text.rpartition('.') # -> text, sep, hint
3397
+
3361
3398
  def call_history_comp(self, evt):
3362
3399
  """Called when history-comp mode."""
3363
3400
  if not self.CanEdit():
@@ -3394,16 +3431,12 @@ class Nautilus(Shell, EditorInterface):
3394
3431
  return
3395
3432
  try:
3396
3433
  cmdl = self.cmdlc
3397
- hint = self.get_last_hint(cmdl)
3434
+ hint = self._get_last_hint(cmdl)
3398
3435
 
3399
3436
  ls = [x for x in self.fragmwords if x.startswith(hint)] # case-sensitive match
3400
3437
  words = sorted(ls, key=lambda s:s.upper())
3401
3438
 
3402
- self.__comp_ind = 0 if words else -1
3403
- self.__comp_hint = hint
3404
- self.__comp_words = words
3405
-
3406
- self.gen_autocomp(len(hint), words)
3439
+ self._gen_autocomp(-1, hint, words)
3407
3440
  self.message("[text] {} candidates matched"
3408
3441
  " with {!r}".format(len(words), hint))
3409
3442
  except Exception:
@@ -3416,26 +3449,24 @@ class Nautilus(Shell, EditorInterface):
3416
3449
  return
3417
3450
 
3418
3451
  def _continue(hints):
3419
- if hints.endswith(' ') and not force: # 'x, y |'
3420
- return
3421
- h = hints.strip()
3422
- if (not h or h.endswith(',')) and not force: # 'x, y,|'
3423
- return
3424
- lh = h.split(',')[-1] # 'x, y, z|' last hint after ','
3425
- if len(lh.split()) > 1: # 'x, y as|' contains a space before 'as'
3426
- return
3427
- return lh
3428
-
3452
+ if not hints.endswith(' '):
3453
+ h = hints.strip()
3454
+ if not h.endswith(','):
3455
+ lh = h.split(',')[-1].strip() # 'x, y, z|' last hint after ','
3456
+ if ' ' not in lh: # 'x, y as|' contains no spaces.
3457
+ return lh
3429
3458
  try:
3430
3459
  cmdl = self.cmdlc
3431
- hint = self.get_last_hint(cmdl)
3460
+ hint = self._get_last_hint(cmdl)
3432
3461
 
3433
- m = re.match(r"from\s+([\w.]+)\s+import\s+(.*)", cmdl)
3434
- if m:
3462
+ if (m := re.match(r"from\s+([\w.]+)\s+import\s+(.*)", cmdl)):
3435
3463
  text, hints = m.groups()
3436
- if not _continue(hints):
3464
+ if not _continue(hints) and not force:
3437
3465
  self.message("[module]>>> waiting for key input...")
3438
3466
  return
3467
+ elif hints.endswith('.'):
3468
+ self.message("[module] invalid import syntax.")
3469
+ return
3439
3470
  if text not in sys.modules:
3440
3471
  self.message("[module]>>> loading {}...".format(text))
3441
3472
  try:
@@ -3444,25 +3475,20 @@ class Nautilus(Shell, EditorInterface):
3444
3475
  self.message("\b failed: {}".format(e))
3445
3476
  return
3446
3477
  ## Add unimported module names.
3447
- keys = [x[len(text)+1:] for x in self.modules if x.startswith(f"{text}.{hint}")]
3478
+ p = "{}.{}".format(text, hint)
3479
+ keys = [x[len(text)+1:] for x in self.modules if x.startswith(p)]
3448
3480
  modules.update(k for k in keys if '.' not in k)
3481
+
3482
+ elif (m := re.match(r"(import|from)\s+(.*)", cmdl)):
3483
+ text, hints = m.groups()
3484
+ if not _continue(hints) and not force:
3485
+ self.message("[module]>>> waiting for key input...")
3486
+ return
3487
+ modules = self.modules
3449
3488
  else:
3450
- m = re.match(r"(import|from)\s+(.*)", cmdl)
3451
- if m:
3452
- text, hints = m.groups()
3453
- if not _continue(hints):
3454
- self.message("[module]>>> waiting for key input...")
3455
- return
3456
- modules = self.modules
3457
- else:
3458
- text, sep, hint = self.get_words_hint(cmdl)
3459
- if not text:
3460
- return
3461
- obj = self.eval(text)
3462
- if not hasattr(obj, '__dict__'):
3463
- self.message("[module] primitive object: {}".format(obj))
3464
- return
3465
- modules = set(k for k, v in vars(obj).items() if inspect.ismodule(v))
3489
+ text, sep, hint = self._get_words_hint(cmdl)
3490
+ obj = self.eval(text)
3491
+ modules = set(k for k, v in vars(obj).items() if inspect.ismodule(v))
3466
3492
 
3467
3493
  P = re.compile(hint)
3468
3494
  p = re.compile(hint, re.I)
@@ -3471,11 +3497,7 @@ class Nautilus(Shell, EditorInterface):
3471
3497
  j = next((k for k, w in enumerate(words) if P.match(w)),
3472
3498
  next((k for k, w in enumerate(words) if p.match(w)), -1))
3473
3499
 
3474
- self.__comp_ind = j
3475
- self.__comp_hint = hint
3476
- self.__comp_words = words
3477
-
3478
- self.gen_autocomp(len(hint), words)
3500
+ self._gen_autocomp(j, hint, words)
3479
3501
  self.message("[module] {} candidates matched"
3480
3502
  " with {!r} in {}".format(len(words), hint, text))
3481
3503
  except re.error as e:
@@ -3483,8 +3505,8 @@ class Nautilus(Shell, EditorInterface):
3483
3505
  except SyntaxError as e:
3484
3506
  self.handler('quit', evt)
3485
3507
  self.message("- {} : {!r}".format(e, text))
3486
- except Exception:
3487
- raise
3508
+ except Exception as e:
3509
+ self.message("- {} : {!r}".format(e, text))
3488
3510
 
3489
3511
  def call_word_autocomp(self, evt):
3490
3512
  """Called when word-comp mode."""
@@ -3492,7 +3514,7 @@ class Nautilus(Shell, EditorInterface):
3492
3514
  self.handler('quit', evt)
3493
3515
  return
3494
3516
  try:
3495
- text, sep, hint = self.get_words_hint(self.cmdlc)
3517
+ text, sep, hint = self._get_words_hint(self.cmdlc)
3496
3518
  obj = self.eval(text)
3497
3519
 
3498
3520
  P = re.compile(hint)
@@ -3502,11 +3524,7 @@ class Nautilus(Shell, EditorInterface):
3502
3524
  j = next((k for k, w in enumerate(words) if P.match(w)),
3503
3525
  next((k for k, w in enumerate(words) if p.match(w)), -1))
3504
3526
 
3505
- self.__comp_ind = j
3506
- self.__comp_hint = hint
3507
- self.__comp_words = words
3508
-
3509
- self.gen_autocomp(len(hint), words)
3527
+ self._gen_autocomp(j, hint, words)
3510
3528
  self.message("[word] {} candidates matched"
3511
3529
  " with {!r} in {}".format(len(words), hint, text))
3512
3530
  except re.error as e:
@@ -3523,7 +3541,7 @@ class Nautilus(Shell, EditorInterface):
3523
3541
  self.handler('quit', evt)
3524
3542
  return
3525
3543
  try:
3526
- text, sep, hint = self.get_words_hint(self.cmdlc)
3544
+ text, sep, hint = self._get_words_hint(self.cmdlc)
3527
3545
  obj = self.eval(text)
3528
3546
 
3529
3547
  P = re.compile(hint)
@@ -3533,11 +3551,7 @@ class Nautilus(Shell, EditorInterface):
3533
3551
  j = next((k for k, w in enumerate(words) if P.match(w)),
3534
3552
  next((k for k, w in enumerate(words) if p.match(w)), -1))
3535
3553
 
3536
- self.__comp_ind = j
3537
- self.__comp_hint = hint
3538
- self.__comp_words = words
3539
-
3540
- self.gen_autocomp(len(hint), words)
3554
+ self._gen_autocomp(j, hint, words)
3541
3555
  self.message("[apropos] {} candidates matched"
3542
3556
  " with {!r} in {}".format(len(words), hint, text))
3543
3557
  except re.error as e:
@@ -3547,12 +3561,3 @@ class Nautilus(Shell, EditorInterface):
3547
3561
  self.message("- {} : {!r}".format(e, text))
3548
3562
  except Exception as e:
3549
3563
  self.message("- {} : {!r}".format(e, text))
3550
-
3551
- @staticmethod
3552
- def get_last_hint(cmdl):
3553
- return re.search(r"[\w.]*$", cmdl).group(0) # or ''
3554
-
3555
- @staticmethod
3556
- def get_words_hint(cmdl):
3557
- text = next(split_words(cmdl, reverse=1), '')
3558
- return text.rpartition('.') # -> text, sep, hint
mwx/wxpdb.py CHANGED
@@ -246,7 +246,7 @@ class Debugger(Pdb):
246
246
  self.set_quit()
247
247
  return
248
248
 
249
- def run(self, cmd):
249
+ def run(self, cmd, filename="<string>"):
250
250
  """Debug a statement executed via the exec() function.
251
251
  """
252
252
  if self.busy:
@@ -257,10 +257,11 @@ class Debugger(Pdb):
257
257
  globals = self.interactive_shell.globals
258
258
  locals = self.interactive_shell.locals
259
259
  if isinstance(cmd, str):
260
- cmd = compile(cmd, "<string>", "exec")
260
+ cmd = compile(cmd, filename, "exec")
261
261
  try:
262
262
  frame = inspect.currentframe().f_back
263
263
  self.set_trace(frame)
264
+ self.send_input('s')
264
265
  exec(cmd, globals, locals)
265
266
  except BdbQuit:
266
267
  pass
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.92.0
3
+ Version: 0.92.4
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
- Author: Kazuya O'moto <komoto@jeol.co.jp>
6
+ Author: Kazuya O'moto
7
7
  Author-email: komoto@jeol.co.jp
8
8
  License: MIT
9
9
  Classifier: License :: OSI Approved :: MIT License
@@ -1,23 +1,23 @@
1
1
  mwx/__init__.py,sha256=5B4YSOuijG1Uo5-FLtLHGB52Cp_F4vnN--4wGPBx7do,2398
2
- mwx/bookshelf.py,sha256=l0I3xO8BJVd_KOGFhGJsGc6Rf-k_OIWQEdfa-iTRnrI,6619
2
+ mwx/bookshelf.py,sha256=FrissUYdGXLABOzJmMaQU6GXvu6n_9DVW3d5wGwQzjM,6613
3
3
  mwx/controls.py,sha256=toNAFJrPFDO7gb0aBU_IlW4AEIEvQJcwBxR-6e04IAc,46700
4
- mwx/framework.py,sha256=lOBTRsuVMgBHi8831rITsYa2IBiMRFxWDzzfmehfSuM,74619
5
- mwx/graphman.py,sha256=o5NRKFYZdoDV1qN5FlLARBXK2QTk0KnK-3wuY1nvoV8,69768
4
+ mwx/framework.py,sha256=8r98-kYiW2JTk2gfDLLXbB7Qq9hkecRsNEDtauyj9qc,74895
5
+ mwx/graphman.py,sha256=PBocTQpWa-f8P5-UV2Ugd01qKCGwFe-rZiginNKu_sI,69738
6
6
  mwx/images.py,sha256=mrnUYH12I3XLVSZcEXlpVltX0XMxufbl2yRvDIQJZqc,49957
7
7
  mwx/matplot2.py,sha256=TM8V5Ggc5iL9lYyM6V4clqH_vIsgS0GsND2ay9zuT0c,32825
8
- mwx/matplot2g.py,sha256=Il_vJV7XmZcCD3GOGfKztehFY3XB35n899iuumB7qXc,65575
8
+ mwx/matplot2g.py,sha256=owNKt2EcSkf15hYqx9lnpF9qT-WqdSkXSRsH82sYMTs,65571
9
9
  mwx/matplot2lg.py,sha256=IHURrul9JzcLO8Lyll1bW1G215pxgvutDmbQgayG70A,26341
10
10
  mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
11
- mwx/nutshell.py,sha256=FOpnjzs9eODIx419q5YM8UV7B6O19PoF6NjHdUYHCAQ,135812
11
+ mwx/nutshell.py,sha256=deb8JHotpLwTIP8715ux5mzOx-cnefteweUAZh0s-fU,136115
12
12
  mwx/utilus.py,sha256=fqxJysHXdLt9OOSKDZnBOwmbHvHJPy1qH3R6dI3NLSw,36947
13
13
  mwx/wxmon.py,sha256=Qk86VbuuW2rR46pqEYLur13G_aloWz5SVv6sib30YY0,12717
14
- mwx/wxpdb.py,sha256=hh3a9rHL5CjQh_2lMMonmZLJKv3RHNgtP4U_VLGbQnM,19411
14
+ mwx/wxpdb.py,sha256=rx_h4EiLEnHbVu2S6VfhWow7NwLAiTAXKiItY4N2qsk,19464
15
15
  mwx/wxwil.py,sha256=KdNaHV-5-fYSFN4h3VxXxdgpB6s5PCpuxkSbytg85eE,5586
16
16
  mwx/wxwit.py,sha256=2gFHi-8nwWRh26RdvZ_AUP--8PDjJB8TUU72y2fBUWM,7557
17
17
  mwx/py/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  mwx/py/filling.py,sha256=KaHooM32hrGGgqw75Cbt8lAvACwC6RXadob9LGgNnEc,16806
19
- mwxlib-0.92.0.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
20
- mwxlib-0.92.0.dist-info/METADATA,sha256=tvDpQGj_EfIvXRPvTjR8faEVsPHukhWIAL5N7u4lOrM,1945
21
- mwxlib-0.92.0.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
22
- mwxlib-0.92.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
23
- mwxlib-0.92.0.dist-info/RECORD,,
19
+ mwxlib-0.92.4.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
20
+ mwxlib-0.92.4.dist-info/METADATA,sha256=vt9uGOpka_Xhh-1QCZ3JPEMBPcV7B1QvBnKXdPv3_Sk,1925
21
+ mwxlib-0.92.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
22
+ mwxlib-0.92.4.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
23
+ mwxlib-0.92.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.3)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5