cubevis 1.0.14__py3-none-any.whl → 1.0.21__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.
@@ -0,0 +1,117 @@
1
+ import threading
2
+ from typing import Dict
3
+
4
+
5
+ class MutualExclusionManager:
6
+ """
7
+ Generic manager for enforcing mutual exclusion between different execution paths.
8
+
9
+ Use this when you want to ensure only one of several mutually exclusive paths
10
+ can be taken within a given context (thread).
11
+
12
+ Example:
13
+ mode_manager = MutualExclusionManager(
14
+ name="display_mode",
15
+ valid_modes={
16
+ 'notebook': "Cannot use Showable after displaying with bokeh.plotting.show().",
17
+ 'separate_tab': "Cannot use bokeh.plotting.show() after displaying with Showable."
18
+ }
19
+ )
20
+
21
+ # In path A:
22
+ mode_manager.set_mode('notebook')
23
+
24
+ # In path B (will raise error if path A was already taken):
25
+ mode_manager.set_mode('separate_tab')
26
+ """
27
+
28
+ def __init__(self, name: str, valid_modes: Dict[str, str]):
29
+ """
30
+ Args:
31
+ name: Descriptive name for this manager (used in error messages)
32
+ valid_modes: Dictionary mapping mode names to error messages to display
33
+ when that mode conflicts with an already-set mode.
34
+ """
35
+ self.name = name
36
+ self.valid_modes = valid_modes
37
+ self._local = threading.local()
38
+
39
+ def set_mode(self, mode: str):
40
+ """
41
+ Set the execution mode. Raises RuntimeError if a different mode was already set.
42
+
43
+ Args:
44
+ mode: The mode identifier to set
45
+
46
+ Raises:
47
+ ValueError: If mode is not in valid_modes
48
+ RuntimeError: If a different mode was already set in this context
49
+ """
50
+ if mode not in self.valid_modes:
51
+ raise ValueError(
52
+ f"Invalid mode '{mode}' for {self.name}. "
53
+ f"Valid modes: {set(self.valid_modes.keys())}"
54
+ )
55
+
56
+ current_mode = self.get_mode()
57
+ if current_mode is not None and current_mode != mode:
58
+ # Use the error message associated with the mode being set
59
+ error_message = self.valid_modes[mode]
60
+ raise RuntimeError(error_message)
61
+
62
+ self._local.mode = mode
63
+
64
+ def get_mode(self) -> str | None:
65
+ """
66
+ Get the current mode, or None if no mode has been set.
67
+
68
+ Returns:
69
+ The current mode string, or None
70
+ """
71
+ return getattr(self._local, 'mode', None)
72
+
73
+ def require_mode(self, mode: str):
74
+ """
75
+ Check that we're in the specified mode, set it if unset, error if different.
76
+
77
+ This is a convenience method that combines get_mode checking with set_mode.
78
+
79
+ Args:
80
+ mode: The required mode
81
+
82
+ Raises:
83
+ RuntimeError: If a different mode was already set
84
+ """
85
+ self.set_mode(mode)
86
+
87
+ def forbid_mode(self, mode: str, message: str | None = None):
88
+ """
89
+ Raise an error if the current mode matches the specified mode.
90
+
91
+ Args:
92
+ mode: The mode to forbid
93
+ message: Optional custom error message. If None, uses the message from valid_modes.
94
+
95
+ Raises:
96
+ RuntimeError: If current mode matches the forbidden mode
97
+ """
98
+ current_mode = self.get_mode()
99
+ if current_mode == mode:
100
+ if message is None:
101
+ message = self.valid_modes.get(
102
+ mode,
103
+ f"Cannot proceed: {self.name} is set to '{mode}', "
104
+ f"which is not allowed in this context."
105
+ )
106
+ raise RuntimeError(message)
107
+
108
+ def reset(self):
109
+ """
110
+ Reset the mode for this context. Useful for testing or manual mode switching.
111
+ """
112
+ if hasattr(self._local, 'mode'):
113
+ del self._local.mode
114
+
115
+ def __repr__(self):
116
+ mode = self.get_mode()
117
+ return f"MutualExclusionManager(name='{self.name}', current_mode={mode!r})"
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cubevis
3
- Version: 1.0.14
3
+ Version: 1.0.21
4
4
  Summary: visualization toolkit and apps for casa
