mwxlib 1.4.20__py3-none-any.whl → 1.5.0__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/framework.py CHANGED
@@ -1,7 +1,7 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "1.4.20"
4
+ __version__ = "1.5.0"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
mwx/graphman.py CHANGED
@@ -100,8 +100,6 @@ class Thread:
100
100
  None : {
101
101
  'thread_begin' : [ None ], # begin processing
102
102
  'thread_end' : [ None ], # end processing
103
- 'thread_quit' : [ None ], # terminated by user
104
- 'thread_error' : [ None ], # failed in error
105
103
  },
106
104
  })
107
105
 
@@ -117,7 +115,6 @@ class Thread:
117
115
  frame = inspect.currentframe().f_back.f_back
118
116
  filename = frame.f_code.co_filename
119
117
  name = frame.f_code.co_name
120
- fname, _ = os.path.splitext(os.path.basename(filename))
121
118
 
122
119
  ## Other threads are not allowed to enter.
123
120
  ct = threading.current_thread()
@@ -125,17 +122,18 @@ class Thread:
125
122
 
126
123
  ## The thread must be activated to enter.
127
124
  ## assert self.active, f"{self!r} must be activated to enter {name!r}."
128
- try:
129
- self.handler(f"{fname}/{name}:enter", self)
130
- yield self
131
- except Exception:
132
- self.handler(f"{fname}/{name}:error", self)
133
- raise
134
- finally:
135
- self.handler(f"{fname}/{name}:exit", self)
125
+ yield self
126
+
127
+ def enters(self, f):
128
+ """Decorator to register a one-time handler for the enter event."""
129
+ return self.handler.binds('thread_begin', f)
130
+
131
+ def exits(self, f):
132
+ """Decorator to register a one-time handler for the exit event."""
133
+ return self.handler.binds('thread_end', f)
136
134
 
137
135
  def wraps(self, f, *args, **kwargs):
138
- """Decorator of thread starter function."""
136
+ """Decorator for a function that starts a new thread."""
139
137
  @wraps(f)
140
138
  def _f(*v, **kw):
141
139
  return self.Start(f, *v, *args, **kw, **kwargs)
@@ -186,21 +184,20 @@ class Thread:
186
184
  @wraps(f)
187
185
  def _f(*v, **kw):
188
186
  try:
189
- self.handler('thread_begin', self)
187
+ wx.CallAfter(self.handler, 'thread_begin', self)
190
188
  self.result = f(*v, **kw)
191
189
  except BdbQuit:
192
190
  pass
193
191
  except KeyboardInterrupt as e:
194
- print("- Thread execution stopped:", e)
195
- except AssertionError as e:
196
- print("- Thread execution failed:", e)
192
+ print("- Thread terminated by user:", e)
193
+ ## wx.CallAfter(self.handler, 'thread_quit', self)
197
194
  except Exception as e:
198
195
  traceback.print_exc()
199
- print("- Thread exception:", e)
200
- self.handler('thread_error', self)
196
+ print("- Thread failed in error:", e)
197
+ ## wx.CallAfter(self.handler, 'thread_error', self)
201
198
  finally:
202
199
  self.active = 0
203
- self.handler('thread_end', self)
200
+ wx.CallAfter(self.handler, 'thread_end', self)
204
201
 
205
202
  if self.running:
