cubevis 1.0.5__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.5
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.6.1
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=5r6Y5ONIzSU_thM-yAxCzHItE5icKI7vVYvLzw3tQNc,33108
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
@@ -41,15 +41,16 @@ cubevis/bokeh/components/__init__.py,sha256=BQOqgBtlDpu6ENrY42nYeS73n2ZSMogJgM2L
41
41
  cubevis/bokeh/format/__init__.py,sha256=umNotXSRR23675c44x3h5h2ILbZX8xrDFCztvriYjEw,1424
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
- cubevis/bokeh/models/__init__.py,sha256=y_BApDwBYASuu95VVLNrNDs8VqElAp127b7ih5J9oho,199
44
+ cubevis/bokeh/models/__init__.py,sha256=3ICcAlkQXMvuAblh8wfcAA5aJFT2z_QN249pEITMR40,247
45
+ cubevis/bokeh/models/_bokeh_app_context.py,sha256=iHCFAJzFinX8I6ty3Vdw6w0Za-5qpoPpSNvbIbc3Q7M,4142
45
46
  cubevis/bokeh/models/_edit_span.py,sha256=7o59ZS0bF_Q_WtstvViWXP-2PiY_F7_zCecTqKcmz0E,196
46
47
  cubevis/bokeh/models/_ev_text_input.py,sha256=SGtefXkWK6jHEk4EneZ_hEUGwoIWwVGjwqLjGsAXMpY,158
47
48
  cubevis/bokeh/models/_shared_dict.py,sha256=AWjLMOKVAXWHSF4gcK2RbxF442QlzQ7hMR0oaODCqB0,901
48
- cubevis/bokeh/models/_showable.py,sha256=7_2qO2EGRk6iEy44AJv_KL5ff0UvDzOahgM6K8q0Nrs,14368
49
+ cubevis/bokeh/models/_showable.py,sha256=-X63iKaQgAI37cTB_23dvBgVPUrAq9KfLiKcxB-KCXo,15723
49
50
  cubevis/bokeh/models/_tip.py,sha256=yNoUWods0xxva1WOfh5It_Y8hbpVy8RVXUmm8p7a58M,1431
50
51
  cubevis/bokeh/models/_tip_button.py,sha256=mwk1C7BMVlZrAAyQLn45S4Q9GEQfU_wU2MWpO0Gwzj4,1610
51
52
  cubevis/bokeh/sources/__init__.py,sha256=4FsudFuVU4o7VG5OG3K1tiMoxIXcJWNz_K9yzMDE8ls,1581
52
- cubevis/bokeh/sources/_data_pipe.py,sha256=7E9UQOcqYTIzXUi_aYMkXn5INW8qTGqTxXaFp-k-mBw,19364
53
+ cubevis/bokeh/sources/_data_pipe.py,sha256=cGgaEW1p2ZwsY5Byi3C-FQFaVf9YB5YJ0m1BHyAt9k0,19823
53
54
  cubevis/bokeh/sources/_image_data_source.py,sha256=5sEWdfqoMk08HQ0JWg6bHJ34dWmphHm52nOZywSAE5c,3789
54
55
  cubevis/bokeh/sources/_image_pipe.py,sha256=pQ05VynLuJbedGja7aXDbVXFkOYbdMceOuOEj-QuluQ,28692
55
56
  cubevis/bokeh/sources/_spectra_data_source.py,sha256=qL1IOjSefWlycaqS4Pz5EHwg-1EwCVmNwxysP9lxDeM,2451
@@ -80,15 +81,15 @@ cubevis/exe/__init__.py,sha256=kH6dvUS_gjzlPxT1V-PU8ZCKvUTwIqJ-Es5UMfH9D9A,108
80
81
  cubevis/exe/_context.py,sha256=hcfn1YYXeIo8Jl_2HV0m2D2Qpo9z4qOunMJovThNctE,5676