5
5
  License: LGPL
6
6
  Author-email: Darrell Schiebel <darrell@schiebel.us>,Pam Harris <pharris@nrao.edu>
7
7
  Requires-Python: >=3.11
8
8
  Requires-Dist: astropy>=5.1
9
- Requires-Dist: bokeh<3.9,>=3.8
9
+ Requires-Dist: bokeh<3.9,>=3.6
10
10
  Requires-Dist: certifi
11
11
  Requires-Dist: matplotlib
12
12
  Requires-Dist: regions>=0.8
@@ -30,9 +30,9 @@ cubevis/__icons__/trash_full_raw.png,sha256=8ChZlNOqnDqmNhNYoqyLiGluYwJSYeQ2UvNL
30
30
  cubevis/__icons__/zoom-to-fit.png,sha256=aozGbrkoBX1q9kV0p272bg0YKGje1gIfVBkFZRlLAXs,9592
31
31
  cubevis/__icons__/zoom-to-fit.svg,sha256=NtYorWvH4s68iAMriqCPGuTBX5SsgVN310UXGKDM7i8,1802
32
32
  cubevis/__init__.py,sha256=c_7j2VgZ9yeRJOoFlzzQt-bQ_awlBMaaPJPSB0MNfcg,3233
33
- cubevis/__js__/bokeh-3.6/cubevisjs.min.js,sha256=F7HjEMjJpJOCCPIuydjOnv4oU1LNjHUJdsho8ZXbTnE,32149
34
- cubevis/__js__/bokeh-3.7/cubevisjs.min.js,sha256=pZ6xsZwdiVQ_oQiFN7N9sJDUCwHQy4KekPE5ycuFgn4,31088
35
- cubevis/__js__/bokeh-3.8/cubevisjs.min.js,sha256=KYALPxQSmcSUSbzlQwd7-2FE2TYbKbPY-mp2GgmFPac,35629
33
+ cubevis/__js__/bokeh-3.6/cubevisjs.min.js,sha256=bZ8IjciHZwcUMrrc_6a3n965WlPCMeQedZjb4-0Ln34,42526
34
+ cubevis/__js__/bokeh-3.7/cubevisjs.min.js,sha256=bZ8IjciHZwcUMrrc_6a3n965WlPCMeQedZjb4-0Ln34,42526
35
+ cubevis/__js__/bokeh-3.8/cubevisjs.min.js,sha256=bZ8IjciHZwcUMrrc_6a3n965WlPCMeQedZjb4-0Ln34,42526
36
36
  cubevis/__js__/casalib.min.js,sha256=J9Uvlat_Vf6cjcvftOG5COk3YH6A371MJ7s5u_ZS2_4,91133
37
37
  cubevis/bokeh/__init__.py,sha256=b2Vgszi7sQPFyu2b4fnQzVXk5uX4B9vb59CilQpP31I,1835
38
38
  cubevis/bokeh/annotations/__init__.py,sha256=tjDIPKbg-rh7Iu3coFWvmX-j2yNj9KuKmRp1aTo71ww,50
@@ -42,11 +42,11 @@ cubevis/bokeh/format/__init__.py,sha256=umNotXSRR23675c44x3h5h2ILbZX8xrDFCztvriY
42
42
  cubevis/bokeh/format/_time_ticks.py,sha256=j-DcPh7RfGE8iX2bPjLQDQPIbiAbmjiEWQnKmdMWA3I,1773
43
43
  cubevis/bokeh/format/_wcs_ticks.py,sha256=RtonOEc-QXzUNmwg3Ec9ONM5u1Sq8_x5CmRdUwQi5HA,2079
44
44
  cubevis/bokeh/models/__init__.py,sha256=3ICcAlkQXMvuAblh8wfcAA5aJFT2z_QN249pEITMR40,247