206
203
  wx.MessageBox("The thread is running (Press [C-g] to quit).",
@@ -226,7 +223,6 @@ class Thread:
226
223
  def _stop():
227
224
  with wx.BusyInfo("One moment please, "
228
225
  "waiting for threads to die..."):
229
- self.handler('thread_quit', self)
230
226
  self.worker.join(1)
231
227
  if self.running:
232
228
  self.active = 0
@@ -349,10 +345,6 @@ class LayerInterface(CtrlInterface):
349
345
 
350
346
  self.handler.append({ # DNA<Layer>
351
347
  None : {
352
- 'thread_begin' : [ None ], # begin processing
353
- 'thread_end' : [ None ], # end processing
354
- 'thread_quit' : [ None ], # terminated by user
355
- 'thread_error' : [ None ], # failed in error
356
348
  'page_shown' : [ None, _F(self.Draw, show=True) ],
357
349
  'page_closed' : [ None, _F(self.Draw, show=False) ],
358
350
  'page_hidden' : [ None, _F(self.Draw, show=False) ],
mwx/nutshell.py CHANGED
@@ -1453,21 +1453,6 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1453
1453
  def grep(self, pattern, flags=re.M):
1454
1454
  yield from re.finditer(pattern.encode(), self.TextRaw, flags)
1455
1455
 
1456
- def search_text(self, text, mode=True):
1457
- """Yields positions where `text` is found.
1458
- If mode is True, search by word; otherwise, search by string.
1459
- """
1460
- text = text.encode()
1461
- pos = -1
1462
- p = re.compile(r"[a-zA-Z0-9_]")
1463
- while 1:
1464
- pos = self.TextRaw.find(text, pos+1)
1465
- if pos < 0:
1466
- break
1467
- if mode and p.search(self.get_char(pos-1) + self.get_char(pos+len(text))):
1468
- continue
1469
- yield pos
1470
-
1471
1456
  def filter_text(self):
1472
1457
  """Show indicators for the selected text."""
1473
1458
  self.__itextlines = []
@@ -1479,13 +1464,16 @@ class EditorInterface(AutoCompInterfaceMixin, CtrlInterface):
1479
1464
  self.message("No words")
1480
1465
  return
1481
1466
  wholeword = (not self.SelectedText) # Enable or disable whole word search.
1482
- lw = len(text.encode())
1467
+ pattern = re.escape(text)
1468
+ if wholeword:
1469
+ pattern = rf"\b{pattern}\b"
1483
1470
  lines = []
1484
- for p in self.search_text(text, wholeword):
1471
+ for m in self.grep(pattern):
1472
+ p, q = m.span()
1485
1473
  lines.append(self.LineFromPosition(p))
1486
1474
  for i in (10, 11,):
1487
1475
  self.SetIndicatorCurrent(i)
1488
- self.IndicatorFillRange(p, lw)
1476
+ self.IndicatorFillRange(p, q-p)
1489
1477
  self.__itextlines = sorted(set(lines)) # keep order, no duplication
1490
1478
  self.message("{}: {} found".format(text, len(lines)))
1491
1479
  try:
mwx/utilus.py CHANGED
@@ -826,6 +826,22 @@ class FSM(dict):
826
826
  f" The transaction must be a list, not a tuple.")
827
827
  return action
828
828
 
829
+ def binds(self, event, action=None, state=None, state2=None):
830
+ """Append a one-time transaction to the context.
831
+
832
+ Like `bind`, but unbinds itself after being called once.
833
+ """
834
+ if action is None:
835
+ return lambda f: self.binds(event, f, state, state2)
836
+
837
+ @wraps(action)
838
+ def _act(*v, **kw):
839
+ try:
840
+ return action(*v, **kw)
841
+ finally:
842
+ self.unbind(event, _act, state)
843
+ return self.bind(event, _act, state, state2)
844
+
829
845
  def unbind(self, event, action=None, state=None):
830
846
  """Remove a transaction from the context.
831
847
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mwxlib
3
- Version: 1.4.20
3
+ Version: 1.5.0
4
4
  Summary: A wrapper of matplotlib and wxPython (phoenix)
5
5
  Home-page: https://github.com/komoto48g/mwxlib
6
6
  Author: Kazuya O'moto
@@ -1,16 +1,16 @@
1
1
  mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
2
2
  mwx/bookshelf.py,sha256=XbJ9HUH5COUm-BVI7iLC7gr9Hj9l-sFjOoaCAqNS4aA,8178
3
3
  mwx/controls.py,sha256=cgYEeBn1GD1s2YrDZd3jzhlACTc9IOZED_JOA8dqTJI,49914
4
- mwx/framework.py,sha256=D1KILJNmv-eQ0HY8ayphIA_Fd9K19d6jHA5q27fp61M,77031
5
- mwx/graphman.py,sha256=sb9Y2z5bW30arFxQnOoMhjxILNUdnAZsDh9rNbY_IPI,70037
4
+ mwx/framework.py,sha256=f5xAUMR05Y1Y_f1SDhZySOxGsfTcmW4H2JT2vHdfAg4,77030
5
+ mwx/graphman.py,sha256=xYaBzPZlA1OJ2suk29CEtVMGJJZd1krHwjXnyxThyuo,69643
6
6
  mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
7
7
  mwx/matplot2.py,sha256=U0axLQeZAR_ys5rXHykVKkvXLibnNwXS-gm-c0U2MGw,33003
8
8
  mwx/matplot2g.py,sha256=foq-NdksvTV_I55UGxLzghp1YXaFfWgzTmigmnIe58E,65376
9
9
  mwx/matplot2lg.py,sha256=cb0EZXivccDQu4oFj5ddSUF9pEE4f5UuFJJK2ELItww,27404
10
10
  mwx/mgplt.py,sha256=KR7MWdl9J6hiiBdO0NB25Y37rP21aFdwBVsB9KZKXo8,5564
11
- mwx/nutshell.py,sha256=sAvHbrD9V4lMaeX_h_r8e5VYnhAe47GMRaRzoNJmtV0,146629
11
+ mwx/nutshell.py,sha256=ELpFChIZR4GgR8dyphqvrsJtgTDBGoQRaw7_F_1VDNc,146181
12
12
  mwx/testsuite.py,sha256=Zk75onPSEn2tf0swS3l-vIn6yTXGB7allIyvJsPHj20,1229
13
- mwx/utilus.py,sha256=ZcKEkY2jR9pvf0bDFXyKk2Z7dDBf-NW84tDPiBlWdic,38081
13
+ mwx/utilus.py,sha256=vu-gzLabGEaY6wAN3ThJrmjTChlZtoKYozSF0om_MOk,38642
14
14
  mwx/wxmon.py,sha256=NIksW_CZv7Kw4dod8tWVwakO4iJuvE8hJSAcjkYfLaE,12800
15
15
  mwx/wxpdb.py,sha256=aZIH7Xs-9ahDLut2P4NmvbB2zHVpI95kx4je1ophNQM,18799
16
16
  mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
@@ -22,7 +22,7 @@ mwx/plugins/frame_listview.py,sha256=xH1au3lI-bZwCzmhVmvNTOHDoVQIBzH4p9_8Y36Qs5U
22
22
  mwx/plugins/line_profile.py,sha256=zzm6_7lnAnNepLbh07ordp3nRWDFQJtu719ZVjrVf8s,819
23
23
  mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
24
24
  mwx/py/filling.py,sha256=fumUG1F5M9TL-Dfqni4G85uk7TmvnUunTbdcPDV0vfo,16857
25
- mwxlib-1.4.20.dist-info/METADATA,sha256=4uLVWBcmszTutWuvX_2Sv3s4nynp2J6hEXRLo1O-uhU,7382
26
- mwxlib-1.4.20.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
27
- mwxlib-1.4.20.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.4.20.dist-info/RECORD,,
25
+ mwxlib-1.5.0.dist-info/METADATA,sha256=vbRM1kvarP86bPrshgFTy74zJ1U3NSvoEJhv6K_osHo,7381
26
+ mwxlib-1.5.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
27
+ mwxlib-1.5.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.5.0.dist-info/RECORD,,