streamlit-nightly 1.33.1.dev20240416__py2.py3-none-any.whl → 1.33.1.dev20240418__py2.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.
Files changed (44) hide show
  1. streamlit/components/v1/custom_component.py +2 -0
  2. streamlit/delta_generator.py +0 -5
  3. streamlit/elements/__init__.py +0 -57
  4. streamlit/elements/arrow_vega_lite.py +8 -1
  5. streamlit/elements/form.py +5 -1
  6. streamlit/elements/spinner.py +16 -30
  7. streamlit/elements/utils.py +36 -1
  8. streamlit/elements/widgets/button.py +20 -1
  9. streamlit/elements/widgets/camera_input.py +3 -0
  10. streamlit/elements/widgets/chat.py +8 -1
  11. streamlit/elements/widgets/checkbox.py +3 -1
  12. streamlit/elements/widgets/color_picker.py +3 -0
  13. streamlit/elements/widgets/data_editor.py +10 -1
  14. streamlit/elements/widgets/file_uploader.py +3 -0
  15. streamlit/elements/widgets/multiselect.py +13 -6
  16. streamlit/elements/widgets/number_input.py +8 -0
  17. streamlit/elements/widgets/radio.py +9 -0
  18. streamlit/elements/widgets/select_slider.py +4 -0
  19. streamlit/elements/widgets/selectbox.py +8 -1
  20. streamlit/elements/widgets/slider.py +3 -1
  21. streamlit/elements/widgets/text_widgets.py +13 -2
  22. streamlit/elements/widgets/time_widgets.py +27 -10
  23. streamlit/runtime/caching/__init__.py +1 -19
  24. streamlit/runtime/caching/cache_data_api.py +8 -2
  25. streamlit/runtime/caching/cache_errors.py +0 -38
  26. streamlit/runtime/caching/cache_resource_api.py +8 -2
  27. streamlit/runtime/caching/cache_utils.py +26 -9
  28. streamlit/runtime/caching/cached_message_replay.py +25 -67
  29. streamlit/runtime/fragment.py +1 -1
  30. streamlit/runtime/legacy_caching/__init__.py +2 -12
  31. streamlit/runtime/legacy_caching/caching.py +1 -80
  32. streamlit/runtime/scriptrunner/script_run_context.py +4 -0
  33. streamlit/static/asset-manifest.json +3 -3
  34. streamlit/static/index.html +1 -1
  35. streamlit/static/static/js/43.b0aa5759.chunk.js +1 -0
  36. streamlit/static/static/js/{main.713dd29d.js → main.81ad100d.js} +2 -2
  37. {streamlit_nightly-1.33.1.dev20240416.dist-info → streamlit_nightly-1.33.1.dev20240418.dist-info}/METADATA +3 -3
  38. {streamlit_nightly-1.33.1.dev20240416.dist-info → streamlit_nightly-1.33.1.dev20240418.dist-info}/RECORD +43 -43
  39. streamlit/static/static/js/43.9ae03282.chunk.js +0 -1
  40. /streamlit/static/static/js/{main.713dd29d.js.LICENSE.txt → main.81ad100d.js.LICENSE.txt} +0 -0
  41. {streamlit_nightly-1.33.1.dev20240416.data → streamlit_nightly-1.33.1.dev20240418.data}/scripts/streamlit.cmd +0 -0
  42. {streamlit_nightly-1.33.1.dev20240416.dist-info → streamlit_nightly-1.33.1.dev20240418.dist-info}/WHEEL +0 -0
  43. {streamlit_nightly-1.33.1.dev20240416.dist-info → streamlit_nightly-1.33.1.dev20240418.dist-info}/entry_points.txt +0 -0
  44. {streamlit_nightly-1.33.1.dev20240416.dist-info → streamlit_nightly-1.33.1.dev20240418.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any
20
20
  from streamlit import _main, type_util
21
21
  from streamlit.components.types.base_custom_component import BaseCustomComponent
22
22
  from streamlit.elements.form import current_form_id
23
+ from streamlit.elements.utils import check_cache_replay_rules
23
24
  from streamlit.errors import StreamlitAPIException
24
25
  from streamlit.proto.Components_pb2 import ArrowTable as ArrowTableProto
25
26
  from streamlit.proto.Components_pb2 import SpecialArg
@@ -101,6 +102,7 @@ PyArrow. To do so locally:
101
102
  And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
102
103
  )