45
- cubevis/bokeh/models/_bokeh_app_context.py,sha256=ScF1mSkTnxOJj2NwWWHO_UtDZMx4CH2pF1vm64oYUWI,2209
45
+ cubevis/bokeh/models/_bokeh_app_context.py,sha256=iHCFAJzFinX8I6ty3Vdw6w0Za-5qpoPpSNvbIbc3Q7M,4142
46
46
  cubevis/bokeh/models/_edit_span.py,sha256=7o59ZS0bF_Q_WtstvViWXP-2PiY_F7_zCecTqKcmz0E,196
47
47
  cubevis/bokeh/models/_ev_text_input.py,sha256=SGtefXkWK6jHEk4EneZ_hEUGwoIWwVGjwqLjGsAXMpY,158
48
48
  cubevis/bokeh/models/_shared_dict.py,sha256=AWjLMOKVAXWHSF4gcK2RbxF442QlzQ7hMR0oaODCqB0,901
49
- cubevis/bokeh/models/_showable.py,sha256=7_2qO2EGRk6iEy44AJv_KL5ff0UvDzOahgM6K8q0Nrs,14368
49
+ cubevis/bokeh/models/_showable.py,sha256=-X63iKaQgAI37cTB_23dvBgVPUrAq9KfLiKcxB-KCXo,15723
50
50
  cubevis/bokeh/models/_tip.py,sha256=yNoUWods0xxva1WOfh5It_Y8hbpVy8RVXUmm8p7a58M,1431
51
51
  cubevis/bokeh/models/_tip_button.py,sha256=mwk1C7BMVlZrAAyQLn45S4Q9GEQfU_wU2MWpO0Gwzj4,1610
52
52
  cubevis/bokeh/sources/__init__.py,sha256=4FsudFuVU4o7VG5OG3K1tiMoxIXcJWNz_K9yzMDE8ls,1581
@@ -81,15 +81,15 @@ cubevis/exe/__init__.py,sha256=kH6dvUS_gjzlPxT1V-PU8ZCKvUTwIqJ-Es5UMfH9D9A,108
81
81
  cubevis/exe/_context.py,sha256=hcfn1YYXeIo8Jl_2HV0m2D2Qpo9z4qOunMJovThNctE,5676
82
82
  cubevis/exe/_mode.py,sha256=s7i19DY_BWESgqKdRQRnQaR5EK52rym4yu2eSylOHgA,139
83
83
  cubevis/exe/_setting.py,sha256=pND6qyQV69N5Y5pW7E8phesEAaGjDE45ASvUtlHPPUE,92
84
- cubevis/exe/_task.py,sha256=eslV_iUsDLaDqSkNLNEtzQg73FC9NJJLsPBss5TqFvA,10912
84
+ cubevis/exe/_task.py,sha256=L5w3wjOJmjrlzYtmNmX__uRugXgVb49CeeALwCEuzrU,11664
85
85
  cubevis/private/_gclean.py,sha256=ExdR6cRxSa6Xne2veGNKhbTtx-tXUIWr2htzEmEZ9Z4,41107
86
86
  cubevis/private/apps/__init__.py,sha256=eQg28HPmEskRVJDQviUyuXroBKpUxocaj0Snk-VBaW4,2927
