mwxlib 0.96.0__py3-none-any.whl → 0.96.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
@@ -1,4 +1,5 @@
1
1
  #! python3
2
+ from functools import partial
2
3
  import re
3
4
  import wx
4
5
 
mwx/controls.py CHANGED
@@ -8,11 +8,12 @@ import wx.lib.scrolledpanel as scrolled
8
8
 
9
9
  from . import images
10
10
  from .utilus import SSM
11
+ from .utilus import warn
11
12
  from .utilus import funcall as _F
12
13
  from .framework import pack, Menu
13
14
 
14
15
  import numpy as np
15
- from numpy import nan, inf
16
+ from numpy import nan, inf # noqa: necessary to eval
16
17
 
17
18
 
18
19
  def _Tip(*tips):
@@ -83,12 +84,12 @@ class Param(object):
83
84
  def __len__(self):
84
85
  return len(self.range)
85
86
 
86
- @wx.deprecatedMsg("Use `Param.callback.bind` instead.") #<DeprecationWarning>
87
87
  def bind(self, action=None, target='control'):
88
+ warn("Use `Param.callback.bind` instead.", DeprecationWarning)
88
89
  return self.callback.bind(target, action)
89
90
 
90
- @wx.deprecatedMsg("Use `Param.callback.unbind` instead.") #<DeprecationWarning>
91
91
  def unbind(self, action=None, target='control'):
92
+ warn("Use `Param.callback.unbind` instead.", DeprecationWarning)
92
93
  return self.callback.unbind(target, action)
93
94
 
94
95
  def reset(self, v=None, backcall=True):
@@ -97,10 +98,8 @@ class Param(object):
97
98
  v = self.std_value
98
99
  if v is None:
99
100
  return
100
- elif v == 'nan': v = nan
101
- elif v == 'inf': v = inf
102
- elif isinstance(v, str):
103
- v = self.__eval(v.replace(',', '')) # eliminates commas
101
+ if isinstance(v, str):
102
+ v = self.__eval(v.replace(',', '')) # eliminates commas; includes nan, inf
104
103
  self._set_value(v)
105
104
  if backcall:
106
105
  self.callback('control', self)
@@ -111,7 +110,8 @@ class Param(object):
111
110
  """
112
111
  if v is None:
113
112
  v = nan
114
- if v in (nan, inf):
113
+
114
+ if np.isnan(v) or np.isinf(v):
115
115
  self.__value = v
116
116
  for knob in self.knobs:
117
117
  knob.update_ctrl(None, notify=False)
@@ -185,7 +185,7 @@ class Param(object):
185
185
  @offset.setter
186
186
  def offset(self, v):
187
187
  if self.std_value is not None:
188
- if v is not nan: # Note: nan +x is not nan
188
+ if not np.isnan(v):
189
189
  v += self.std_value
190
190
  self._set_value(v)
191
191
 
@@ -253,6 +253,7 @@ class LParam(Param):
253
253
 
254
254
  @range.setter
255
255
  def range(self, v):
256
+ assert v is None or len(v) <= 3, "The range must be of length <= 3 or None"
256
257
  if v is None:
257
258
  v = (0, 0)
258
259
  self.__min = v[0]
@@ -266,7 +267,8 @@ class LParam(Param):
266
267
  """A knob index -> value
267
268
  Returns -1 if the value is nan or inf.
268
269
  """
269
- if self.value in (nan, inf):
270
+ v = self.value
271
+ if np.isnan(v) or np.isinf(v):
270
272
  return -1
271
273
  return int(round((self.value - self.min) / self.step))
272
274
 
@@ -294,7 +296,6 @@ class Knob(wx.Panel):
294
296
  None -> static text (default)
295
297
  chkbox -> label with check box
296
298
  button -> label with flat button
297
- editable: textctrl is editable or readonly
298
299
  cw : width of ctrl
299
300
  lw : width of label
300
301
  tw : width of textbox
@@ -319,7 +320,7 @@ class Knob(wx.Panel):
319
320
  wx.Panel.__init__(self, parent, **kwargs)
320
321
 
321
322
  assert isinstance(param, Param),\
322
- "Argument `param` must be an instance of Param class."
323
+ "Argument `param` must be an instance of Param"
323
324
 
324
325
  self.__bit = 1
325
326
  self.__par = param
@@ -354,23 +355,22 @@ class Knob(wx.Panel):
354
355
  else:
355
356
  raise Exception("unknown style: {!r}".format(style))
356
357
 
357
- self.label.Enable(lw)
358
358
  self.label.Bind(wx.EVT_MIDDLE_DOWN, lambda v: self.__par.reset())
359
-
360
359
  self.label.SetToolTip(self.__par._tooltip)
360
+ self.label.Enable(lw) # skip focus
361
361
 
362
- if editable:
363
- self.text = wx.TextCtrl(self, size=(tw,h), style=wx.TE_PROCESS_ENTER)
364
- self.text.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
365
- self.text.Bind(wx.EVT_KILL_FOCUS, self.OnTextExit)
366
- self.text.Bind(wx.EVT_KEY_DOWN, self.OnTextKeyDown)
367
- self.text.Bind(wx.EVT_KEY_UP, self.OnTextKeyUp)
368
- self.text.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
369
- self.text.Bind(wx.EVT_MIDDLE_DOWN, lambda v: self.__par.reset())
370
- else:
371
- self.text = wx.TextCtrl(self, size=(tw,h), style=wx.TE_READONLY)
362
+ if not editable:
363
+ warn("Knob option `editable` is deprecated.", DeprecationWarning)
364
+
365
+ self.text = wx.TextCtrl(self, size=(tw,h), style=wx.TE_PROCESS_ENTER)
366
+ self.text.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter)
367
+ self.text.Bind(wx.EVT_KILL_FOCUS, self.OnTextExit)
368
+ self.text.Bind(wx.EVT_KEY_DOWN, self.OnTextKeyDown)
369
+ self.text.Bind(wx.EVT_KEY_UP, self.OnTextKeyUp)
370
+ self.text.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
371
+ self.text.Bind(wx.EVT_MIDDLE_DOWN, lambda v: self.__par.reset())
372
372
 
373
- self.text.Enable(tw)
373
+ self.text.Enable(tw) # skip focus
374
374
 
375
375
  if type == 'slider':
376
376
  self.ctrl = wx.Slider(self, size=(cw,h), style=wx.SL_HORIZONTAL)
@@ -404,8 +404,8 @@ class Knob(wx.Panel):
404
404
  else:
405
405
  raise Exception("unknown type: {!r}".format(type))
406
406
 
407
- self.ctrl.Enable(cw != 0)
408
407
  self.ctrl.Bind(wx.EVT_MIDDLE_DOWN, lambda v: self.__par.reset())
408
+ self.ctrl.Enable(cw) # skip focus
409
409
 
410
410
  c = (cw and type != 'vspin')
411
411
  self.SetSizer(
@@ -425,6 +425,7 @@ class Knob(wx.Panel):
425
425
  evt.Skip()
426
426
 
427
427
  def update_range(self):
428
+ """Called when range is being changed (internal use only)."""
428
429
  v = self.__par
429
430
  if isinstance(self.ctrl, wx.Choice): #<wx.Choice>
430
431
  items = [v.__str__(x) for x in v.range]
@@ -435,6 +436,7 @@ class Knob(wx.Panel):
435
436
  self.ctrl.SetRange(0, len(v)-1) #<wx.Slider> <wx.SpinButton>
436
437
 
437
438
  def update_label(self):
439
+ """Called when label is being changed (internal use only)."""
438
440
  v = self.__par
439
441
  if isinstance(self.label, wx.CheckBox):
440
442
  self.label.SetValue(v.check)
@@ -445,6 +447,7 @@ class Knob(wx.Panel):
445
447
  self.label.Refresh()
446
448
 
447
449
  def update_ctrl(self, valid=True, notify=False):
450
+ """Called when value is being changed (internal use only)."""
448
451
  v = self.__par
449
452
  try:
450
453
  j = v.index
@@ -765,32 +768,32 @@ class Clipboard:
765
768
  The clipboard data cannot be transferred unless wx.Frame exists.
766
769
  """
