mwxlib 1.5.9__py3-none-any.whl → 1.5.11__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.5.9"
4
+ __version__ = "1.5.11"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from contextlib import contextmanager
@@ -49,10 +49,6 @@ def deb(target=None, loop=True, locals=None, **kwargs):
49
49
  kwargs.setdefault("execStartupScript", True)
50
50
  kwargs.setdefault("standalone", True)
51
51
 
52
- if "debrc" in kwargs: # for backward compatibility
53
- warn("Deprecated keyword: 'debrc'. Use 'session' instead.", DeprecationWarning)
54
- kwargs.setdefault('session', kwargs.pop('debrc'))
55
-
56
52
  app = wx.GetApp() or wx.App()
57
53
  frame = ShellFrame(None, target, **kwargs)
58
54
  frame.Show()
mwx/graphman.py CHANGED
@@ -37,19 +37,6 @@ from .matplot2lg import LineProfile # noqa
37
37
  from .matplot2lg import Histogram
38
38
 
39
39
 
40
- def split_paths(obj):
41
- """Split obj path into dirname and basename.
42
- The object can be module name:str, module, or class.
43
- """
44
- if hasattr(obj, '__file__'): #<class 'module'>
45
- obj = obj.__file__
46
- elif isinstance(obj, type): #<class 'type'>
47
- obj = inspect.getsourcefile(obj)
48
- if obj.endswith(".py"):
49
- obj, _ = os.path.splitext(obj)
50
- return os.path.split(obj)
51
-
52
-
53
40
  class Thread:
54
41
  """Thread manager for graphman.Layer
55
42
 
@@ -194,13 +181,13 @@ class Thread:
194
181
  except KeyboardInterrupt as e:
195
182
  print("- Thread terminated by user:", e)
196
183
  except Exception as e:
184
+ print("- Thread failed in error:", e)
185
+ traceback.print_exc()
197
186
  tbstr = traceback.format_tb(e.__traceback__)
198
187
  wx.CallAfter(wx.MessageBox,
199
188
  f"{e}\n\n" + tbstr[-1] + f"{type(e).__name__}: {e}",
200
189
  f"Error in the thread running {f.__name__!r}\n\n",
201
190
  style=wx.ICON_ERROR)
202
- traceback.print_exc()
203
- print("- Thread failed in error:", e)
204
191
  finally:
205
192
  self.active = 0
206
193
  wx.CallAfter(self.handler, 'thread_end', self)
@@ -377,18 +364,18 @@ class LayerInterface(CtrlInterface):
377
364
  lambda v: reset_params(v, checked_only=wx.GetKeyState(wx.WXK_SHIFT)),
378
365
  lambda v: v.Enable(bool(self.parameters))),
379
366
  (),
380
- (mwx.ID_(201), "&Reload module", "Reload module", Icon('load'),
381
- lambda v: self.parent.reload_plug(self.__module__),
367
+ (mwx.ID_(201), "&Reload module", "Reload", Icon('load'),
368
+ lambda v: self.parent.reload_plug(self),
382
369
  lambda v: v.Enable(self.reloadable
383
370
  and not (self.thread and self.thread.active))),
384
371
 
385
- (mwx.ID_(202), "&Unload module", "Unload module", Icon('delete'),
386
- lambda v: self.parent.unload_plug(self.__module__),
372
+ (mwx.ID_(202), "&Unload module", "Unload", Icon('delete'),
373
+ lambda v: self.parent.unload_plug(self),
387
374
  lambda v: v.Enable(self.unloadable
388
375
  and not (self.thread and self.thread.active))),
389
376
  (),
390
377
  (mwx.ID_(203), "&Dive into {!r}".format(self.__module__), "dive", Icon('core'),
391
- lambda v: self.parent.inspect_plug(self.__module__)),
378
+ lambda v: self.parent.inspect_plug(self)),
392
379
  ]
393
380
  self.Bind(wx.EVT_CONTEXT_MENU,
394
381
  lambda v: Menu.Popup(self, self.menu))
@@ -399,7 +386,7 @@ class LayerInterface(CtrlInterface):
399
386
  try:
400
387
  self.Init()
401
388
  except Exception as e:
402
- traceback.print_exc()
389
+ traceback.print_exc() # Failed to initialize the plug.
403
390
  if parent:
404
391
  bmp = wx.StaticBitmap(self, bitmap=Icon('!!!'))
405
392
  txt = wx.StaticText(self, label="Exception")
@@ -409,8 +396,7 @@ class LayerInterface(CtrlInterface):
409
396
  if session:
410
397
  self.load_session(session)
411
398
  except Exception:
412
- traceback.print_exc()
413
- print("- Failed to load session of", self)
399
+ traceback.print_exc() # Failed to load the plug session.
414
400
 
415
401
  def Init(self):
416
402
  """Initialize layout before load_session (to be overridden)."""
@@ -1055,11 +1041,7 @@ class Frame(mwx.Frame):
1055
1041
  return plug
1056
1042
 
1057
1043
  def get_plug(self, name):
1058
- """Get named plug window.
1059
-
1060
- Args:
1061
- name : str or plug object.
1062
- """
1044
+ """Get named plug window."""
1063
1045
  if isinstance(name, str):
1064
1046
  if name.endswith(".py"):
1065
1047
  name, _ = os.path.splitext(os.path.basename(name))
@@ -1068,47 +1050,6 @@ class Frame(mwx.Frame):
1068
1050
  elif isinstance(name, LayerInterface):
1069
1051
  return name
1070
1052
 
1071
- def load_module(self, root):
1072
- """Load module of plugin (internal use only).
1073
-
1074
- Note:
1075
- This is called automatically from load_plug,
1076
- and should not be called directly from user.
1077
- """
1078
- dirname_, name = split_paths(root)
1079
-
1080
- ## Update the include-path to load the module correctly.
1081
- if os.path.isdir(dirname_):
1082
- if dirname_ in sys.path:
1083
- sys.path.remove(dirname_)
1084
- sys.path.insert(0, dirname_)
1085
- elif dirname_:
1086
- print("- No such directory {!r}".format(dirname_))
1087
- return False
1088
-
1089
- try:
1090
- if name in sys.modules:
1091
- module = reload(sys.modules[name])
1092
- else:
1093
- module = import_module(name)
1094
- except Exception as e:
1095
- traceback.print_exc()
1096
- print(f"- Unable to load {root!r}.", e)
1097
- return False
1098
-
1099
- ## Check if the module has a class `Plugin`.
1100
- if not hasattr(module, 'Plugin'):
1101
- if isinstance(root, type):
1102
- warn(f"Use dummy plug for debugging {name!r}.")
1103
- module.__dummy_plug__ = root
1104
- register(root, module)
1105
- else:
1106
- if hasattr(module, '__dummy_plug__'):
1107
- root = module.__dummy_plug__ # old class (imported)
1108
- cls = getattr(module, root.__name__) # new class (reloaded)
1109
- register(cls, module)
1110
- return module
1111
-
1112
1053
  def load_plug(self, root, force=False, session=None, show=False,
1113
1054
  dock=0, floating_pos=None, floating_size=None,
1114
1055
  **kwargs):
@@ -1131,14 +1072,23 @@ class Frame(mwx.Frame):
1131
1072
  None if succeeded else False
1132
1073
 
1133
1074
  Note:
1134
- The root module must have a class Plugin <Layer>
1075
+ The root module must contain a class Plugin <Layer>.
1135
1076
  """