81
82
  cubevis/exe/_mode.py,sha256=s7i19DY_BWESgqKdRQRnQaR5EK52rym4yu2eSylOHgA,139
82
83
  cubevis/exe/_setting.py,sha256=pND6qyQV69N5Y5pW7E8phesEAaGjDE45ASvUtlHPPUE,92
83
- cubevis/exe/_task.py,sha256=eslV_iUsDLaDqSkNLNEtzQg73FC9NJJLsPBss5TqFvA,10912
84
+ cubevis/exe/_task.py,sha256=L5w3wjOJmjrlzYtmNmX__uRugXgVb49CeeALwCEuzrU,11664
84
85
  cubevis/private/_gclean.py,sha256=ExdR6cRxSa6Xne2veGNKhbTtx-tXUIWr2htzEmEZ9Z4,41107
85
86
  cubevis/private/apps/__init__.py,sha256=eQg28HPmEskRVJDQviUyuXroBKpUxocaj0Snk-VBaW4,2927
86
- cubevis/private/apps/_createmask.py,sha256=kLwb138M3CyZWG2MIv0-1jdpxjpelmroY_85KlSJptA,23592
87
- cubevis/private/apps/_createregion.py,sha256=OHZzTUaQ8Ofl5xt2mCrhXEDkfED-B3TxL-TCi7EXVeo,26724
88
- cubevis/private/apps/_interactiveclean.mustache,sha256=fM6-8p1DrWcxNHx9YY1zQUn9trfvKqKekJAOHlLZ96o,3776
89
- cubevis/private/apps/_interactiveclean.py,sha256=QRPqR7uDQhrMz1FZ1E_OvWB6w1p9U0c4s33VMGCgff8,139277
90
- cubevis/private/apps/_interactivecleannotebook.mustache,sha256=TqWMC2rFHIhwsoz--d0RFaKAfPPbvU7wjlwuWHgRhpM,4494
91
- 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
92
93
  cubevis/private/apps/_plotants.py,sha256=top6VWVd_sE48IVPH_sIg3_sQeDl5tadi5DL7r5tUEI,10823
93
94
  cubevis/private/apps/_plotbandpass.py,sha256=NwOgKSRnpLw9Pt3KIdBpoV78q1OnjCvj6lWFqeyICt8,185
94
95
  cubevis/private/casashell/createmask.py,sha256=C1eSUUsttSGghjZ5aDUVhRxnjir5MlYXVyxzEYLcI3k,14457
@@ -103,15 +104,15 @@ cubevis/remote/__init__.py,sha256=0LgSfWUw8cYnVrOYGq3o15tWJPkgcvTyYIrvRSAW6N8,12
103
104
  cubevis/remote/_gclean.py,sha256=TpmCmCUtMjqOFnA2wtYdp4EJo-59DyI00aaTWQbMQU4,1930
104
105
  cubevis/remote/_local.py,sha256=PcPCFcwttTFZd3O33-5pqDuGKQKK6CA0gz1MTIkTiNI,10326
105
106
  cubevis/remote/_remote_kernel.py,sha256=wfu7ZzKn-oCxZxzDIkC5puBvGf8WbCLYL3CzM56_FNc,2652
106
- cubevis/toolbox/__init__.py,sha256=xzqwAG9863d7UKBVBRw7FrRUQbvCdFcLBq4vTpg63DU,1487
107
+ cubevis/toolbox/__init__.py,sha256=sEN80BX91q_Z2zImDlT8oZ-0o8sE-iH7n3i4S1lmRLo,1450
107
108
  cubevis/toolbox/_app_context.py,sha256=rkjddiE4Ynf2HeyI0Hf8DOUt89bF67-2IlgD1uKSdOI,2908
