mwxlib 1.5.10__py3-none-any.whl → 1.5.12__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.10"
4
+ __version__ = "1.5.12"
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 {!r}".format(self.__module__), "Reload", 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 {!r}".format(self.__module__), "Unload", 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)."""
@@ -583,8 +569,7 @@ class Graph(GraphPlot):
583
569
  del self.region
584
570
 
585
571
  def hide_layers(self):
586
- for name in self.parent.plugins:
587
- plug = self.parent.get_plug(name)
572
+ for plug in self.parent.get_all_plugs():
588
573
  for art in plug.Arts:
589
574
  art.set_visible(0)
590
575
  self.remove_markups()
@@ -895,8 +880,7 @@ class Frame(mwx.Frame):
895
880
  elif ret == wx.ID_CANCEL:
896
881
  evt.Veto()
897
882
  return
898
- n = sum(bool(plug.thread and plug.thread.active)
899
- for plug in (self.get_plug(name) for name in self.plugins))
883
+ n = sum(bool(plug.thread and plug.thread.active) for plug in self.get_all_plugs())
900
884
  if n:
901
885
  s = 's' if n > 1 else ''
902
886
  if wx.MessageBox( # Confirm closing the thread.
@@ -1055,11 +1039,7 @@ class Frame(mwx.Frame):
1055
1039
  return plug
1056
1040
 
1057
1041
  def get_plug(self, name):
1058
- """Get named plug window.
1059
-
1060
- Args:
1061
- name : str or plug object.
1062
- """
1042
+ """Get named plug window."""
1063
1043
  if isinstance(name, str):
1064
1044
  if name.endswith(".py"):
1065
1045
  name, _ = os.path.splitext(os.path.basename(name))
@@ -1068,46 +1048,9 @@ class Frame(mwx.Frame):
1068
1048
  elif isinstance(name, LayerInterface):
1069
1049
  return name
1070
1050
 
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
1051
+ def get_all_plugs(self):
1052
+ for name, module in self.plugins.items():
1053
+ yield module.__plug__
1111
1054
 
1112
1055
  def load_plug(self, root, force=False, session=None, show=False,
1113
1056
  dock=0, floating_pos=None, floating_size=None,
@@ -1131,31 +1074,72 @@ class Frame(mwx.Frame):
1131
1074
  None if succeeded else False
1132
1075
 
1133
1076
  Note:
1134
- The root module must have a class Plugin <Layer>
1077
+ The root module must contain a class Plugin <Layer>.
1135
1078
  """
1136
1079
  props = dict(dock_direction=dock,
1137
1080
  floating_pos=floating_pos,
1138
1081
  floating_size=floating_size)
1139
1082
 
1140
- _dirname, name = split_paths(root)
1083
+ if inspect.ismodule(root):
1084
+ name = root.__file__
1085
+ ## name = root.__name__ @TODO: Change root module name
1086
+ elif inspect.isclass(root):
1087
+ name = inspect.getsourcefile(root)
1088
+ else:
1089
+ name = root
1090
+ dirname_, name = os.path.split(name) # if the name is full path,...
1091
+ if name.endswith(".py"):
1092
+ name = name[:-3]
1093
+
1094
+ if not force:
1095
+ ## 文字列参照 (root:str) による重複ロードを避ける @TODO: Change root module name
1096
+ ## for mod in self.plugins.values():
1097
+ ## if root == mod.__file__:
1098
+ ## print(f"- {name!r} is already loaded as {mod.__name__!r}.")
1099
+ ## return None
1100
+ ## Check if the named plug is already loaded.
1101
+ plug = self.get_plug(name)
1102
+ if plug:
1103
+ self.update_pane(name, **props)
1104
+ self.show_pane(name, show)
1105
+ try:
1106
+ if session:
1107
+ plug.load_session(session)
1108
+ except Exception:
1109
+ traceback.print_exc() # Failed to load the plug session.
1110
+ return None
1141
1111
 
1142
- plug = self.get_plug(name)
1143
- if plug and not force:
1144
- self.update_pane(name, **props)
1145
- self.show_pane(name, show)
1146
- try:
1147
- if session:
1148
- plug.load_session(session)
1149
- except Exception:
1150
- traceback.print_exc()
1151
- print("- Failed to load session of", plug)
1152
- return None
1112
+ ## Update the include-path to load the module correctly.
1113
+ if os.path.isdir(dirname_):
1114
+ if dirname_ in sys.path:
1115
+ sys.path.remove(dirname_)
1116
+ sys.path.insert(0, dirname_)
1117
+ elif dirname_:
1118
+ print(f"- No such directory {dirname_!r}.")
1119
+ return False
1153
1120
 