1136
1077
  props = dict(dock_direction=dock,
1137
1078
  floating_pos=floating_pos,
1138
1079
  floating_size=floating_size)
1139
1080
 
1140
- _dirname, name = split_paths(root)
1081
+ if inspect.ismodule(root):
1082
+ name = root.__file__ # @TODO root.__name__
1083
+ elif inspect.isclass(root):
1084
+ name = inspect.getsourcefile(root)
1085
+ else:
1086
+ name = root
1087
+ dirname_, name = os.path.split(name) # if the name is full path,...
1088
+ if name.endswith(".py"):
1089
+ name = name[:-3]
1141
1090
 
1091
+ ## Check if the plug is already loaded or needs to be reloaded.
1142
1092
  plug = self.get_plug(name)
1143
1093
  if plug and not force:
1144
1094
  self.update_pane(name, **props)
@@ -1147,15 +1097,40 @@ class Frame(mwx.Frame):
1147
1097
  if session:
1148
1098
  plug.load_session(session)
1149
1099
  except Exception:
1150
- traceback.print_exc()
1151
- print("- Failed to load session of", plug)
1100
+ traceback.print_exc() # Failed to load the plug session.
1152
1101
  return None
1153
1102
 
1154
- module = self.load_module(root)
1155
- if not module:
1103
+ ## Update the include-path to load the module correctly.
1104
+ if os.path.isdir(dirname_):
1105
+ if dirname_ in sys.path:
1106
+ sys.path.remove(dirname_)
1107
+ sys.path.insert(0, dirname_)
1108
+ elif dirname_:
1109
+ print(f"- No such directory {dirname_!r}.")
1110
+ return False
1111
+
1112
+ ## Load or reload the root module, and check whether it contains a class named `Plugin`.
1113
+ try:
1114
+ if name in sys.modules:
1115
+ module = reload(sys.modules[name])
1116
+ else:
1117
+ module = import_module(name)
1118
+ except Exception:
1119
+ traceback.print_exc() # Unable to load the module.
1156
1120
  return False