108
- cubevis/toolbox/_cube.py,sha256=o-FSoq5giXbCVXdjDWWfEUGyvqV0Fw_QjP4EzHCmUZ8,306242
109
- cubevis/toolbox/_interactive_clean_ui.mustache,sha256=yUlZJLXfeAyDotXzJIriBcgAlrsIxG6-A1dm3Lvywng,111892
110
- cubevis/toolbox/_interactive_clean_ui.py,sha256=XKSrU1AK2YYrWQBjWbFe-dbuemHUZeCs-M71caPKn3w,111803
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
111
112
  cubevis/toolbox/_interactiveclean_wrappers.py,sha256=XqyCGz33CMDhszTxnwZ_3-64GszUK1XYnGKUOxl9sas,5071
112
113
  cubevis/toolbox/_region_list.py,sha256=_1RvnXwqMoaAq8CPy-6IyhabLi_snXqO566onehI2y0,8957
113
114
  cubevis/utils/_ResourceManager.py,sha256=SaaR29etabRiKxmUK-aWvAm4v_OPFJH8CX7bNFm0Lgo,3410
114
- cubevis/utils/__init__.py,sha256=-hSFUv8F4DgpbtZY3uznn65cuMoqsYxvb17U9iC_E9Y,27994
115
+ cubevis/utils/__init__.py,sha256=6u9bbkK_KY98qa6VJOGzjz0mwtKblbK63pxZ34OJ4mg,28048
115
116
  cubevis/utils/_browser.py,sha256=rmJ8_wq6XqhXZmVdmWI4t736qB-zd7ZbzfjVdVz40eY,261
116
117
  cubevis/utils/_contextmgrchain.py,sha256=r5SrCBdgQIVH7zXKOmq5oWhDUSeHaZpgsIfWFHvb3cQ,2859
117
118
  cubevis/utils/_conversion.py,sha256=SziCU8sOGtG7djlY766-MeOvnQgvT9C737FEfJ4aYsE,3262
@@ -121,12 +122,13 @@ cubevis/utils/_git.py,sha256=fLrwN40zm6fv3SKz3MSwj-wtUa9AslpwPPIYJNLzXik,1120
121
122
  cubevis/utils/_import_protected_module.py,sha256=AIISHPdiSzwgVzLXqHSWSHT-L7lcMWbYrsMlGlTFafE,1482
122
123
  cubevis/utils/_jupyter.py,sha256=37aNCGO52sOyklBQAR5eaAHkv-5NpmzCXPuTT7Euk0o,4214
123
124
  cubevis/utils/_logging.py,sha256=HqyoTib7QSuAUbzicPVMdhFtxWKo-Dv4GgD0AYDDXIY,2348
125
+ cubevis/utils/_mutual_exclusion.py,sha256=fkVsHPrFfeXdLSoZGw49ObxsTfwAeeJQTAcOCM2LvC8,3879
124
126
  cubevis/utils/_pkgs.py,sha256=mu2CCzndmJZYP81UkFhxveW_CisWLUvagJVolHOEVgM,2294
125
127
  cubevis/utils/_regions.py,sha256=TdAg4ZUUyhg3nFmX9_KLboqmc0LkyOdEW8M1WDR5Udk,1669
126
128
  cubevis/utils/_static.py,sha256=rN-sqXNqQ5R2M3wmPHU1GPP5OTyyWQlUPRuimCrht-g,2347
127
129
  cubevis/utils/_tiles.py,sha256=A9W1X61VOhBMTOKXVajzOIoiV2FBdO5N2SFB9SUpDOo,7336
128
- cubevis/__version__.py,sha256=c_ze905nYtc4YMhztpSDwQgaxCKfL3HM75hI5ocPNM8,21
129
- cubevis-1.0.5.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
130
- cubevis-1.0.5.dist-info/METADATA,sha256=YmIPxhCzfAwlsIXk0nAZGtzJrZEDL8tGdRN7NCBxO6w,2628
131
- cubevis-1.0.5.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
132
- cubevis-1.0.5.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,,