1154
- module = self.load_module(root)
1155
- if not module:
1121
+ ## Load or reload the module, and check whether it contains a class named `Plugin`.
1122
+ try:
1123
+ if name in sys.modules:
1124
+ module = reload(sys.modules[name])
1125
+ else:
1126
+ module = import_module(name)
1127
+ except Exception:
1128
+ traceback.print_exc() # Unable to load the module.
1156
1129
  return False
1130
+ else:
1131
+ if not hasattr(module, 'Plugin'):
1132
+ if isinstance(root, type):
1133
+ ## warn(f"Use dummy plug for {name!r}.")
1134
+ module.__dummy_plug__ = root
1135
+ register(root, module)
1136
+ else:
1137
+ if hasattr(module, '__dummy_plug__'):
1138
+ root = module.__dummy_plug__ # old class (imported)
1139
+ cls = getattr(module, root.__name__) # new class (reloaded)
1140
+ register(cls, module)
1157
1141
 
1158
- ## assert name == Plugin.__module__
1142
+ ## Note: name (module.__name__) != Plugin.__module__ if module is a package.
1159
1143
  try:
1160
1144
  Plugin = module.Plugin # Check if the module has a class `Plugin`.
1161
1145
  title = Plugin.category # Plugin <LayerInterface>
@@ -1199,12 +1183,6 @@ class Frame(mwx.Frame):
1199
1183
  style=wx.ICON_ERROR)
1200
1184
  return False
1201
1185
 
1202
- ## Add to the list after the plug is created successfully.
1203
- self.plugins[name] = module
1204
-
1205
- ## Set reference of a plug (one module, one plugin).
1206
- module.__plug__ = plug
1207
-
1208
1186
  ## Create pane or notebook pane.
1209
1187
  caption = plug.caption
1210
1188
  if not isinstance(caption, str):
@@ -1233,6 +1211,12 @@ class Frame(mwx.Frame):
1233
1211
  .Name(name).Caption(caption)
1234
1212
  .FloatingSize(size).MinSize(size).Show(0))
1235
1213
 
1214
+ ## Add to the list after the plug is created successfully.
1215
+ self.plugins[name] = module
1216
+
1217
+ ## Set reference of a plug (one module, one plugin).
1218
+ module.__plug__ = plug
1219
+
1236
1220
  ## Set winow.Name for inspection.
1237
1221
  plug.Name = name
1238
1222
 
@@ -1271,13 +1255,10 @@ class Frame(mwx.Frame):
1271
1255
  """Unload plugin and detach the pane from UI manager."""
1272
1256
  plug = self.get_plug(name)
1273
1257
  if not plug:
1258
+ print(f"- {name!r} is not listed in plugins.")
1274
1259
  return
1275
1260
 
1276
- name = plug.__module__
1277
- if name not in self.plugins:
1278
- return
1279
-
1280
- del self.plugins[name]
1261
+ del self.plugins[plug.Name]
1281
1262
 
1282
1263
  if plug.__Menu_item:
1283
1264
  menu, sep, tail = plug.menukey.rpartition('/')
@@ -1304,23 +1285,25 @@ class Frame(mwx.Frame):
1304
1285
  nb.Destroy()
1305
1286
 
1306
1287
  def reload_plug(self, name):
1288
+ """Reload plugin."""
1307
1289
  plug = self.get_plug(name)
1308
- if not plug or not plug.reloadable:
1290
+ if not plug:
1291
+ print(f"- {name!r} is not listed in plugins.")
1309
1292
  return
1293
+
1310
1294
  session = {}
1311
1295
  try:
1312
1296
  print("Reloading {}...".format(plug))
1313
1297
  plug.save_session(session)
1314
1298
  except Exception:
1315
- traceback.print_exc()
1316
- print("- Failed to save session of", plug)
1299
+ traceback.print_exc() # Failed to save the plug session.
1317
1300
  self.load_plug(plug.__module__, force=1, session=session)
1318
1301
 
1319
1302
  def inspect_plug(self, name):
1320
- """Dive into the process to inspect plugs in the shell.
1321
- """
1303
+ """Dive into the process to inspect plugs in the shell."""
1322
1304
  plug = self.get_plug(name)