1121
+ else:
1122
+ if not hasattr(module, 'Plugin'):
1123
+ if isinstance(root, type):
1124
+ ## warn(f"Use dummy plug for {name!r}.")
1125
+ module.__dummy_plug__ = root
1126
+ register(root, module)
1127
+ else:
1128
+ if hasattr(module, '__dummy_plug__'):
1129
+ root = module.__dummy_plug__ # old class (imported)
1130
+ cls = getattr(module, root.__name__) # new class (reloaded)
1131
+ register(cls, module)
1157
1132
 
1158
- ## assert name == Plugin.__module__
1133
+ ## Note: name (module.__name__) != Plugin.__module__ if module is a package.
1159
1134
  try:
1160
1135
  Plugin = module.Plugin # Check if the module has a class `Plugin`.
1161
1136
  title = Plugin.category # Plugin <LayerInterface>
@@ -1271,13 +1246,10 @@ class Frame(mwx.Frame):
1271
1246
  """Unload plugin and detach the pane from UI manager."""
1272
1247
  plug = self.get_plug(name)
1273
1248
  if not plug:
1249
+ print(f"- {name!r} is not listed in plugins.")
1274
1250
  return
1275
1251
 
1276
- name = plug.__module__
1277
- if name not in self.plugins:
1278
- return
1279
-
1280
- del self.plugins[name]
1252
+ del self.plugins[plug.Name]
1281
1253
 
1282
1254
  if plug.__Menu_item:
1283
1255
  menu, sep, tail = plug.menukey.rpartition('/')
@@ -1304,23 +1276,28 @@ class Frame(mwx.Frame):
1304
1276
  nb.Destroy()
1305
1277
 
1306
1278
  def reload_plug(self, name):
1279
+ """Reload plugin."""
1307
1280
  plug = self.get_plug(name)
1308
- if not plug or not plug.reloadable:
1281
+ if not plug:
1282
+ print(f"- {name!r} is not listed in plugins.")
1309
1283
  return
1284
+ if not plug.reloadable:
1285
+ print(f"- {name!r} is not reloadable.")
1286
+ return
1287
+
1310
1288
  session = {}
1311
1289
  try:
1312
1290
  print("Reloading {}...".format(plug))
1313
1291
  plug.save_session(session)
1314
1292
  except Exception:
1315
- traceback.print_exc()
1316
- print("- Failed to save session of", plug)
1293
+ traceback.print_exc() # Failed to save the plug session.
1317
1294
  self.load_plug(plug.__module__, force=1, session=session)
1318
1295
 
1319
1296
  def inspect_plug(self, name):
1320
- """Dive into the process to inspect plugs in the shell.
1321
- """
1297
+ """Dive into the process to inspect plugs in the shell."""
1322
1298
  plug = self.get_plug(name)
1323
1299
  if not plug:
1300
+ print(f"- {name!r} is not listed in plugins.")
1324
1301
  return
1325
1302
 
1326
1303
  shell = self.shellframe.clone_shell(plug)
@@ -1713,7 +1690,7 @@ class Frame(mwx.Frame):
1713
1690
  filename = dlg.Path
1714
1691
 
1715
1692
  if flush:
1716
- for name in list(self.plugins): # plugins:dict mutates during iteration
1693
+ for name in list(self.plugins): # plugins:dict mutates during iteration
1717
1694
  self.unload_plug(name)
1718
1695
  del self.graph[:]
1719
1696
  del self.output[:]
@@ -1767,24 +1744,23 @@ class Frame(mwx.Frame):
1767
1744
  self.message("Saving session to {!r}...".format(self.session_file))
1768
1745
 
1769
1746
  with open(self.session_file, 'w') as o,\
1770
- np.printoptions(threshold=np.inf): # printing all(inf) elements
1747
+ np.printoptions(threshold=np.inf): # printing all(inf) elements
1771
1748
  o.write("#! Session file (This file is generated automatically)\n")
1772
1749
  o.write("self.SetSize({})\n".format(self.Size))
1773
1750
  o.write("self.SetPosition({})\n".format(self.Position))
1774
1751
 
1775
1752
  for name, module in self.plugins.items():