87
- cubevis/private/apps/_createmask.py,sha256=kLwb138M3CyZWG2MIv0-1jdpxjpelmroY_85KlSJptA,23592
88
- cubevis/private/apps/_createregion.py,sha256=OHZzTUaQ8Ofl5xt2mCrhXEDkfED-B3TxL-TCi7EXVeo,26724
89
- cubevis/private/apps/_interactiveclean.mustache,sha256=fM6-8p1DrWcxNHx9YY1zQUn9trfvKqKekJAOHlLZ96o,3776
90
- cubevis/private/apps/_interactiveclean.py,sha256=QRPqR7uDQhrMz1FZ1E_OvWB6w1p9U0c4s33VMGCgff8,139277
91
- cubevis/private/apps/_interactivecleannotebook.mustache,sha256=TqWMC2rFHIhwsoz--d0RFaKAfPPbvU7wjlwuWHgRhpM,4494
92
- cubevis/private/apps/_interactivecleannotebook.py,sha256=0N65GJG4D9vKWnl1lMNpNuKotQpy8NePkB97cdc-uI8,139995
87
+ cubevis/private/apps/_createmask.py,sha256=MTsN47vuOu2iYjjQGHprnHWdJWTQea7clrTSG8TYtzY,23240
88
+ cubevis/private/apps/_createregion.py,sha256=Q5YmYOeh46WPN7xMite4OAUFpHSZtAFTvJD4R6bsjpY,27020
89
+ cubevis/private/apps/_interactiveclean.mustache,sha256=G8itL37DlLZU4Vxe24Sh6DM4aUFmoQSylALC1ktAiSg,3825
90
+ cubevis/private/apps/_interactiveclean.py,sha256=2N-FV8CcDyqVKpbktaaxIfP5RK2Dv71DWsDRxuUIan8,139326
91
+ cubevis/private/apps/_interactivecleannotebook.mustache,sha256=haJG7huuBCq8h9EwKaWQNsPEdOjTd5yLw9GUJxPr_jM,5251
92
+ cubevis/private/apps/_interactivecleannotebook.py,sha256=LJS9wRggRt2swJqWhDK3XRuS0ACGPGho5c5tjcm9-TI,140752
93
93
  cubevis/private/apps/_plotants.py,sha256=top6VWVd_sE48IVPH_sIg3_sQeDl5tadi5DL7r5tUEI,10823
94
94
  cubevis/private/apps/_plotbandpass.py,sha256=NwOgKSRnpLw9Pt3KIdBpoV78q1OnjCvj6lWFqeyICt8,185
95
95
  cubevis/private/casashell/createmask.py,sha256=C1eSUUsttSGghjZ5aDUVhRxnjir5MlYXVyxzEYLcI3k,14457
@@ -104,15 +104,15 @@ cubevis/remote/__init__.py,sha256=0LgSfWUw8cYnVrOYGq3o15tWJPkgcvTyYIrvRSAW6N8,12
104
104
  cubevis/remote/_gclean.py,sha256=TpmCmCUtMjqOFnA2wtYdp4EJo-59DyI00aaTWQbMQU4,1930
105
105
  cubevis/remote/_local.py,sha256=PcPCFcwttTFZd3O33-5pqDuGKQKK6CA0gz1MTIkTiNI,10326
106
106
  cubevis/remote/_remote_kernel.py,sha256=wfu7ZzKn-oCxZxzDIkC5puBvGf8WbCLYL3CzM56_FNc,2652
107
- cubevis/toolbox/__init__.py,sha256=xzqwAG9863d7UKBVBRw7FrRUQbvCdFcLBq4vTpg63DU,1487
107
+ cubevis/toolbox/__init__.py,sha256=sEN80BX91q_Z2zImDlT8oZ-0o8sE-iH7n3i4S1lmRLo,1450
108
108
  cubevis/toolbox/_app_context.py,sha256=rkjddiE4Ynf2HeyI0Hf8DOUt89bF67-2IlgD1uKSdOI,2908
109
- cubevis/toolbox/_cube.py,sha256=o-FSoq5giXbCVXdjDWWfEUGyvqV0Fw_QjP4EzHCmUZ8,306242
110
- cubevis/toolbox/_interactive_clean_ui.mustache,sha256=jDhATZohY14ntaG3N30E_gnf7uHkr4JwxXQmEYPwD4g,111937
111
- cubevis/toolbox/_interactive_clean_ui.py,sha256=N_TYgp8U-M6-A_5aNZaieIhwT-qhbkbPhc2ULaDuTDc,111848
109
+ cubevis/toolbox/_cube.py,sha256=yNVeRFU3ZIM3FeOG4gsy2l6u7gnyqnFlQ6GzQ1fqIg4,308223
110
+ cubevis/toolbox/_interactive_clean_ui.mustache,sha256=IVTcqkxIyw7SzfU92_70dG7bF9UapromDdmeukQ90cg,114113
111
+ cubevis/toolbox/_interactive_clean_ui.py,sha256=98KnLZnDXqO5xl7Ie7WpirogtKL0a5myHejsC89CVSU,114024
112
112
  cubevis/toolbox/_interactiveclean_wrappers.py,sha256=XqyCGz33CMDhszTxnwZ_3-64GszUK1XYnGKUOxl9sas,5071