767
770
  @staticmethod
768
- def read(verbose=True):
771
+ def read(verbose=False):
769
772
  do = wx.TextDataObject()
770
773
  if wx.TheClipboard.Open():
771
774
  wx.TheClipboard.GetData(do)
772
775
  wx.TheClipboard.Close()
773
776
  text = do.GetText()
774
777
  if verbose:
775
- print("From clipboard: {}".format(text))
778
+ print(f"From clipboard:\n{text}")
776
779
  return text
777
780
  else:
778
781
  print("- Unable to open clipboard.")
779
782
 
780
783
  @staticmethod
781
- def write(text, verbose=True):
784
+ def write(text, verbose=False):
782
785
  do = wx.TextDataObject(str(text))
783
786
  if wx.TheClipboard.Open():
784
787
  wx.TheClipboard.SetData(do)
785
788
  wx.TheClipboard.Flush()
786
789
  wx.TheClipboard.Close()
787
790
  if verbose:
788
- print("To clipboard: {}".format(text))
791
+ print(f"To clipboard:\n{text}")
789
792
  else:
790
793
  print("- Unable to open clipboard.")
791
794
 
792
795
  @staticmethod
793
- def imread(verbose=True):
796
+ def imread(verbose=False):
794
797
  do = wx.BitmapDataObject()
795
798
  if wx.TheClipboard.Open():
796
799
  wx.TheClipboard.GetData(do)
@@ -804,14 +807,14 @@ class Clipboard:
804
807
  img = bmp.ConvertToImage()
805
808
  buf = np.array(img.GetDataBuffer()) # do copy, don't ref
806
809
  if verbose:
807
- print("From clipboard {:.1f} Mb data".format(buf.nbytes/1e6))
810
+ print("From clipboard: {:.1f} Mb data read.".format(buf.nbytes/1e6))
808
811
  w, h = img.GetSize()
809
812
  return buf.reshape(h, w, 3)
810
813
  except Exception:
811
814
  print("- The contents of the clipboard are not images.")
812
815
 
813
816
  @staticmethod
814
- def imwrite(buf, verbose=True):
817
+ def imwrite(buf, verbose=False):
815
818
  try:
816
819
  ## Convert buf --> bmp
817
820
  h, w = buf.shape[:2]
@@ -829,7 +832,7 @@ class Clipboard:
829
832
  wx.TheClipboard.Flush()
830
833
  wx.TheClipboard.Close()
831
834
  if verbose:
832
- print("To clipboard: {:.1f} Mb data".format(buf.nbytes/1e6))
835
+ print("To clipboard: {:.1f} Mb data written.".format(buf.nbytes/1e6))
833
836
  else:
834
837
  print("- Unable to open clipboard.")
835
838
 
mwx/framework.py CHANGED
@@ -1,14 +1,12 @@
1
1
  #! python3
2
2
  """mwxlib framework.
3
3
  """
4
- __version__ = "0.96.0"
4
+ __version__ = "0.96.4"
5
5
  __author__ = "Kazuya O'moto <komoto@jeol.co.jp>"
6
6
 
7
7
  from functools import wraps, partial
8
8
  from importlib import reload
9
- from contextlib import contextmanager
10
9
  import traceback
11
- import warnings
12
10
  import builtins
13
11
  import datetime
14
12
  import textwrap
@@ -21,8 +19,8 @@ from wx import stc
21
19
  from wx.py import dispatcher
22
20
 
23
21
  from .utilus import funcall as _F
22
+ from .utilus import get_rootpath, ignore, warn # noqa
24
23
  from .utilus import FSM, TreeList, apropos, typename, where, mro, pp
25
- from .utilus import get_rootpath
26
24
 
27
25
 
28
26
  def deb(target=None, loop=True, locals=None, **kwargs):
@@ -232,7 +230,7 @@ class KeyCtrlInterfaceMixin:
232
230
  state = self.handler.default_state
233
231
  event = keymap + ' pressed'
234
232
 
235
- assert state is not None, "Don't make keymap for None:state."
233
+ assert state is not None, "Don't make keymap for None:state"
236
234
 