103
104
 
105
+ check_cache_replay_rules()
104
106
  # In addition to the custom kwargs passed to the component, we also
105
107
  # send the special 'default' and 'key' params to the component
106
108
  # frontend.
@@ -528,11 +528,6 @@ class DeltaGenerator(
528
528
  "call your fragment function inside a `with st.sidebar` context manager."
529
529
  )
530
530
 
531
- # Warn if we're called from within a legacy @st.cache function
532
- legacy_caching.maybe_show_cached_st_function_warning(dg, delta_type)
533
- # Warn if we're called from within @st.memo or @st.singleton
534
- caching.maybe_show_cached_st_function_warning(dg, delta_type)
535
-
536
531
  # Warn if an element is being changed but the user isn't running the streamlit server.
537
532
  _maybe_print_use_warning()
538
533
 
@@ -11,60 +11,3 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
15
- WIDGETS = [
16
- "button",
17
- "camera_input",
18
- "chat_input",
19
- "checkbox",
20
- "color_picker",
21
- "component_instance",
22
- "download_button",
23
- "file_uploader",
24
- "form",
25
- "multiselect",
26
- "number_input",
27
- "radio",
28
- "selectbox",
29
- "select_slider",
30
- "slider",
31
- "text_input",
32
- "text_area",
33
- "time_input",
34
- "date_input",
35
- ]
36
- NONWIDGET_ELEMENTS = [
37
- "alert",
38
- "arrow_area_chart",
39
- "arrow_bar_chart",
40
- "arrow_data_frame",
41
- "arrow_line_chart",
42
- "arrow_table",
43
- "arrow_vega_lite_chart",
44
- "audio",
45
- "balloons",
46
- "bokeh_chart",
47
- "code",
48
- "deck_gl_json_chart",
49
- "doc_string",
50
- "empty",
51
- "exception",
52
- "graphviz_chart",
53
- "heading",
54
- "iframe",
55
- "imgs",
56
- "json",
57
- # link_button unlike button and download_button is not a widget. It only sends a
58
- # forward messages to the frontend, and not sends trigger value back.
59
- "link_button",
60
- "markdown",
61
- "metric",
62
- "page_link",
63
- "plotly_chart",
64
- "progress",
65
- "pyplot",
66
- "snow",
67
- "text",
68
- "video",
69
- "write",
70
- ]
@@ -155,7 +155,14 @@ def marshall(
155
155
  raise ValueError("Vega-Lite charts require a non-empty spec dict.")
156
156
 
157
157
  if "autosize" not in spec:
158
- spec["autosize"] = {"type": "fit", "contains": "padding"}
158
+ # type fit does not work for many chart types. This change focuses
159
+ # on vconcat with use_container_width=True as there are unintended
160
+ # consequences of changing the default autosize for all charts.
161
+ # fit-x fits the width and height can be adjusted.
162
+ if "vconcat" in spec and use_container_width:
163
+ spec["autosize"] = {"type": "fit-x", "contains": "padding"}
164
+ else:
165
+ spec["autosize"] = {"type": "fit", "contains": "padding"}
159
166
 
160
167
  # Pull data out of spec dict when it's in a 'datasets' key:
161
168
  # marshall(proto, {datasets: {foo: df1, bar: df2}, ...})
@@ -194,11 +194,15 @@ class FormMixin:
194
194
 
195
195
  """
196
196
  # Import this here to avoid circular imports.
197
- from streamlit.elements.utils import check_session_state_rules
197
+ from streamlit.elements.utils import (
198
+ check_cache_replay_rules,
199
+ check_session_state_rules,
200
+ )
198
201
 
199
202
  if is_in_form(self.dg):
200
203
  raise StreamlitAPIException("Forms cannot be nested in other forms.")
201
204
 
205
+ check_cache_replay_rules()
202
206
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
203
207
 
204
208
  # A form is uniquely identified by its key.
@@ -42,20 +42,10 @@ def spinner(text: str = "In progress...", *, _cache: bool = False) -> Iterator[N
42
42
  >>> st.success('Done!')
43
43
 
44
44
  """
45
- import streamlit.runtime.caching as caching
46
- import streamlit.runtime.legacy_caching.caching as legacy_caching
47
45
  from streamlit.proto.Spinner_pb2 import Spinner as SpinnerProto
48
46
  from streamlit.string_util import clean_text
49
47
 
50
- # @st.cache optionally uses spinner for long-running computations.
51
- # Normally, streamlit warns the user when they call st functions
52
- # from within an @st.cache'd function. But we do *not* want to show
53
- # these warnings for spinner's message, so we create and mutate this
54
- # message delta within the "suppress_cached_st_function_warning"
55
- # context.
56
- with legacy_caching.suppress_cached_st_function_warning():
57
- with caching.suppress_cached_st_function_warning():
58
- message = st.empty()
48
+ message = st.empty()
59
49
 
60
50
  # Set the message 0.5 seconds in the future to avoid annoying
61
51
  # flickering if this spinner runs too quickly.
@@ -68,12 +58,10 @@ def spinner(text: str = "In progress...", *, _cache: bool = False) -> Iterator[N
68
58
  def set_message():
69
59
  with display_message_lock:
70
60
  if display_message:
71
- with legacy_caching.suppress_cached_st_function_warning():
72
- with caching.suppress_cached_st_function_warning():
73
- spinner_proto = SpinnerProto()
74
- spinner_proto.text = clean_text(text)
75
- spinner_proto.cache = _cache
76
- message._enqueue("spinner", spinner_proto)
61
+ spinner_proto = SpinnerProto()
62
+ spinner_proto.text = clean_text(text)
63
+ spinner_proto.cache = _cache
64
+ message._enqueue("spinner", spinner_proto)
77
65
 
78
66
  add_script_run_ctx(threading.Timer(DELAY_SECS, set_message)).start()
79
67
 
@@ -83,16 +71,14 @@ def spinner(text: str = "In progress...", *, _cache: bool = False) -> Iterator[N
83
71
  if display_message_lock:
84
72
  with display_message_lock:
85
73
  display_message = False
86
- with legacy_caching.suppress_cached_st_function_warning():
87
- with caching.suppress_cached_st_function_warning():
88
- if "chat_message" in set(message._active_dg._ancestor_block_types):
89
- # Temporary stale element fix:
90
- # For chat messages, we are resetting the spinner placeholder to an
91
- # empty container instead of an empty placeholder (st.empty) to have
92
- # it removed from the delta path. Empty containers are ignored in the
93
- # frontend since they are configured with allow_empty=False. This
94
- # prevents issues with stale elements caused by the spinner being
95
- # rendered only in some situations (e.g. for caching).
96
- message.container()
97
- else:
98
- message.empty()
74
+ if "chat_message" in set(message._active_dg._ancestor_block_types):
75
+ # Temporary stale element fix:
76
+ # For chat messages, we are resetting the spinner placeholder to an
77
+ # empty container instead of an empty placeholder (st.empty) to have
78
+ # it removed from the delta path. Empty containers are ignored in the
79
+ # frontend since they are configured with allow_empty=False. This
80
+ # prevents issues with stale elements caused by the spinner being
81
+ # rendered only in some situations (e.g. for caching).
82
+ message.container()
83
+ else:
84
+ message.empty()
@@ -20,7 +20,7 @@ from typing import TYPE_CHECKING, Any, Hashable, Iterable, Sequence, cast, overl
20
20
  import streamlit
21
21
  from streamlit import config, runtime, type_util
22
22
  from streamlit.elements.form import is_in_form
23
- from streamlit.errors import StreamlitAPIException
23
+ from streamlit.errors import StreamlitAPIException, StreamlitAPIWarning
24
24
  from streamlit.proto.LabelVisibilityMessage_pb2 import LabelVisibilityMessage
25
25
  from streamlit.runtime.state import WidgetCallback, get_session_state
26
26
  from streamlit.runtime.state.common import RegisterWidgetResult
@@ -86,6 +86,41 @@ def check_session_state_rules(
86
86
  _shown_default_value_warning = True
87
87
 
88
88
 
89
+ class CachedWidgetWarning(StreamlitAPIWarning):
90
+ def __init__(self):
91
+ super().__init__(
92
+ """
93
+ Your script uses a widget command in a cached function
94
+ (function decorated with `@st.cache_data` or `@st.cache_resource`).
95
+ This code will only be called when we detect a cache "miss",
96
+ which can lead to unexpected results.
97
+
98
+ How to fix this:
99
+ * Move all widget commands outside the cached function.
100
+ * Or, if you know what you're doing, use `experimental_allow_widgets=True`
101
+ in the cache decorator to enable widget replay and suppress this warning.
102
+ """
103
+ )
104
+
105
+
106
+ def check_cache_replay_rules() -> None:
107
+ """Check if a widget is allowed to be used in the current context.
108
+ More specifically, this checks if the current context is inside a
109
+ cached function that disallows widget usage. If so, it raises a warning.
110
+
111
+ If there are other similar checks in the future, we could extend this
112
+ function to check for those as well. And rename it to check_widget_usage_rules.
113
+ """
114
+ if runtime.exists():
115
+ from streamlit.runtime.scriptrunner.script_run_context import get_script_run_ctx
116
+
117
+ ctx = get_script_run_ctx()
118
+ if ctx and ctx.disallow_cached_widget_usage:
119
+ # We use an exception here to show a proper stack trace
120
+ # that indicates to the user where the issue is.
121
+ streamlit.exception(CachedWidgetWarning())
122
+
123
+
89
124
  def get_label_visibility_proto_value(
90
125
  label_visibility_string: type_util.LabelVisibility,
91
126
  ) -> LabelVisibilityMessage.LabelVisibilityOptions.ValueType:
@@ -24,7 +24,6 @@ from typing_extensions import TypeAlias
24
24
 
25
25
  from streamlit import runtime, source_util
26
26
  from streamlit.elements.form import current_form_id, is_in_form
27
- from streamlit.elements.utils import check_callback_rules, check_session_state_rules
28
27
  from streamlit.errors import StreamlitAPIException
29
28
  from streamlit.file_util import get_main_script_directory, normalize_path_join
30
29
  from streamlit.proto.Button_pb2 import Button as ButtonProto
@@ -551,7 +550,17 @@ class ButtonMixin:
551
550
  ctx: ScriptRunContext | None = None,
552
551
  ) -> bool:
553
552
  key = to_key(key)
553
+
554
+ # Importing these functions here to avoid circular imports
555
+ from streamlit.elements.utils import (
556
+ check_cache_replay_rules,
557
+ check_callback_rules,
558
+ check_session_state_rules,
559
+ )
560
+
561
+ check_cache_replay_rules()
554
562
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
563
+ check_callback_rules(self.dg, on_click)
555
564
 
556
565
  id = compute_widget_id(
557
566
  "download_button",
@@ -704,8 +713,18 @@ class ButtonMixin:
704
713
  use_container_width: bool = False,
705
714
  ctx: ScriptRunContext | None = None,
706
715
  ) -> bool:
716
+ key = to_key(key)
717
+
718
+ # Importing these functions here to avoid circular imports
719
+ from streamlit.elements.utils import (
720
+ check_cache_replay_rules,
721
+ check_callback_rules,
722
+ check_session_state_rules,
723
+ )
724
+
707
725
  if not is_form_submitter:
708
726
  check_callback_rules(self.dg, on_click)
727
+ check_cache_replay_rules()
709
728
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
710
729
 
711
730
  id = compute_widget_id(
@@ -22,6 +22,7 @@ from typing_extensions import TypeAlias
22
22
 
23
23
  from streamlit.elements.form import current_form_id
24
24
  from streamlit.elements.utils import (
25
+ check_cache_replay_rules,
25
26
  check_callback_rules,
26
27
  check_session_state_rules,
27
28
  get_label_visibility_proto_value,
@@ -195,6 +196,8 @@ class CameraInputMixin:
195
196
  ctx: ScriptRunContext | None = None,
196
197
  ) -> UploadedFile | None:
197
198
  key = to_key(key)
199
+
200
+ check_cache_replay_rules()
198
201
  check_callback_rules(self.dg, on_change)
199
202
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
200
203
  maybe_raise_label_warnings(label, label_visibility)
@@ -21,7 +21,6 @@ from typing import TYPE_CHECKING, Literal, cast
21
21
  from streamlit import runtime
22
22
  from streamlit.elements.form import is_in_form
23
23
  from streamlit.elements.image import AtomicImage, WidthBehaviour, image_to_url
24
- from streamlit.elements.utils import check_callback_rules, check_session_state_rules
25
24
  from streamlit.errors import StreamlitAPIException
26
25
  from streamlit.proto.Block_pb2 import Block as BlockProto
27
26
  from streamlit.proto.ChatInput_pb2 import ChatInput as ChatInputProto
@@ -289,6 +288,14 @@ class ChatMixin:
289
288
  # We default to an empty string here and disallow user choice intentionally
290
289
  default = ""
291
290
  key = to_key(key)
291
+
292
+ from streamlit.elements.utils import (
293
+ check_cache_replay_rules,
294
+ check_callback_rules,
295
+ check_session_state_rules,
296
+ )
297
+
298
+ check_cache_replay_rules()
292
299
  check_callback_rules(self.dg, on_submit)
293
300
  check_session_state_rules(default_value=default, key=key, writes_allowed=False)
294
301
 
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, cast
20
20
 
21
21
  from streamlit.elements.form import current_form_id
22
22
  from streamlit.elements.utils import (
23
+ check_cache_replay_rules,
23
24
  check_callback_rules,
24
25
  check_session_state_rules,
25
26
  get_label_visibility_proto_value,
@@ -274,11 +275,12 @@ class CheckboxMixin:
274
275
  ctx: ScriptRunContext | None = None,
275
276
  ) -> bool:
276
277
  key = to_key(key)
278
+
279
+ check_cache_replay_rules()
277
280
  check_callback_rules(self.dg, on_change)
278
281
  check_session_state_rules(
279
282
  default_value=None if value is False else value, key=key
280
283
  )
281
-
282
284
  maybe_raise_label_warnings(label, label_visibility)
283
285
 
284
286
  id = compute_widget_id(
@@ -22,6 +22,7 @@ from typing import cast
22
22
  import streamlit
23
23
  from streamlit.elements.form import current_form_id
24
24
  from streamlit.elements.utils import (
25
+ check_cache_replay_rules,
25
26
  check_callback_rules,
26
27
  check_session_state_rules,
27
28
  get_label_visibility_proto_value,
@@ -169,6 +170,8 @@ class ColorPickerMixin:
169
170
  ctx: ScriptRunContext | None = None,
170
171
  ) -> str:
171
172
  key = to_key(key)
173
+
174
+ check_cache_replay_rules()
172
175
  check_callback_rules(self.dg, on_change)
173
176
  check_session_state_rules(default_value=value, key=key)
174
177
  maybe_raise_label_warnings(label, label_visibility)
@@ -55,7 +55,6 @@ from streamlit.elements.lib.column_config_utils import (
55
55
  update_column_config,
56
56
  )
57
57
  from streamlit.elements.lib.pandas_styler_utils import marshall_styler
58
- from streamlit.elements.utils import check_callback_rules, check_session_state_rules
59
58
  from streamlit.errors import StreamlitAPIException
60
59
  from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
61
60
  from streamlit.runtime.metrics_util import gather_metrics
@@ -774,10 +773,20 @@ class DataEditorMixin:
774
773
  height: 350px
775
774
 
776
775
  """
776
+ # Lazy-loaded import
777
777
  import pandas as pd
778
778
  import pyarrow as pa
779
779
 
780
+ # Import here to avoid cyclic import warning
781
+ from streamlit.elements.utils import (
782
+ check_cache_replay_rules,
783
+ check_callback_rules,
784
+ check_session_state_rules,
785
+ )
786
+
780
787
  key = to_key(key)
788
+
789
+ check_cache_replay_rules()
781
790
  check_callback_rules(self.dg, on_change)
782
791
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
783
792
 
@@ -23,6 +23,7 @@ from typing_extensions import TypeAlias
23
23
  from streamlit import config
24
24
  from streamlit.elements.form import current_form_id
25
25
  from streamlit.elements.utils import (
26
+ check_cache_replay_rules,
26
27
  check_callback_rules,
27
28
  check_session_state_rules,
28
29
  get_label_visibility_proto_value,
@@ -398,6 +399,8 @@ class FileUploaderMixin:
398
399
  ctx: ScriptRunContext | None = None,
399
400
  ) -> UploadedFile | list[UploadedFile] | None:
400
401
  key = to_key(key)
402
+
403
+ check_cache_replay_rules()
401
404
  check_callback_rules(self.dg, on_change)
402
405
  check_session_state_rules(default_value=None, key=key, writes_allowed=False)
403
406
  maybe_raise_label_warnings(label, label_visibility)
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Sequence, cast, overlo
20
20
 
21
21
  from streamlit.elements.form import current_form_id
22
22
  from streamlit.elements.utils import (
23
+ check_cache_replay_rules,
23
24
  check_callback_rules,
24
25
  check_session_state_rules,
25
26
  get_label_visibility_proto_value,
@@ -82,15 +83,19 @@ def _check_and_convert_to_indices(
82
83
  default_values, "pandas.core.series.Series"
83
84
  ):
84
85
  default_values = list(cast(Sequence[Any], default_values))
85
- elif not default_values or default_values in opt:
86
- default_values = [default_values]
87
- else:
86
+ elif (
87
+ isinstance(default_values, (tuple, set))
88
+ or default_values
89
+ and default_values not in opt
90
+ ):
88
91
  default_values = list(default_values)
89
-
92
+ else:
93
+ default_values = [default_values]
90
94
  for value in default_values:
91
95
  if value not in opt:
92
96
  raise StreamlitAPIException(
93
- "Every Multiselect default value must exist in options"
97
+ f"The default value '{value}' is part of the options. "
98
+ "Please make sure that every default values also exists in the options."
94
99
  )
95
100
 
96
101
  return [opt.index(value) for value in default_values]
@@ -282,12 +287,14 @@ class MultiSelectMixin:
282
287
  ctx: ScriptRunContext | None = None,
283
288
  ) -> list[T]:
284
289
  key = to_key(key)
290
+
291
+ check_cache_replay_rules()
285
292
  check_callback_rules(self.dg, on_change)
286
293
  check_session_state_rules(default_value=default, key=key)
294
+ maybe_raise_label_warnings(label, label_visibility)
287
295
 
288
296
  opt = ensure_indexable(options)
289
297
  check_python_comparable(opt)
290
- maybe_raise_label_warnings(label, label_visibility)
291
298
 
292
299
  indices = _check_and_convert_to_indices(opt, default)
293
300
 
@@ -23,6 +23,7 @@ from typing_extensions import TypeAlias
23
23
 
24
24
  from streamlit.elements.form import current_form_id
25
25
  from streamlit.elements.utils import (
26
+ check_cache_replay_rules,
26
27
  check_callback_rules,
27
28
  check_session_state_rules,
28
29
  get_label_visibility_proto_value,
@@ -36,6 +37,7 @@ from streamlit.runtime.state import (
36
37
  WidgetArgs,
37
38
  WidgetCallback,
38
39
  WidgetKwargs,
40
+ get_session_state,
39
41
  register_widget,
40
42
  )
41
43
  from streamlit.runtime.state.common import compute_widget_id
@@ -277,6 +279,8 @@ class NumberInputMixin:
277
279
  ctx: ScriptRunContext | None = None,
278
280
  ) -> Number | None:
279
281
  key = to_key(key)
282
+
283
+ check_cache_replay_rules()
280
284
  check_callback_rules(self.dg, on_change)
281
285
  check_session_state_rules(
282
286
  default_value=value if value != "min" else None, key=key
@@ -320,6 +324,10 @@ class NumberInputMixin:
320
324
  f"\n`step` has {type(step).__name__} type."
321
325
  )
322
326
 
327
+ session_state = get_session_state().filtered_state
328
+ if key is not None and key in session_state and session_state[key] is None:
329
+ value = None
330
+
323
331
  if value == "min":
324
332
  if min_value is not None:
325
333
  value = min_value
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Sequence, cast
20
20
 
21
21
  from streamlit.elements.form import current_form_id
22
22
  from streamlit.elements.utils import (
23
+ check_cache_replay_rules,
23
24
  check_callback_rules,
24
25
  check_session_state_rules,
25
26
  get_label_visibility_proto_value,
@@ -33,6 +34,7 @@ from streamlit.runtime.state import (
33
34
  WidgetArgs,
34
35
  WidgetCallback,
35
36
  WidgetKwargs,
37
+ get_session_state,
36
38
  register_widget,
37
39
  )
38
40
  from streamlit.runtime.state.common import compute_widget_id, save_for_app_testing
@@ -249,9 +251,12 @@ class RadioMixin:
249
251
  ctx: ScriptRunContext | None,
250
252
  ) -> T | None:
251
253
  key = to_key(key)
254
+
255
+ check_cache_replay_rules()
252
256
  check_callback_rules(self.dg, on_change)
253
257
  check_session_state_rules(default_value=None if index == 0 else index, key=key)
254
258
  maybe_raise_label_warnings(label, label_visibility)
259
+
255
260
  opt = ensure_indexable(options)
256
261
  check_python_comparable(opt)
257
262
 
@@ -289,6 +294,10 @@ class RadioMixin:
289
294
  f"Radio captions must be strings. Passed type: {type(caption).__name__}"
290
295
  )
291
296
 
297
+ session_state = get_session_state().filtered_state
298
+ if key is not None and key in session_state and session_state[key] is None:
299
+ index = None
300
+
292
301
  radio_proto = RadioProto()
293
302
  radio_proto.id = id
294
303
  radio_proto.label = label
@@ -22,6 +22,7 @@ from typing_extensions import TypeGuard
22
22
 
23
23
  from streamlit.elements.form import current_form_id
24
24
  from streamlit.elements.utils import (
25
+ check_cache_replay_rules,
25
26
  check_callback_rules,
26
27
  check_session_state_rules,
27
28
  get_label_visibility_proto_value,
@@ -256,9 +257,12 @@ class SelectSliderMixin:
256
257
  ctx: ScriptRunContext | None = None,
257
258
  ) -> T | tuple[T, T]:
258
259
  key = to_key(key)
260
+
261
+ check_cache_replay_rules()
259
262
  check_callback_rules(self.dg, on_change)
260
263
  check_session_state_rules(default_value=value, key=key)
261
264
  maybe_raise_label_warnings(label, label_visibility)
265
+
262
266
  opt = ensure_indexable(options)
263
267
  check_python_comparable(opt)
264
268
 
@@ -19,6 +19,7 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Sequence, cast
19
19
 
20
20
  from streamlit.elements.form import current_form_id
21
21
  from streamlit.elements.utils import (
22
+ check_cache_replay_rules,
22
23
  check_callback_rules,
23
24
  check_session_state_rules,
24
25
  get_label_visibility_proto_value,
@@ -32,6 +33,7 @@ from streamlit.runtime.state import (
32
33
  WidgetArgs,
33
34
  WidgetCallback,
34
35
  WidgetKwargs,
36
+ get_session_state,
35
37
  register_widget,
36
38
  )
37
39
  from streamlit.runtime.state.common import compute_widget_id, save_for_app_testing
@@ -229,9 +231,10 @@ class SelectboxMixin:
229
231
  ctx: ScriptRunContext | None = None,
230
232
  ) -> T | None:
231
233
  key = to_key(key)
234
+
235
+ check_cache_replay_rules()
232
236
  check_callback_rules(self.dg, on_change)
233
237
  check_session_state_rules(default_value=None if index == 0 else index, key=key)
234
-
235
238
  maybe_raise_label_warnings(label, label_visibility)
236
239
 
237
240
  opt = ensure_indexable(options)
@@ -260,6 +263,10 @@ class SelectboxMixin:
260
263
  "Selectbox index must be between 0 and length of options"
261
264
  )
262
265
 
266
+ session_state = get_session_state().filtered_state
267
+ if key is not None and key in session_state and session_state[key] is None:
268
+ index = None
269
+
263
270
  selectbox_proto = SelectboxProto()
264
271
  selectbox_proto.id = id
265
272
  selectbox_proto.label = label
@@ -24,6 +24,7 @@ from typing_extensions import TypeAlias
24
24
 
25
25
  from streamlit.elements.form import current_form_id
26
26
  from streamlit.elements.utils import (
27
+ check_cache_replay_rules,
27
28
  check_callback_rules,
28
29
  check_session_state_rules,
29
30
  get_label_visibility_proto_value,
@@ -364,9 +365,10 @@ class SliderMixin:
364
365
  ctx: ScriptRunContext | None = None,
365
366
  ) -> SliderReturn:
366
367
  key = to_key(key)
368
+
369
+ check_cache_replay_rules()
367
370
  check_callback_rules(self.dg, on_change)
368
371
  check_session_state_rules(default_value=value, key=key)
369
-
370
372
  maybe_raise_label_warnings(label, label_visibility)
371
373
 
372
374
  id = compute_widget_id(