1776
1753
  plug = self.get_plug(name)
1777
- path = os.path.abspath(module.__file__)
1778
- basename = os.path.basename(path)
1779
- if basename == "__init__.py": # is module package?
1780
- path = path[:-12]
1754
+ if '.' not in name:
1755
+ name = module.__file__ # Replace the name with full path.
1756
+ if hasattr(module, '__path__'): # is the module a package?
1757
+ name = os.path.dirname(name)
1781
1758
  session = {}
1782
1759
  try:
1783
1760
  plug.save_session(session)
1784
1761
  except Exception:
1785
- traceback.print_exc()
1786
- print("- Failed to save session of", plug)
1787
- o.write("self.load_plug({!r}, session={})\n".format(path, session or None))
1762
+ traceback.print_exc() # Failed to save the plug session.
1763
+ o.write("self.load_plug({!r}, session={})\n".format(name, session or None))
1788
1764
  o.write("self._mgr.LoadPerspective({!r})\n".format(self._mgr.SavePerspective()))
1789
1765
 
1790
1766
  def _save(view):
@@ -75,6 +75,10 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
75
75
  'C-a pressed' : (0, self.OnSelectAllItems),
76
76
  'C-o pressed' : (0, self.OnLoadItems),
77
77
  'C-s pressed' : (0, self.OnSaveItems),
78
+ 'C-S-s pressed' : (0, self.OnSaveItems),
79
+ 'C-c pressed' : (0, self.OnCopyInfo),
80
+ 'C-l pressed' : (0, self.OnEditLocalUnit),
81
+ 'f2 pressed' : (0, self.OnEditAnnotation),
78
82
  'M-up pressed' : (0, self.Target.OnPageUp),
79
83
  'M-down pressed' : (0, self.Target.OnPageDown),
80
84
  },
@@ -98,7 +102,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
98
102
 