113
113
  cubevis/toolbox/_region_list.py,sha256=_1RvnXwqMoaAq8CPy-6IyhabLi_snXqO566onehI2y0,8957
114
114
  cubevis/utils/_ResourceManager.py,sha256=SaaR29etabRiKxmUK-aWvAm4v_OPFJH8CX7bNFm0Lgo,3410
115
- cubevis/utils/__init__.py,sha256=-hSFUv8F4DgpbtZY3uznn65cuMoqsYxvb17U9iC_E9Y,27994
115
+ cubevis/utils/__init__.py,sha256=6u9bbkK_KY98qa6VJOGzjz0mwtKblbK63pxZ34OJ4mg,28048
116
116
  cubevis/utils/_browser.py,sha256=rmJ8_wq6XqhXZmVdmWI4t736qB-zd7ZbzfjVdVz40eY,261
117
117
  cubevis/utils/_contextmgrchain.py,sha256=r5SrCBdgQIVH7zXKOmq5oWhDUSeHaZpgsIfWFHvb3cQ,2859
118
118
  cubevis/utils/_conversion.py,sha256=SziCU8sOGtG7djlY766-MeOvnQgvT9C737FEfJ4aYsE,3262
@@ -122,12 +122,13 @@ cubevis/utils/_git.py,sha256=fLrwN40zm6fv3SKz3MSwj-wtUa9AslpwPPIYJNLzXik,1120
122
122
  cubevis/utils/_import_protected_module.py,sha256=AIISHPdiSzwgVzLXqHSWSHT-L7lcMWbYrsMlGlTFafE,1482
123
123
  cubevis/utils/_jupyter.py,sha256=37aNCGO52sOyklBQAR5eaAHkv-5NpmzCXPuTT7Euk0o,4214
124
124
  cubevis/utils/_logging.py,sha256=HqyoTib7QSuAUbzicPVMdhFtxWKo-Dv4GgD0AYDDXIY,2348
125
+ cubevis/utils/_mutual_exclusion.py,sha256=fkVsHPrFfeXdLSoZGw49ObxsTfwAeeJQTAcOCM2LvC8,3879
125
126
  cubevis/utils/_pkgs.py,sha256=mu2CCzndmJZYP81UkFhxveW_CisWLUvagJVolHOEVgM,2294
126
127
  cubevis/utils/_regions.py,sha256=TdAg4ZUUyhg3nFmX9_KLboqmc0LkyOdEW8M1WDR5Udk,1669
127
128
  cubevis/utils/_static.py,sha256=rN-sqXNqQ5R2M3wmPHU1GPP5OTyyWQlUPRuimCrht-g,2347
128
129
  cubevis/utils/_tiles.py,sha256=A9W1X61VOhBMTOKXVajzOIoiV2FBdO5N2SFB9SUpDOo,7336
129
- cubevis/__version__.py,sha256=3X90f6HGpDfnyIIIVOe0gXw8CJq4nN8scff1OJoFAmk,22
130
- cubevis-1.0.14.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
131
- cubevis-1.0.14.dist-info/METADATA,sha256=Wu2Q1pdn4LY_7zwhqg8tbR7lVyTsJYOxKPvox9dIUQg,2632
132
- cubevis-1.0.14.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
133
- cubevis-1.0.14.dist-info/RECORD,,
130
+ cubevis/__version__.py,sha256=V8mcjgjAaALTQgu46QC6JsqtVhIuwUw8ouH3h3lkBi8,22
131
+ cubevis-1.0.21.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
132
+ cubevis-1.0.21.dist-info/METADATA,sha256=CocE5gz6awIhYzmwtQys8x8sn1qM4Wg05D_fAuHELJQ,2632
133
+ cubevis-1.0.21.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
134
+ cubevis-1.0.21.dist-info/RECORD,,