237
235
  self.handler.update({ # DNA<KeyCtrlInterfaceMixin>
238
236
  state : {
@@ -290,14 +288,12 @@ class KeyCtrlInterfaceMixin:
290
288
  key += ' pressed'
291
289
 
292
290
  if map not in self.handler:
293
- warnings.warn(f"New map to define_key {keymap!r} in {self}.",
294
- stacklevel=2)
291
+ warn(f"New map to define_key {keymap!r} in {self}.")
295
292
  self.make_keymap(map) # make new keymap
296
293
 
297
294
  transaction = self.handler[map].get(key, [state])
298
295
  if len(transaction) > 1:
299
- warnings.warn(f"Duplicate define_key {keymap!r} in {self}.",
300
- stacklevel=2)
296
+ warn(f"Duplicate define_key {keymap!r} in {self}.")
301
297
 
302
298
  if action is None:
303
299
  self.handler[map].pop(key, None) # cf. undefine_key
@@ -322,10 +318,6 @@ class CtrlInterface(KeyCtrlInterfaceMixin):
322
318
  handler = property(lambda self: self.__handler)
323
319
 
324
320
  def __init__(self):
325
- if hasattr(self, 'handler'):
326
- warnings.warn(f"Duplicate iniheritance of CtrlInterface by {self}.",
327
- stacklevel=2)
328
- return
329
321
  self.__key = ''
330
322
  self.__button = ''
331
323
  self.__isDragging = False
@@ -629,8 +621,7 @@ class MenuBar(wx.MenuBar, TreeList):
629
621
  Call when the menulist is changed.
630
622
  """
631
623
  if not self.Parent:
632
- warnings.warn(f"No parents bound to {self}.",
633
- stacklevel=2)
624
+ warn(f"No parents bound to {self}.")
634
625
  return
635
626
 
636
627
  menu = self.getmenu(key)
@@ -657,8 +648,7 @@ class MenuBar(wx.MenuBar, TreeList):
657
648
  Call when the menulist is changed.
658
649
  """
659
650
  if not self.Parent:
660
- warnings.warn(f"No parents bound to {self}.",
661
- stacklevel=2)
651
+ warn(f"No parents bound to {self}.")
662
652
  return
663
653
 
664
654
  for j in range(self.GetMenuCount()): # remove and del all top-level menu
mwx/graphman.py CHANGED
@@ -9,7 +9,6 @@ from bdb import BdbQuit
9
9
  import subprocess
10
10
  import threading
11
11
  import traceback
12
- import warnings
13
12
  import inspect
14
13
  import sys
15
14
  import os
@@ -26,6 +25,7 @@ from PIL import Image
26
25
  from PIL.TiffImagePlugin import TiffImageFile
27
26
 
28
27
  from . import framework as mwx
28
+ from .utilus import ignore, warn
29
29
  from .utilus import funcall as _F
30
30
  from .controls import ControlPanel, Icon
31
31
  from .framework import CtrlInterface, AuiNotebook, Menu, FSM
@@ -310,7 +310,10 @@ class LayerInterface(CtrlInterface):
310
310
  self.__artists.remove(art)
311
311
 
312
312
  def __init__(self, parent, session=None):
313
- CtrlInterface.__init__(self)
313
+ if hasattr(self, 'handler'):
314
+ warn(f"Duplicate iniheritance of CtrlInterface by {self}.")
315
+ else:
316
+ CtrlInterface.__init__(self)
314
317
 
315
318
  self.parent = parent
316
319
  self.__artists = []
@@ -855,15 +858,14 @@ class Frame(mwx.Frame):
855
858
 
856
859
  Editor = "notepad"
857
860
 
861
+ @ignore(ResourceWarning)
858
862
  def edit(self, fn):
859
863
  if hasattr(fn, '__file__'):
860
864
  name, _ = os.path.splitext(fn.__file__)
861
865
  fn = name + '.py'
862
866
  cmd = '{} "{}"'.format(self.Editor, fn)
863
- with warnings.catch_warnings():
864
- warnings.simplefilter("ignore", ResourceWarning)
865
- subprocess.Popen(cmd)
866
- self.message(cmd)
867
+ subprocess.Popen(cmd)
868
+ self.message(cmd)
867
869
 
868
870
  def set_title(self, frame):
869
871
  ssn = os.path.basename(self.session_file or '--')
@@ -887,6 +889,20 @@ class Frame(mwx.Frame):
887
889
  elif ret == wx.ID_CANCEL:
888
890
  evt.Veto()
889
891
  return
892
+ for name in self.plugins:
893
+ plug = self.get_plug(name)
894
+ if plug.thread and plug.thread.active:
895
+ if wx.MessageBox( # Confirm thread close.
896
+ "The thread is running.\n\n"
897
+ "Enter [q]uit to exit before closing.\n"
898
+ "Continue closing?",
899
+ "Close {!r}".format(plug.Name),
900
+ style=wx.YES_NO|wx.ICON_INFORMATION) != wx.YES:
901
+ self.message("The close has been canceled.")
902
+ evt.Veto()
903
+ return
904
+ self.Quit()
905
+ break
890
906
  for frame in self.graph.all_frames:
891
907
  if frame.pathname is None:
892
908
  if wx.MessageBox( # Confirm close.
@@ -914,11 +930,9 @@ class Frame(mwx.Frame):
914
930
  Args:
915
931
  name : str or plug object.
916
932
  """
917
- if name in self.plugins:
918
- plug = self.plugins[name].__plug__
919
- name = plug.category or name
920
- elif isinstance(name, LayerInterface):
921
- name = name.category or name
933
+ plug = self.get_plug(name)
934
+ if plug:
935
+ name = plug.category or plug
922
936
  if name:
923
937
  return self._mgr.GetPane(name)
924
938
 
@@ -953,6 +967,7 @@ class Frame(mwx.Frame):
953
967
  ## Note: We need to distinguish cases whether:
954
968
  ## - pane.window is AuiNotebook or normal Panel,
955
969
  ## - pane.window is floating (win.Parent is AuiFloatingFrame) or docked.
970
+
956
971
  plug = self.get_plug(name) # -> None if pane.window is a Graph
957
972
  win = pane.window # -> Window (plug / notebook / Graph)
958
973
  try:
@@ -1029,7 +1044,7 @@ class Frame(mwx.Frame):
1029
1044
  win.handler('page_closed', win)
1030
1045
 
1031
1046
  ## --------------------------------
1032
- ## Plugin (Layer) interface
1047
+ ## Plugin <Layer> interface
1033
1048
  ## --------------------------------
1034
1049
  plugins = property(lambda self: self.__plugins)
1035
1050
 
@@ -1063,15 +1078,14 @@ class Frame(mwx.Frame):
1063
1078
 
1064
1079
  @staticmethod
1065
1080
  def register(cls, module=None):
1066
- """Register dummy plug; Add module.Plugin(Layer).
1081
+ """Register dummy plug; Add module.Plugin <Layer>.
1067
1082
  """
1068
1083
  if not module:
1069
1084
  module = inspect.getmodule(cls) # rebase module or __main__
1070
1085
 
1071
1086
  if issubclass(cls, LayerInterface):
1072
1087
  cls.__module__ = module.__name__ # __main__ to module
1073
- warnings.warn(f"Duplicate iniheritance of LayerInterface by {cls}.",
1074
- stacklevel=2)
1088
+ warn(f"Duplicate iniheritance of LayerInterface by {cls}.")
1075
1089
  module.Plugin = cls
1076
1090
  return cls
1077
1091
 
@@ -1121,8 +1135,7 @@ class Frame(mwx.Frame):
1121
1135
  ## the module must have a class `Plugin`.
1122
1136
  if not hasattr(module, 'Plugin'):
1123
1137
  if isinstance(root, type):
1124
- warnings.warn(f"Use dummy plug for debugging {name!r}.",
1125
- stacklevel=3)
1138
+ warn(f"Use dummy plug for debugging {name!r}.")
1126
1139
  module.__dummy_plug__ = root
1127
1140
  self.register(root, module)
1128
1141
  else:
@@ -1420,7 +1433,7 @@ class Frame(mwx.Frame):
1420
1433
  "ALL files (*.*)|*.*",
1421
1434
  style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) as dlg:
1422
1435
  if dlg.ShowModal() != wx.ID_OK:
1423
- return
1436
+ return None
1424
1437
  filename = dlg.Path
1425
1438
 
1426
1439
  res, mis = self.read_attributes(filename)
@@ -1445,7 +1458,7 @@ class Frame(mwx.Frame):
1445
1458
  if not frames:
1446
1459
  frames = self.selected_view.all_frames
1447
1460
  if not frames:
1448
- return
1461
+ return None
1449
1462
 
1450
1463
  if not filename:
1451
1464
  fn = next((x.pathname for x in frames if x.pathname), '')
@@ -1455,7 +1468,7 @@ class Frame(mwx.Frame):
1455
1468
  wildcard="Index (*.index)|*.index",
1456
1469
  style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
1457
1470
  if dlg.ShowModal() != wx.ID_OK:
1458
- return
1471
+ return None
1459
1472
  filename = dlg.Path
1460
1473
 
1461
1474
  savedir = os.path.dirname(filename)
@@ -1608,6 +1621,7 @@ class Frame(mwx.Frame):
1608
1621
  os.remove(path)
1609
1622
  raise
1610
1623
 
1624
+ @ignore(ResourceWarning)
1611
1625
  def load_buffer(self, paths=None, view=None):
1612
1626
  """Load buffers from paths to the view window.
1613
1627
 
@@ -1625,11 +1639,11 @@ class Frame(mwx.Frame):
1625
1639
  style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST
1626
1640
  |wx.FD_MULTIPLE) as dlg:
1627
1641
  if dlg.ShowModal() != wx.ID_OK:
1628
- return
1642
+ return None
1629
1643
  paths = dlg.Paths
1644
+ frames = []
1645
+ frame = None
1630
1646
  try:
1631
- frames = []
1632
- frame = None
1633
1647
  for i, path in enumerate(paths):
1634
1648
  fn = os.path.basename(path)
1635
1649
  self.message("Loading {!r} ({} of {})...".format(fn, i+1, len(paths)))
@@ -1672,7 +1686,7 @@ class Frame(mwx.Frame):
1672
1686
  if not frame:
1673
1687
  frame = self.selected_view.frame
1674
1688
  if not frame:
1675
- return
1689
+ return None
1676
1690
 
1677
1691
  if not path:
1678
1692
  with wx.FileDialog(self, "Save buffer as",
@@ -1680,7 +1694,7 @@ class Frame(mwx.Frame):
1680
1694
  wildcard='|'.join(self.wildcards),
1681
1695
  style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
1682
1696
  if dlg.ShowModal() != wx.ID_OK:
1683
- return
1697
+ return None
1684
1698
  path = dlg.Path
1685
1699
  try:
1686
1700
  name = os.path.basename(path)
@@ -1700,13 +1714,14 @@ class Frame(mwx.Frame):
1700
1714
  except Exception as e:
1701
1715
  self.message("\b failed.")
1702
1716
  wx.MessageBox(str(e), style=wx.ICON_ERROR)
1717
+ return None
1703
1718
 
1704
1719
  def save_buffers_as_tiffs(self, path=None, frames=None):
1705
1720
  """Export buffers to a file as a multi-page tiff."""
1706
1721
  if not frames:
1707
1722
  frames = self.selected_view.all_frames
1708
1723
  if not frames:
1709
- return
1724
+ return None
1710
1725
 
1711
1726
  if not path:
1712
1727
  with wx.FileDialog(self, "Save frames as stack-tiff",
@@ -1714,7 +1729,7 @@ class Frame(mwx.Frame):
1714
1729
  wildcard="TIF file (*.tif)|*.tif",
1715
1730
  style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dlg:
1716
1731
  if dlg.ShowModal() != wx.ID_OK:
1717
- return
1732
+ return None
1718
1733
  path = dlg.Path
1719
1734
  try:
1720
1735
  name = os.path.basename(path)
@@ -1733,6 +1748,7 @@ class Frame(mwx.Frame):
1733
1748
  except Exception as e:
1734
1749
  self.message("\b failed.")
1735
1750
  wx.MessageBox(str(e), style=wx.ICON_ERROR)
1751
+ return False
1736
1752
  finally:
1737
1753
  del busy
1738
1754
 
mwx/matplot2g.py CHANGED
@@ -2,7 +2,6 @@
2
2
  """mwxlib graph plot for images.
3
3
  """
4
4
  import traceback
5
- import warnings
6
5
  import wx
7
6
 
8
7
  from matplotlib import cm
@@ -10,11 +9,12 @@ from matplotlib import patches
10
9
  from PIL import Image
11
10
  import cv2
12
11
  import numpy as np
13
- from numpy import pi, nan
12
+ from numpy import pi
14
13
  from scipy import ndimage as ndi
15
14
 
16
15
  from . import framework as mwx
17
16
  from .framework import Menu
17
+ from .utilus import warn
18
18
  from .utilus import funcall as _F
19
19
  from .controls import Clipboard
20
20
  from .matplot2 import MatplotPanel
@@ -224,24 +224,26 @@ class AxesImagePhantom(object):
224
224
  @property
225
225
  def unit(self):
226
226
  """Logical length per pixel arb.unit [u/pixel]."""
227
- return self.__localunit or self.parent.globalunit
227
+ return self.__localunit or self.parent.unit
228
228
 
229
229
  @unit.setter
230
230
  def unit(self, v):
231
231
  u = self.unit
232
- if v in (None, nan):
233
- v = self.parent.globalunit
232
+ if v is None:
233
+ v = self.parent.unit
234
234
  self.__localunit = None
235
+ elif np.isnan(v) or np.isinf(v):
236
+ raise ValueError("The unit value cannot be NaN or Inf")
235
237
  elif v <= 0:
236
- raise Exception("The unit value must be greater than zero.")
238
+ raise ValueError("The unit value must be greater than zero")
237
239
  else:
238
240
  if v == self.__localunit: # no effect when v is localunit
239
241
  return
240
242
  self.__localunit = v
241
243
  self.__attributes['localunit'] = self.__localunit
242
244
  self.update_extent()
243
- self.parent.update_markup_ratio(v/u)
244
245
  self.parent.handler('frame_updated', self)
246
+ self.parent.canvas.draw_idle()
245
247
 
246
248
  @unit.deleter
247
249
  def unit(self):
@@ -249,7 +251,7 @@ class AxesImagePhantom(object):
249
251
 
250
252
  @property
251
253
  def xy_unit(self):
252
- u = self.__localunit or self.parent.globalunit
254
+ u = self.__localunit or self.parent.unit
253
255
  return (u, u * self.__aspect_ratio)
254
256
 
255
257
  @property
@@ -331,8 +333,7 @@ class AxesImagePhantom(object):
331
333
  def _cast(n):
332
334
  return np.int32(np.floor(np.round(n, 1)))
333
335
  if y is None:
334
- warnings.warn("Setting xy data with single tuple is deprecated.",
335
- DeprecationWarning, stacklevel=2)
336
+ warn("Setting xy data with single tuple.", DeprecationWarning)
336
337
  x, y = x
337
338
  if isinstance(x, (list, tuple)):
338
339
  x = np.array(x)
@@ -348,8 +349,7 @@ class AxesImagePhantom(object):
348
349
  def xyfrompixel(self, nx, ny=None):
349
350
  """Convert pixel [nx,ny] -> (x,y) xydata (float number)."""
350
351
  if ny is None:
351
- warnings.warn("Setting xy data with single tuple is deprecated.",
352
- DeprecationWarning, stacklevel=2)
352
+ warn("Setting xy data with single tuple.", DeprecationWarning)
353
353
  nx, ny = nx
354
354
  if isinstance(nx, (list, tuple)):
355
355
  nx = np.array(nx)
@@ -658,8 +658,8 @@ class GraphPlot(MatplotPanel):
658
658
  j = names.index(name) # existing frame
659
659
  if j != -1:
660
660
  art = self.__Arts[j]
661
- art.update_buffer(buf) # => frame_modified
662
- art.update_attributes(kwargs) # => frame_updated
661
+ art.update_buffer(buf) # => [frame_modified]
662
+ art.update_attributes(kwargs) # => [frame_updated] localunit => [canvas_draw]
663
663
  art.update_extent()
664
664
  if show:
665
665
  self.select(j)
@@ -674,7 +674,11 @@ class GraphPlot(MatplotPanel):
674
674
  self.__Arts.insert(j, art)
675
675
  self.handler('frame_loaded', art)
676
676
  if show:
677
+ u = self.frame and self.frame.unit # current frame unit
677
678
  self.select(j)
679
+ ## Update view if the unit length is different from before selection
680
+ if u != art.unit:
681
+ self.axes.axis(art.get_extent())
678
682
  return art
679
683
 
680
684
  def select(self, j):
@@ -688,17 +692,10 @@ class GraphPlot(MatplotPanel):
688
692
  self.handler('frame_hidden', self.frame)
689
693
 
690
694
  if j is not None:
691
- u = self.frame and self.frame.unit # current frame unit
692
-
693
695
  art = self.__Arts[j]
694
696
  art.set_visible(1)
695
697
  self.__index = j % len(self)
696
698
  self.handler('frame_shown', art)
697
-
698
- ## Update view if the unit length is different than before
699
- if u != art.unit:
700
- ## self.update_axis()
701
- self.axes.axis(art.get_extent())
702
699
  else:
703
700
  self.__index = None
704
701
 
@@ -828,10 +825,12 @@ class GraphPlot(MatplotPanel):
828
825
 
829
826
  @unit.setter
830
827
  def unit(self, v):
831
- if v in (None, nan):
832
- raise Exception("The globalunit must be non-nil value.")
828
+ if v is None:
829
+ raise ValueError("The globalunit must be non-nil value")
830
+ elif np.isnan(v) or np.isinf(v):
831
+ raise ValueError("Axis limits cannot be NaN or Inf")
833
832
  elif v <= 0:
834
- raise Exception("The unit value must be greater than zero.")
833
+ raise ValueError("The unit value must be greater than zero")
835
834
  else:
836
835
  if v == self.__unit: # no effect unless unit changes
837
836
  return
@@ -839,19 +838,10 @@ class GraphPlot(MatplotPanel):
839
838
  self.__unit = v
840
839
  for art in self.__Arts:
841
840
  art.update_extent()
842
- else:
843
- self.update_markup_ratio(v/u)
844
- for art in self.__Arts:
845
841
  self.handler('frame_updated', art)
842
+ self.canvas.draw_idle()
846
843
 
847
- globalunit = unit
848
-
849
- def update_markup_ratio(self, r):
850
- """Modify markup objects position."""
851
- if self.Selector.size: self.Selector *= r
852
- if self.Markers.size: self.Markers *= r
853
- if self.Region.size: self.Region *= r
854
- self.draw()
844
+ globalunit = unit # for backward compatibility
855
845
 
856
846
  def kill_buffer(self):
857
847
  if self.buffer is not None:
mwx/matplot2lg.py CHANGED
@@ -623,7 +623,7 @@ class LineProfile(LinePlot):
623
623
  with io.StringIO() as o:
624
624
  for x, y in zip(X, Y):
625
625
  o.write("{:g}\t{:g}\n".format(x, y))
626
- Clipboard.write(o.getvalue(), verbose=0)
626
+ Clipboard.write(o.getvalue())
627
627
  self.message("Write data to clipboard.")
628
628
 
629
629
  def annotate(self):
mwx/nutshell.py CHANGED
@@ -7,7 +7,6 @@ from contextlib import contextmanager
7
7
  from pprint import pformat
8
8
  from bdb import BdbQuit
9
9
  import traceback
10
- import warnings
11
10
  import inspect
12
11
  import builtins
13
12
  import dis
@@ -26,6 +25,7 @@ from wx.py.shell import Shell
26
25
  from wx.py.editwindow import EditWindow
27
26
 
28
27
  from .utilus import funcall as _F
28
+ from .utilus import ignore
29
29
  from .utilus import split_words, split_paren, split_tokens, find_modules
30
30
  from .framework import CtrlInterface, AuiNotebook, Menu
31
31
 
@@ -1986,7 +1986,7 @@ class EditorBook(AuiNotebook, CtrlInterface):
1986
1986
  self.swap_buffer(buf, lineno)
1987
1987
  return True
1988
1988
  ## return False
1989
- raise Exception("The requested URL was not found.")
1989
+ raise Exception("The requested URL was not found")
1990
1990
  if buf._load_file(filename):
1991
1991
  self.swap_buffer(buf, lineno)
1992
1992
  return True
@@ -2161,6 +2161,7 @@ class Interpreter(interpreter.Interpreter):
2161
2161
  except AttributeError:
2162
2162
  pass
2163
2163
 
2164
+ @ignore(DeprecationWarning)
2164
2165
  def getCallTip(self, command='', *args, **kwargs):
2165
2166
  """Return call tip text for a command.
2166
2167
 
@@ -2169,12 +2170,10 @@ class Interpreter(interpreter.Interpreter):
2169
2170
  (override) Ignore ValueError: no signature found for builtin
2170
2171
  if the unwrapped function is a builtin function.
2171
2172
  """
2172
- with warnings.catch_warnings():
2173
- warnings.simplefilter('ignore', DeprecationWarning)
2174
- try:
2175
- return interpreter.Interpreter.getCallTip(self, command, *args, **kwargs)
2176
- except ValueError:
2177
- return interpreter.Interpreter.getCallTip(self) # dummy
2173
+ try:
2174
+ return interpreter.Interpreter.getCallTip(self, command, *args, **kwargs)
2175
+ except ValueError:
2176
+ return interpreter.Interpreter.getCallTip(self) # dummy
2178
2177
 
2179
2178
 
2180
2179
  class Nautilus(Shell, EditorInterface):
@@ -72,7 +72,6 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
72
72
  'Lbutton dblclick' : (0, self.OnShowItems), # -> frame_shown
73
73
  'enter pressed' : (0, self.OnShowItems), # -> frame_shown
74
74
  'delete pressed' : (0, self.OnRemoveItems), # -> frame_removed/shown
75
- 'f2 pressed' : (0, self.OnEditAnnotation),
76
75
  'C-a pressed' : (0, self.OnSelectAllItems),
77
76
  'C-o pressed' : (0, self.OnLoadItems),
78
77
  'C-s pressed' : (0, self.OnSaveItems),
@@ -97,26 +96,17 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
97
96
  }
98
97
  self.Target.handler.append(self.context)
99
98
 
100
- def copy_info(all=True):
101
- frames = self.Target.all_frames
102
- if frames:
103
- frame = frames[self.focused_item]
104
- if all:
105
- text = pformat(frame.attributes, sort_dicts=0)
106
- else:
107
- text = "{}\n{}".format(frame.name, frame.annotation)
108
- Clipboard.write(text)
109
-
110
99
  self.menu = [
111
- (101, "&Edit annotation", "Edit annotation", Icon('pencil'),
112
- self.OnEditAnnotation),
100
+ (100, "Edit localunit", Icon('image'),
101
+ self.OnEditUnit,
102
+ lambda v: v.Enable(self.focused_item != -1)),
103
+
104
+ (101, "Edit annotation", Icon('pencil'),
105
+ self.OnEditAnnotation,
106
+ lambda v: v.Enable(self.focused_item != -1)),
113
107
  (),
114
108
  (102, "Copy info", Icon('copy'),
115
- lambda v: copy_info(0),
116
- lambda v: v.Enable(len(list(self.selected_items)))),
117
-
118
- (103, "Copy ALL data", Icon('copy', '+'),
119
- lambda v: copy_info(1),
109
+ self.OnCopyInfo,
120
110
  lambda v: v.Enable(len(list(self.selected_items)))),
121
111
  ]
122
112
  self.Bind(wx.EVT_CONTEXT_MENU,
@@ -183,26 +173,40 @@ class CheckList(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
183
173
  self.parent.parent.load_index(view=self.Target)
184
174
 
185
175
  def OnSaveItems(self, evt):
186
- frames = self.Target.all_frames
187
- selected_frames = [frames[j] for j in self.selected_items]
176
+ selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
188
177
  if selected_frames:
189
178
  self.parent.message("Exporting {} frames.".format(len(selected_frames)))
190
179
  self.parent.parent.save_index(frames=selected_frames)
191
180
  else:
192
181
  self.parent.message("No frame selected.")
193
182
 
183
+ def OnCopyInfo(self, evt):
184
+ selected_frames = [self.Target.all_frames[j] for j in self.selected_items]
185
+ if selected_frames:
186
+ text = ''
187
+ for frame in selected_frames:
188
+ text += pformat(frame.attributes, sort_dicts=0) # ALL attributes
189
+ ## text += '{}\n{}\n'.format(frame.name, frame.annotation)
190
+ Clipboard.write(text)
191
+ else:
192
+ self.parent.message("No frame selected.")
193
+
194
+ def OnEditUnit(self, evt):
195
+ frame = self.Target.all_frames[self.focused_item]
196
+ with wx.TextEntryDialog(self, frame.name,
197
+ 'Enter localunit', repr(frame.localunit)) as dlg:
198
+ if dlg.ShowModal() == wx.ID_OK:
199
+ frame.unit = eval(dlg.Value or 'None')
200
+
194
201
  def OnEditAnnotation(self, evt):
195
- frames = self.Target.all_frames
196
- if frames:
197
- frame = frames[self.focused_item]
198
- with wx.TextEntryDialog(self, frame.name,
199
- 'Enter an annotation', frame.annotation) as dlg:
200
- if dlg.ShowModal() == wx.ID_OK:
201
- frame.annotation = dlg.Value
202
+ frame = self.Target.all_frames[self.focused_item]
203
+ with wx.TextEntryDialog(self, frame.name,
204
+ 'Enter an annotation', frame.annotation) as dlg:
205
+ if dlg.ShowModal() == wx.ID_OK:
206
+ frame.annotation = dlg.Value
202
207
 
203
208
  def OnItemSelected(self, evt):
204
- frames = self.Target.all_frames
205
- frame = frames[evt.Index]
209
+ frame = self.Target.all_frames[evt.Index]
206
210
  self.parent.message(frame.pathname)
207
211
  evt.Skip()
208
212
 
mwx/utilus.py CHANGED
@@ -37,6 +37,16 @@ def ignore(*category):
37
37
  yield
38
38
 
39
39
 
40
+ def warn(message, category=None):
41
+ frame = inspect.currentframe().f_back # previous call stack frame
42
+ skip = [frame.f_code.co_filename]
43
+ stacklevel = 1
44
+ while frame.f_code.co_filename in skip:
45
+ frame = frame.f_back
46
+ stacklevel += 1
47
+ return warnings.warn(message, category, stacklevel+1)
48
+
49
+
40
50
  def atom(v):
41
51
  return not hasattr(v, '__name__')
42
52
 
@@ -434,13 +444,12 @@ def find_modules(force=False, verbose=True):
434
444
  lm = eval(o.read()) # read and evaluate module list
435
445
 
436
446
  ## Check additional packages and modules
437
- verbose = False
447
+ ## verbose = False
438
448
  for info in walk_packages_no_import(['.']):
439
449
  _callback('.', info.name)
440
450
  else:
441
- print("Please wait a moment "
442
- "while Py{} gathers a list of all available modules... "
443
- "(This is executed once)".format(sys.winver))
451
+ print(f"Please wait a moment while Py{sys.winver} gathers a list of "
452
+ "all available modules... (This is executed once)")
444
453
 
445
454
  lm = list(sys.builtin_module_names)
446
455
 
@@ -684,7 +693,6 @@ class FSM(dict):
684
693
  " action : {}".format(typename(act)),
685
694
  " args : {}".format(args),
686
695
  " kwargs : {}".format(kwargs))
687
- traceback.print_exc()
688
696
  self.__matched_pattern = None
689
697
  return retvals
690
698
 
@@ -728,12 +736,11 @@ class FSM(dict):
728
736
 
729
737
  @staticmethod
730
738
  def dump(*args):
731
- print(*args, sep='\n', file=sys.__stderr__)
732
739
  fn = get_rootpath("deb-dump.log")
733
740
  with open(fn, 'a') as o:
734
741
  print(time.strftime('!!! %Y/%m/%d %H:%M:%S'), file=o)
735
- print(*args, sep='\n', end='\n', file=o)
736
- print(traceback.format_exc(), file=o)
742
+ print(*args, traceback.format_exc(), sep='\n', file=o)
743
+ print(*args, traceback.format_exc(), sep='\n', file=sys.__stderr__)
737
744
 
738
745
  @staticmethod
739
746
  def duplicate(context):
@@ -810,11 +817,8 @@ class FSM(dict):
810
817
  assert isinstance(event, str)
811
818
  assert callable(action) or action is None
812
819
 
813
- def warn(msg):
814
- warnings.warn(msg, stacklevel=3)
815
-
816
820
  if state not in self:
817
- warn("- FSM warning: [{!r}] context newly created.".format(state))
821
+ warn(f"- FSM [{state!r}] context newly created.")
818
822
  self[state] = SSM() # new context
819
823
 
820
824
  context = self[state]
@@ -823,16 +827,16 @@ class FSM(dict):
823
827
 
824
828
  if event in context:
825
829
  if state2 != context[event][0]:
826
- warn("- FSM warning: transaction may conflict.\n"
827
- " The state {2!r} and the original state is not the same."
828
- " {0!r} : {1!r} --> {2!r}".format(event, state, state2))
830
+ warn(f"- FSM transaction may conflict.\n"
831
+ f" The state {state2!r} is different from the original state."
832
+ f" {event!r} : {state!r} --> {state2!r}")
829
833
  pass
830
834
  context[event][0] = state2 # update transition
831
835
  else:
832
836
  ## if state2 not in self:
833
- ## warn("- FSM warning: transaction may contradict\n"
834
- ## " The state {2!r} is not found in the contexts."
835
- ## " {0!r} : {1!r} --> {2!r}".format(event, state, state2))
837
+ ## warn(f"- FSM transaction may contradict\n"
838
+ ## f" The state {state2!r} is not found in the contexts."
839
+ ## f" {event!r} : {state!r} --> {state2!r}")
836
840
  ## pass
837
841
  context[event] = [state2] # new event:transaction
838
842
 
@@ -844,8 +848,8 @@ class FSM(dict):
844
848
  try:
845
849
  transaction.append(action)
846
850
  except AttributeError:
847
- warn("- FSM warning: cannot append new transaction ({!r} : {!r})\n"
848
- " The transaction must be a list, not a tuple".format(state, event))
851
+ warn(f"- FSM cannot append new transaction ({state!r} : {event!r})\n"
852
+ f" The transaction must be a list, not a tuple")
849
853
  return action
850
854
 
851
855
  def unbind(self, event, action=None, state=None):
@@ -858,16 +862,13 @@ class FSM(dict):
858
862
  """
859
863
  assert callable(action) or action is None
860
864
 
861
- def warn(msg):
862
- warnings.warn(msg, stacklevel=3)
863
-
864
865
  if state not in self:
865
- warn("- FSM warning: [{!r}] context does not exist.".format(state))
866
+ warn(f"- FSM [{state!r}] context does not exist.")
866
867
  return
867
868
 
868
869
  context = self[state]
869
870
  if event not in context:
870
- warn("- FSM warning: No such transaction ({!r} : {!r})".format(state, event))
871
+ warn(f"- FSM has no such transaction ({state!r} : {event!r})")
871
872
  return
872
873
 
873
874
  transaction = context[event]
@@ -881,8 +882,8 @@ class FSM(dict):
881
882
  transaction.remove(action)
882
883
  return True
883
884
  except AttributeError:
884
- warn("- FSM warning: removing action from context ({!r} : {!r})\n"
885
- " The transaction must be a list, not a tuple".format(state, event))
885
+ warn(f"- FSM removing action from context ({state!r} : {event!r})\n"
886
+ f" The transaction must be a list, not a tuple")
886
887
  return False
887
888
 
888
889
 
@@ -964,7 +965,7 @@ class TreeList(object):
964
965
  else:
965
966
  ls.append([key, value]) # append to items:list
966
967
  except (ValueError, TypeError, AttributeError) as e:
967
- print(f"- TreeList:warning {e!r}: {key=!r}")
968
+ warn(f"- TreeList:warning {e!r}: {key=!r}")
968
969
 
969
970
  def _delf(self, ls, key):
970
971
  if '/' in key:
mwx/wxmon.py CHANGED
@@ -3,12 +3,11 @@
3
3
 
4
4
  *** Inspired by wx.lib.eventwatcher ***
5
5
  """
6
- import warnings
7
6
  import wx
8
7
  import wx.lib.eventwatcher as ew
9
8
  from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
10
9
 
11
- from .utilus import where
10
+ from .utilus import where, ignore
12
11
  from .controls import Icon, Clipboard
13
12
  from .framework import CtrlInterface, Menu
14
13
 
@@ -176,8 +175,7 @@ class EventMonitor(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
176
175
  source = ew._makeSourceString(obj) + " id=0x{:X}".format(id(evt))
177
176
  stamp = 1
178
177
 
179
- with warnings.catch_warnings():
180
- warnings.simplefilter('ignore', DeprecationWarning)
178
+ with ignore(DeprecationWarning):
181
179
  attribs = ew._makeAttribString(evt)
182
180
 
183
181
  data = self.__items
@@ -232,7 +230,7 @@ class EventMonitor(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
232
230
  if self.IsSelected(i):
233
231
  event, name, *_, attribs = self.__items[i]
234
232
  text += "{}\t{}\n{}\n\n".format(event, name, attribs)
235
- Clipboard.write(text.strip('\n'))
233
+ Clipboard.write(text[:-1])
236
234
 
237
235
  def OnSortItems(self, evt): #<wx._controls.ListEvent>
238
236
  n = self.ItemCount
mwx/wxwil.py CHANGED
@@ -145,7 +145,7 @@ class LocalsWatcher(wx.ListCtrl, ListCtrlAutoWidthMixin, CtrlInterface):
145
145
  if self.IsSelected(i):
146
146
  key, vstr = self.__items[i]
147
147
  text += "{} = {}\n".format(key, vstr)
148
- Clipboard.write(text.strip('\n'))
148
+ Clipboard.write(text)
149
149
 
150
150
  def OnSortItems(self, evt): #<wx._controls.ListEvent>
151
151
  n = self.ItemCount
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mwxlib
3
- Version: 0.96.0
3
+ Version: 0.96.4
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
@@ -0,0 +1,28 @@
1
+ mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
2
+ mwx/bookshelf.py,sha256=CjcgtHC33KR5mHp1lW6Bqfndpzr7hC8ICkFihw4kM3g,5134
3
+ mwx/controls.py,sha256=JGoDEqfa0m5unISRcAdTxqCXihfuFo1mnLQcMimpGdc,48445
4
+ mwx/framework.py,sha256=bP9D868lzBecp1ZRYEv_GupYtior0AoiK6M8B-yxBvw,75249
5
+ mwx/graphman.py,sha256=eNL1Uja1m4g8ER3emArTFPZllvxEjvdnZTc1y8QMciE,71267
6
+ mwx/images.py,sha256=gyvqW4TLWdJMKmsaWiPiV_PuHJM1GbHgeELERLwGzg8,45291
7
+ mwx/matplot2.py,sha256=-G7z0Osozm9NjLfXvX5UcdFviwbNUktjbd904_g-PqQ,33516
8
+ mwx/matplot2g.py,sha256=22rpdkqJQEJADINPaG5htACutbt8oG1ewO8LMpxaqH4,65237
9
+ mwx/matplot2lg.py,sha256=MDbkO0vn5yi9rwTBCBJ4rsIHcWyoGXeNTbp0xfrvTdM,27381
10
+ mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
11
+ mwx/nutshell.py,sha256=HNo8ZuhLZPKd_Cg4s9NN-KfuSXHRP_jaw1s59GVXkN4,136971
12
+ mwx/utilus.py,sha256=jTjeunx_9-HrjdWaceX1Xeq3pHMS4M7M9ma2i4uhKJY,37369
13
+ mwx/wxmon.py,sha256=f3V24EF7kdMlYF7usLYK9QE5KU6fSu0jVqsvwAiA-Ag,12647
14
+ mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
15
+ mwx/wxwil.py,sha256=0bzSTfMEjllJheKxZPb4p8Luz6Il3V29bCLBty72U2o,5576
16
+ mwx/wxwit.py,sha256=yU6XeCCWRBP7CLmpphjT072PfXAL30DNaxoChDX2p0I,7322
17
+ mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
+ mwx/plugins/ffmpeg_view.py,sha256=wZXRgsiPyIphcA8hvXQoE7NZp4cc_YBOO0ZpuKmUJKE,9369
19
+ mwx/plugins/fft_view.py,sha256=HcnBr-y_yFdSfASPRzMLANta4SwSDShd65QWnCU3XhM,2665
20
+ mwx/plugins/frame_listview.py,sha256=Li993CV0pPY23Jb8cGQkc3wVeDlHWLEe8RuDbNZeB8s,10351
21
+ mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
+ mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
+ mwx/py/filling.py,sha256=KaHooM32hrGGgqw75Cbt8lAvACwC6RXadob9LGgNnEc,16806
24
+ mwxlib-0.96.4.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
+ mwxlib-0.96.4.dist-info/METADATA,sha256=z1bx81IMuasnA9ZGE1vUidxqqh7cOC_LmB-Rdrqd0xw,1925
26
+ mwxlib-0.96.4.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
27
+ mwxlib-0.96.4.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
+ mwxlib-0.96.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.0)
2
+ Generator: setuptools (70.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,28 +0,0 @@
1
- mwx/__init__.py,sha256=nN62CGTWjME7Zz2h-jIRB8MxwuErIkHPGrlBzydkF0o,643
2
- mwx/bookshelf.py,sha256=DAhMQk3_J4rdE50adBMFu5wNz3WdMh_zzJ37O9ncceo,5103
3
- mwx/controls.py,sha256=IAT3l3-azlPFtMc2VGNMiQhI390ExW0S4CgjEOKFI4s,48200
4
- mwx/framework.py,sha256=Z-WbpepmraX_7wCq4jWpOCeDhUrUO5NlOmFLf2RjoLk,75666
5
- mwx/graphman.py,sha256=4SRwCMs4-sS3n23FthythhuG9dBJ8TLz_TVyoYAbdoA,70639
6
- mwx/images.py,sha256=gyvqW4TLWdJMKmsaWiPiV_PuHJM1GbHgeELERLwGzg8,45291
7
- mwx/matplot2.py,sha256=-G7z0Osozm9NjLfXvX5UcdFviwbNUktjbd904_g-PqQ,33516
8
- mwx/matplot2g.py,sha256=Ii0y4Ebod-9EJ-WPaCyZ-voM5uC3MTDmNktJD7OiTtA,65496
9
- mwx/matplot2lg.py,sha256=pcu1oDPE_BlpFqNGPPKf9vpTuDs_h_u3OTRAJx5-Sds,27392
10
- mwx/mgplt.py,sha256=ITzxA97yDwr_35BUk5OqnyskSuKVDbpf2AQCKY1jHTI,5671
11
- mwx/nutshell.py,sha256=pbsQATwt906lOXGFWJmuwZIwU_ve78o46I2g5zNjvG4,137050
12
- mwx/utilus.py,sha256=Uwj6vbNUUztwOswPG75xtsT2y_PZqh3QiJraxmA9iT0,37401
13
- mwx/wxmon.py,sha256=6es-jVz9Ht7vZnG7VBJcaNYLHY0PnZtij60SXcZRTeY,12727
14
- mwx/wxpdb.py,sha256=lLowkkAgMhPFHAfklD7wZHq0qbSMjRxnBFtSajmVgME,19133
15
- mwx/wxwil.py,sha256=zP1-5Fpi1wpDQU977229zIH6QRuSkkyfuAlNKWjGoGg,5588
16
- mwx/wxwit.py,sha256=yU6XeCCWRBP7CLmpphjT072PfXAL30DNaxoChDX2p0I,7322
17
- mwx/plugins/__init__.py,sha256=jnJ-Sl9XJ_7BFDslD_r7dsbxsOT57q_IaEriV53XIGY,41
18
- mwx/plugins/ffmpeg_view.py,sha256=wZXRgsiPyIphcA8hvXQoE7NZp4cc_YBOO0ZpuKmUJKE,9369
19
- mwx/plugins/fft_view.py,sha256=HcnBr-y_yFdSfASPRzMLANta4SwSDShd65QWnCU3XhM,2665
20
- mwx/plugins/frame_listview.py,sha256=RaYOj-YKrpLqhT8TkBRDX1TQnSPv90V185j8OjrWJTs,10108
21
- mwx/plugins/line_profile.py,sha256=--9NIc3x5EfRB3L59JvD7rzENQHyiYfu7wWJo6AuMkA,820
22
- mwx/py/__init__.py,sha256=xykgfOytOwNuvXsfkLoumFZSTN-iBsHOjczYXngjmUE,12
23
- mwx/py/filling.py,sha256=KaHooM32hrGGgqw75Cbt8lAvACwC6RXadob9LGgNnEc,16806
24
- mwxlib-0.96.0.dist-info/LICENSE,sha256=PGtRKCaTkmUDlBQwpptJAxJtdqxIUtAmdBsaT9nUVkA,1091
25
- mwxlib-0.96.0.dist-info/METADATA,sha256=3UowIlnhpmH3yDgustsBu7iviC9fFKYIWtspEFsWYNs,1925
26
- mwxlib-0.96.0.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
27
- mwxlib-0.96.0.dist-info/top_level.txt,sha256=SI1Mh118AstnUFGPNq5aMNKiAnVNmZk1S9Ij-OwAEpY,4
28
- mwxlib-0.96.0.dist-info/RECORD,,