99
103
  self.menu = [
100
104
  (100, "Edit localunit", Icon('image'),
101
- self.OnEditUnit,
105
+ self.OnEditLocalUnit,
102
106
  lambda v: v.Enable(self.focused_item != -1)),
103
107
 
104
108
  (101, "Edit annotation", Icon('pencil'),
@@ -181,20 +185,20 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
181
185
  def OnCopyInfo(self, evt):
182
186
  selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
183
187
  if selected_frames:
184
- text = ''
188
+ text = []
185
189
  for frame in selected_frames:
186
- text += pformat(frame.attributes, sort_dicts=0) # ALL attributes
187
- ## text += '{}\n{}\n'.format(frame.name, frame.annotation)
188
- Clipboard.write(text)
190
+ text += [pformat(frame.attributes, sort_dicts=0)] # ALL attributes
191
+ Clipboard.write('\n'.join(text))
189
192
  else:
190
193
  self.parent.message("No frame selected.")
191
194
 
192
- def OnEditUnit(self, evt):
195
+ def OnEditLocalUnit(self, evt):
193
196
  frame = self.Target.all_frames[self.focused_item]
194
197
  with wx.TextEntryDialog(self, frame.name,
195
198
  'Enter localunit', repr(frame.localunit)) as dlg:
196
199
  if dlg.ShowModal() == wx.ID_OK:
197
200
  frame.unit = eval(dlg.Value or 'None')
201
+ self.SetFocus()
198
202
 
199
203
  def OnEditAnnotation(self, evt):
200
204
  frame = self.Target.all_frames[self.focused_item]
@@ -202,6 +206,7 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
202
206
  'Enter an annotation', frame.annotation) as dlg:
203
207
  if dlg.ShowModal() == wx.ID_OK:
204
208
  frame.annotation = dlg.Value
209
+ self.SetFocus()
205
210
 
206
211
  def OnItemSelected(self, evt):
207
212
  frame = self.Target.all_frames[evt.Index]
mwx/utilus.py CHANGED
@@ -278,14 +278,14 @@ def pp(obj):
278
278
  pprint(obj, **pp.__dict__)
279
279
 
280
280
 
281
- if pp:
281
+ if 1:
282
282
  pp.indent = 1
283
283
  pp.width = 80 # default 80
284
284
  pp.depth = None
285
285
  if sys.version_info >= (3,6):
286
286
  pp.compact = False
287
287
  if sys.version_info >= (3,8):
288
- pp.sort_dicts = True
288
+ pp.sort_dicts = False
289
289
 
290
290
 
291
291
  def split_words(text, reverse=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mwxlib
3
- Version: 1.5.9
3
+ Version: 1.5.11
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,8 +1,8 @@
1
1
  mwx/__init__.py,sha256=pS7ZG8QKRypiFFiaWAq_opBB6I_1viZ0zUMk2TbjzE0,667
2
2
  mwx/bookshelf.py,sha256=yW17nMNPXKHM7LLXLpr9DaRhyFHz_OBAZ_DsuEK2QzA,8387
3
3
  mwx/controls.py,sha256=Mpzpp2eWyS_X7RjxTJay1-Fldchk-x-rUBpUhHSG-5w,49924
4
- mwx/framework.py,sha256=Bgvh2fqP5oRE79H0NFU5n_bFVLaE1c8JYHEJ8SUuqfw,77784
5
- mwx/graphman.py,sha256=zaKfcWbj6YYg2GFj_ijiqLd44OORFVKOvbQwucxNpno,69894
4
+ mwx/framework.py,sha256=LRy4HZqH_JdGhVzKnfq9LxEyF24CDmzaQRzyJ5P53Us,77574
5
+ mwx/graphman.py,sha256=hixEmn8YAbmVLYjB_XRpyddKytlw8UJH32jm-fA1EKU,69601
6
6
  mwx/images.py,sha256=Kkfy9QI_hMtwShSjUS4-ZpC_EkVuah_XhpBOR4wAKkM,49792
7
7
  mwx/matplot2.py,sha256=5Z-m9KXtSXpzBQs3swqPbfl_mfVdDoPaWKqpiepfau8,33019
8
8
  mwx/matplot2g.py,sha256=hLBYWjXPc2jgtKPTQWCdieIegQvS4jjUUaedV4qDLoE,65255
@@ -10,7 +10,7 @@ mwx/matplot2lg.py,sha256=fpxOX18vonUTpA_nAr-wBhQ_2YNsL_nfxdCDliuP1sU,27430
10
10
  mwx/mgplt.py,sha256=SVUJ0ls4gC9xulbWxK2qqmDxf0uBCflvwoPkxoF5s3M,5566
11
11
  mwx/nutshell.py,sha256=CX-NK3kOEi3JHhjKh39R2_m1po1SvMxraaDk2xt6q-Y,147617
12
12
  mwx/testsuite.py,sha256=0Q_n_XOOsZ8lsLWUkuO8QW00hts9wEQfnUKMpf0BAyU,1235
13
- mwx/utilus.py,sha256=RiBKZLLnVqT-YrU3gFZ69eZAD25RaPARm2_fOGXG4cw,38964
13
+ mwx/utilus.py,sha256=YVU-2aR9_22-clA0OCFKfmW0c49uhNWdbQaNXxNKXxA,38964
14
14
  mwx/wxmon.py,sha256=NIksW_CZv7Kw4dod8tWVwakO4iJuvE8hJSAcjkYfLaE,12800
15
15
  mwx/wxpdb.py,sha256=kKzEGivjoZ9zGcB3ttYsAym4putyilmXZXj-5CGaivQ,18813
16
16
  mwx/wxwil.py,sha256=hhyB1lPrF9ixeObxCOKQv0Theu-B-kpJg_yVU3EGSNg,5406
@@ -18,11 +18,11 @@ mwx/wxwit.py,sha256=mTH92bWw1F3ycaq4EoxVD_4hIxy2fbKZZbQg3f1ZD1Y,7350
18
18
  mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
19
19
  mwx/plugins/ffmpeg_view.py,sha256=GT3mAP7cvAgkzHyA0Em_FP8wiWS-dRekUyBgaXIBQCc,10982
20
20
  mwx/plugins/fft_view.py,sha256=Hsho8y-42hG3htQAJ9ct1347NHJ8qPvN4snq_1jYOxw,2793
21
- mwx/plugins/frame_listview.py,sha256=q-8CrWPovgkEe4ICESfdRUDfAWJYoriElufuAcyu30U,10380
21
+ mwx/plugins/frame_listview.py,sha256=yd2NCgspqGfTNhj1wxuW8r1zapIm7vNzVX2iytk8CDM,10618
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.5.9.dist-info/METADATA,sha256=nOrVtH-e2vPfhgGbjSkhKVVF-E1i8Z3pyP-HryhUPhs,7381
26
- mwxlib-1.5.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- mwxlib-1.5.9.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.5.9.dist-info/RECORD,,
25
+ mwxlib-1.5.11.dist-info/METADATA,sha256=p669CmL2U7lNRmxUD2QMu286bsTCCQeOMUN990PNpqU,7382
26
+ mwxlib-1.5.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ mwxlib-1.5.11.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.5.11.dist-info/RECORD,,