1323
1305
  if not plug:
1306
+ print(f"- {name!r} is not listed in plugins.")
1324
1307
  return
1325
1308
 
1326
1309
  shell = self.shellframe.clone_shell(plug)
@@ -1349,8 +1332,7 @@ class Frame(mwx.Frame):
1349
1332
 
1350
1333
  def Quit(self, evt=None):
1351
1334
  """Stop all Layer threads."""
1352
- for name in self.plugins:
1353
- plug = self.get_plug(name)
1335
+ for plug in self.get_all_plugs():
1354
1336
  thread = plug.thread # Note: thread can be None or shared.
1355
1337
  if thread and thread.active:
1356
1338
  ## thread.active = 0
@@ -1775,16 +1757,14 @@ class Frame(mwx.Frame):
1775
1757
  for name, module in self.plugins.items():
1776
1758
  plug = self.get_plug(name)
1777
1759
  if '.' not in name:
1778
- name = os.path.abspath(module.__file__) # Replace name with full path.
1779
- basename = os.path.basename(name)
1780
- if basename == "__init__.py": # is module package?
1781
- name = name[:-12]
1760
+ name = module.__file__ # Replace the name with full path.
1761
+ if hasattr(module, '__path__'): # is the module a package?
1762
+ name = os.path.dirname(name)
1782
1763
  session = {}
1783
1764
  try:
1784
1765
  plug.save_session(session)
1785
1766
  except Exception:
1786
- traceback.print_exc()
1787
- print("- Failed to save session of", plug)
1767
+ traceback.print_exc() # Failed to save the plug session.
1788
1768
  o.write("self.load_plug({!r}, session={})\n".format(name, session or None))
1789
1769
  o.write("self._mgr.LoadPerspective({!r})\n".format(self._mgr.SavePerspective()))
1790
1770
 
mwx/utilus.py CHANGED
@@ -200,8 +200,12 @@ def typename(obj, docp=False, qualp=True):
200
200
  return pydoc.describe(obj) # atom -> short description
201
201
 
202
202
  modname = getattr(obj, '__module__', None)
203
- if modname and modname != "__main__" and not modname.startswith('mwx'):
204
- name = modname + ('.' if qualp else '..') + name
203
+ if modname:
204
+ if qualp:
205
+ name = modname + '.' + name
206
+ else:
207
+ if not modname.startswith(("__main__", "mwx")):
208
+ name = modname + '..' + name
205
209
 
206
210
  if docp and callable(obj) and obj.__doc__:
207
211
  name += "<{!r}>".format(obj.__doc__.splitlines()[0]) # concat the first doc line
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mwxlib
3
- Version: 1.5.10
3
+ Version: 1.5.12
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=hvjhA9nWgrWkpDzx1m478BD5_1OLUrSP-dfSZN463FA,77785
5
- mwx/graphman.py,sha256=mrs4am6VbIT20gS2j9-ISHSIscZeP-eM_lLj3xYhufo,70012
4
+ mwx/framework.py,sha256=XFzMG6Jah0hROirGBGjmZHsv12986GV2-bjT4sl0D5w,77574
5
+ mwx/graphman.py,sha256=AjXd8Hyb-lCEkPuCz1C19aEi6dnt3DW8N0b89cVYITU,69905
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=YVU-2aR9_22-clA0OCFKfmW0c49uhNWdbQaNXxNKXxA,38964
13
+ mwx/utilus.py,sha256=dsJ_wsEjqm-B75It-lwVCAiCPyPXZerngm_6TCUEmRU,39028
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
@@ -22,7 +22,7 @@ mwx/plugins/frame_listview.py,sha256=yd2NCgspqGfTNhj1wxuW8r1zapIm7vNzVX2iytk8CDM
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.10.dist-info/METADATA,sha256=TVRXE_-HQOVN7z-VvBMRAs1IKcYwvsPoWP-qS8Bcwh4,7382
26
- mwxlib-1.5.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- mwxlib-1.5.10.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-1.5.10.dist-info/RECORD,,
25
+ mwxlib-1.5.12.dist-info/METADATA,sha256=h77mRadmYbztrngMyjSysNdiM9fGxuQcbIN9zCpRpcY,7382
26
+ mwxlib-1.5.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ mwxlib-1.5.12.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-1.5.12.dist-info/RECORD,,