streamlit-nightly 1.45.2.dev20250514__py3-none-any.whl → 1.45.2.dev20250515__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 (96) hide show
  1. streamlit/connections/sql_connection.py +10 -7
  2. streamlit/connections/util.py +2 -2
  3. streamlit/elements/lib/options_selector_utils.py +10 -2
  4. streamlit/elements/markdown.py +1 -1
  5. streamlit/elements/plotly_chart.py +7 -7
  6. streamlit/elements/vega_charts.py +7 -7
  7. streamlit/elements/widgets/file_uploader.py +2 -2
  8. streamlit/elements/widgets/number_input.py +3 -3
  9. streamlit/elements/widgets/radio.py +21 -0
  10. streamlit/elements/widgets/select_slider.py +1 -13
  11. streamlit/elements/widgets/selectbox.py +22 -0
  12. streamlit/elements/widgets/slider.py +35 -9
  13. streamlit/runtime/caching/cache_data_api.py +18 -14
  14. streamlit/runtime/connection_factory.py +1 -1
  15. streamlit/runtime/scriptrunner/script_runner.py +1 -2
  16. streamlit/runtime/secrets.py +10 -8
  17. streamlit/runtime/state/query_params_proxy.py +14 -12
  18. streamlit/runtime/state/session_state.py +2 -2
  19. streamlit/static/index.html +1 -1
  20. streamlit/static/static/js/{ErrorOutline.esm.DbGVRvJi.js → ErrorOutline.esm.DZL6W-d3.js} +1 -1
  21. streamlit/static/static/js/{FileDownload.esm.Dsazfko3.js → FileDownload.esm.BTdAw4zC.js} +1 -1
  22. streamlit/static/static/js/{FileHelper.MycXbml-.js → FileHelper.Beb1sf3m.js} +1 -1
  23. streamlit/static/static/js/{FormClearHelper.BBCnWP4b.js → FormClearHelper.BJursVXh.js} +1 -1
  24. streamlit/static/static/js/{Hooks.Cogxcj3O.js → Hooks.C9-XVXXu.js} +1 -1
  25. streamlit/static/static/js/{InputInstructions.DmFmv5Ss.js → InputInstructions.DFH2wY93.js} +1 -1
  26. streamlit/static/static/js/{ProgressBar.CL8D7fKU.js → ProgressBar.6M24tsRk.js} +1 -1
  27. streamlit/static/static/js/{RenderInPortalIfExists.BIF2_x-k.js → RenderInPortalIfExists.BjKKk4eZ.js} +1 -1
  28. streamlit/static/static/js/{Toolbar.BiePqUs0.js → Toolbar.AcZDbsfk.js} +1 -1
  29. streamlit/static/static/js/{base-input.9-IewVJN.js → base-input.DbRAJnqp.js} +1 -1
  30. streamlit/static/static/js/{checkbox.CvxVkFoK.js → checkbox.0qSLqyAl.js} +1 -1
  31. streamlit/static/static/js/{createSuper.CcYwpbOm.js → createSuper.BVzb0XXY.js} +1 -1
  32. streamlit/static/static/js/{data-grid-overlay-editor.DVakjLUQ.js → data-grid-overlay-editor.veQYOXpb.js} +1 -1
  33. streamlit/static/static/js/{downloader.DUDYpW4X.js → downloader.C_vYtX1r.js} +1 -1
  34. streamlit/static/static/js/{es6.Dd8C3gJG.js → es6.DlS5aK2H.js} +2 -2
  35. streamlit/static/static/js/{iframeResizer.contentWindow.ElqrcVSG.js → iframeResizer.contentWindow.DYLRAnnn.js} +1 -1
  36. streamlit/static/static/js/{index.y8UOtxmw.js → index.7-HGyLk8.js} +1 -1
  37. streamlit/static/static/js/{index.DiE_wY_P.js → index.B4jkkFu1.js} +1 -1
  38. streamlit/static/static/js/{index.CwLlrvyN.js → index.B7lVUFiI.js} +1 -1
  39. streamlit/static/static/js/{index.C44ecW4y.js → index.BA7OvX6X.js} +1 -1
  40. streamlit/static/static/js/{index.CkOK3vMg.js → index.BNNdZZ73.js} +1 -1
  41. streamlit/static/static/js/{index.D8g5_NeN.js → index.Bs42fx1x.js} +1 -1
  42. streamlit/static/static/js/{index.D5Y8GQ-0.js → index.C-SVYz-x.js} +1 -1
  43. streamlit/static/static/js/{index.Ogd9LUng.js → index.C8AfWtJ-.js} +1 -1
  44. streamlit/static/static/js/{index.DWBlm6kP.js → index.CEN6fgTl.js} +1 -1
  45. streamlit/static/static/js/{index.DfYxhBCm.js → index.COQpmMRs.js} +1 -1
  46. streamlit/static/static/js/{index.BkpDVBQw.js → index.CVpOBIPc.js} +1 -1
  47. streamlit/static/static/js/{index.BRTdJWEL.js → index.CZ_7kbSY.js} +1 -1
  48. streamlit/static/static/js/{index.DWL3vnFa.js → index.CdJve-c-.js} +1 -1
  49. streamlit/static/static/js/{index.8U8I-dVE.js → index.ChCdyltc.js} +1 -1
  50. streamlit/static/static/js/{index.BANNX-Et.js → index.CnuHgtvi.js} +1 -1
  51. streamlit/static/static/js/{index.PYQDVW05.js → index.CpBBbkiT.js} +1 -1
  52. streamlit/static/static/js/{index.B5gxNAgv.js → index.CqJn4aNa.js} +1 -1
  53. streamlit/static/static/js/{index.Dxf51cqQ.js → index.CsMycx_g.js} +1 -1
  54. streamlit/static/static/js/{index.CDxF0FlW.js → index.CzjlNese.js} +1 -1
  55. streamlit/static/static/js/{index.Bgid2lLN.js → index.D6vjCnF6.js} +1 -1
  56. streamlit/static/static/js/{index.Bud-F2Rk.js → index.DI4lQWQ9.js} +1 -1
  57. streamlit/static/static/js/{index.C-wDYZmi.js → index.DOZrTqtO.js} +1 -1
  58. streamlit/static/static/js/{index.DgQ-i_4o.js → index.DQoQce-F.js} +10 -10
  59. streamlit/static/static/js/{index.rR2rxOdw.js → index.DU1Hm4Vy.js} +1 -1
  60. streamlit/static/static/js/{index.DrVpZAT_.js → index.D_NeaxbH.js} +1 -1
  61. streamlit/static/static/js/{index.3TsDLcVz.js → index.DawYHwts.js} +1 -1
  62. streamlit/static/static/js/{index.DNeEyPk6.js → index.DgKQMQQ-.js} +1 -1
  63. streamlit/static/static/js/{index.Chn8rXFO.js → index.Dh9pGVkc.js} +1 -1
  64. streamlit/static/static/js/{index.CssifhIa.js → index.DvaGxMeZ.js} +1 -1
  65. streamlit/static/static/js/{index.CM8qhnIu.js → index.Dx0WWCBs.js} +5 -5
  66. streamlit/static/static/js/{index.DX_Td1Hq.js → index.KEBclOiy.js} +1 -1
  67. streamlit/static/static/js/{index.BYGvkzYg.js → index.SG-0kuQk.js} +1 -1
  68. streamlit/static/static/js/{index.CtEWZzBM.js → index.TZA6glxs.js} +1 -1
  69. streamlit/static/static/js/{index.uT7_kc4D.js → index.bbxNeuVP.js} +1 -1
  70. streamlit/static/static/js/{index.DK1C5mv_.js → index.pKO-QKd7.js} +1 -1
  71. streamlit/static/static/js/{index.QqgppQA_.js → index.qHLLYZv1.js} +1 -1
  72. streamlit/static/static/js/{index.D0fj09K-.js → index.vXLfHXtB.js} +1 -1
  73. streamlit/static/static/js/{input.D1uIuNvR.js → input.4UlvIkvl.js} +1 -1
  74. streamlit/static/static/js/{memory.C_YLF4Fx.js → memory.CjAKg4CS.js} +1 -1
  75. streamlit/static/static/js/{mergeWith.BrhEAUIQ.js → mergeWith.Bnn9a11J.js} +1 -1
  76. streamlit/static/static/js/{number-overlay-editor.Cl4hS5U2.js → number-overlay-editor.BGyA8GbD.js} +1 -1
  77. streamlit/static/static/js/{possibleConstructorReturn.BizCfnoE.js → possibleConstructorReturn.Cu-FTKlF.js} +1 -1
  78. streamlit/static/static/js/{sandbox.BYlf4D-n.js → sandbox.D4Wf-7jE.js} +1 -1
  79. streamlit/static/static/js/{textarea.BvMrgzVs.js → textarea.B0_fGlpz.js} +1 -1
  80. streamlit/static/static/js/{timepicker.8sMF8VpM.js → timepicker._IYyhmJr.js} +1 -1
  81. streamlit/static/static/js/{toConsumableArray.Cl96Bc5x.js → toConsumableArray.BRgjiMf8.js} +1 -1
  82. streamlit/static/static/js/{uniqueId.BoXr82qs.js → uniqueId.DWtxcoYp.js} +1 -1
  83. streamlit/static/static/js/{useBasicWidgetState.DYpB4KjS.js → useBasicWidgetState.CJa4vrfr.js} +1 -1
  84. streamlit/static/static/js/{useOnInputChange.D17AAeVI.js → useOnInputChange.DXDP3ow3.js} +1 -1
  85. streamlit/static/static/js/{withFullScreenWrapper.Lq8QUQxx.js → withFullScreenWrapper.BYUNeZvy.js} +1 -1
  86. streamlit/string_util.py +1 -5
  87. streamlit/type_util.py +1 -1
  88. streamlit/vendor/pympler/asizeof.py +2 -1
  89. streamlit/watcher/local_sources_watcher.py +3 -3
  90. streamlit/web/server/oidc_mixin.py +2 -2
  91. {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250515.dist-info}/METADATA +1 -1
  92. {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250515.dist-info}/RECORD +96 -96
  93. {streamlit_nightly-1.45.2.dev20250514.data → streamlit_nightly-1.45.2.dev20250515.data}/scripts/streamlit.cmd +0 -0
  94. {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250515.dist-info}/WHEEL +0 -0
  95. {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250515.dist-info}/entry_points.txt +0 -0
  96. {streamlit_nightly-1.45.2.dev20250514.dist-info → streamlit_nightly-1.45.2.dev20250515.dist-info}/top_level.txt +0 -0
@@ -319,13 +319,16 @@ class SQLConnection(BaseConnection["Engine"]):
319
319
  import pandas as pd
320
320
 
321
321
  instance = self._instance.connect()
322
- return pd.read_sql(
323
- text(sql),
324
- instance,
325
- index_col=index_col,
326
- chunksize=chunksize,
327
- params=params,
328
- **kwargs,
322
+ return cast(
323
+ "DataFrame",
324
+ pd.read_sql(
325
+ text(sql),
326
+ instance,
327
+ index_col=index_col,
328
+ chunksize=chunksize,
329
+ params=params,
330
+ **kwargs,
331
+ ),
329
332
  )
330
333
 
331
334
  # We modify our helper function's `__qualname__` here to work around default
@@ -21,7 +21,7 @@
21
21
  from __future__ import annotations
22
22
 
23
23
  import os
24
- from typing import TYPE_CHECKING, Any, cast
24
+ from typing import TYPE_CHECKING, Any
25
25
 
26
26
  if TYPE_CHECKING:
27
27
  from collections.abc import Collection
@@ -92,6 +92,6 @@ def running_in_sis() -> bool:
92
92
  is_in_stored_procedure,
93
93
  )
94
94
 
95
- return cast("bool", is_in_stored_procedure())
95
+ return is_in_stored_procedure() # type: ignore
96
96
  except ModuleNotFoundError:
97
97
  return False
@@ -185,7 +185,11 @@ def maybe_coerce_enum(
185
185
  ) -> RegisterWidgetResult[T]: ...
186
186
 
187
187
 
188
- def maybe_coerce_enum(register_widget_result, options, opt_sequence):
188
+ def maybe_coerce_enum(
189
+ register_widget_result: RegisterWidgetResult[Any],
190
+ options: OptionSequence[Any],
191
+ opt_sequence: Sequence[Any],
192
+ ) -> RegisterWidgetResult[Any]:
189
193
  """Maybe Coerce a RegisterWidgetResult with an Enum member value to
190
194
  RegisterWidgetResult[option] if option is an EnumType, otherwise just return
191
195
  the original RegisterWidgetResult.
@@ -227,7 +231,11 @@ def maybe_coerce_enum_sequence(
227
231
  ) -> RegisterWidgetResult[tuple[T, T]]: ...
228
232
 
229
233
 
230
- def maybe_coerce_enum_sequence(register_widget_result, options, opt_sequence):
234
+ def maybe_coerce_enum_sequence(
235
+ register_widget_result: RegisterWidgetResult[list[Any] | tuple[Any, ...]],
236
+ options: OptionSequence[Any],
237
+ opt_sequence: Sequence[Any],
238
+ ) -> RegisterWidgetResult[list[Any] | tuple[Any, ...]]:
231
239
  """Maybe Coerce a RegisterWidgetResult with a sequence of Enum members as value
232
240
  to RegisterWidgetResult[Sequence[option]] if option is an EnumType, otherwise just
233
241
  return the original RegisterWidgetResult.
@@ -22,7 +22,7 @@ from streamlit.string_util import clean_text, validate_icon_or_emoji
22
22
  from streamlit.type_util import SupportsStr, is_sympy_expression
23
23
 
24
24
  if TYPE_CHECKING:
25
- import sympy # type: ignore
25
+ import sympy
26
26
 
27
27
  from streamlit.delta_generator import DeltaGenerator
28
28
 
@@ -29,7 +29,7 @@ from typing import (
29
29
  overload,
30
30
  )
31
31
 
32
- from typing_extensions import TypeAlias
32
+ from typing_extensions import Required, TypeAlias
33
33
 
34
34
  from streamlit import type_util
35
35
  from streamlit.deprecation_util import show_deprecation_warning
@@ -159,10 +159,10 @@ class PlotlySelectionState(TypedDict, total=False):
159
159
 
160
160
  """
161
161
 
162
- points: list[dict[str, Any]]
163
- point_indices: list[int]
164
- box: list[dict[str, Any]]
165
- lasso: list[dict[str, Any]]
162
+ points: Required[list[dict[str, Any]]]
163
+ point_indices: Required[list[int]]
164
+ box: Required[list[dict[str, Any]]]
165
+ lasso: Required[list[dict[str, Any]]]
166
166
 
167
167
 
168
168
  class PlotlyState(TypedDict, total=False):
@@ -205,7 +205,7 @@ class PlotlyState(TypedDict, total=False):
205
205
 
206
206
  """
207
207
 
208
- selection: PlotlySelectionState
208
+ selection: Required[PlotlySelectionState]
209
209
 
210
210
 
211
211
  @dataclass
@@ -231,7 +231,7 @@ class PlotlyChartSelectionSerde:
231
231
  )
232
232
 
233
233
  if "selection" not in selection_state:
234
- selection_state = empty_selection_state
234
+ selection_state = empty_selection_state # type: ignore[unreachable]
235
235
 
236
236
  return cast("PlotlyState", AttributeDictionary(selection_state))
237
237
 
@@ -31,7 +31,7 @@ from typing import (
31
31
  overload,
32
32
  )
33
33
 
34
- from typing_extensions import TypeAlias
34
+ from typing_extensions import Required, TypeAlias
35
35
 
36
36
  from streamlit import dataframe_util, type_util
37
37
  from streamlit.elements.lib import dicttools
@@ -218,7 +218,7 @@ class VegaLiteState(TypedDict, total=False):
218
218
 
219
219
  """
220
220
 
221
- selection: AttributeDictionary
221
+ selection: Required[AttributeDictionary]
222
222
 
223
223
 
224
224
  @dataclass
@@ -242,7 +242,7 @@ class VegaLiteStateSerde:
242
242
  )
243
243
 
244
244
  if "selection" not in selection_state:
245
- selection_state = empty_selection_state
245
+ selection_state = empty_selection_state # type: ignore[unreachable]
246
246
 
247
247
  return cast("VegaLiteState", AttributeDictionary(selection_state))
248
248
 
@@ -1479,7 +1479,7 @@ class VegaChartsMixin:
1479
1479
  use_container_width: bool | None = None,
1480
1480
  theme: Literal["streamlit"] | None = "streamlit",
1481
1481
  key: Key | None = None,
1482
- on_select: Literal["ignore"], # No default value here to make it work with mypy
1482
+ on_select: Literal["ignore"] = "ignore",
1483
1483
  selection_mode: str | Iterable[str] | None = None,
1484
1484
  ) -> DeltaGenerator: ...
1485
1485
 
@@ -1492,7 +1492,7 @@ class VegaChartsMixin:
1492
1492
  use_container_width: bool | None = None,
1493
1493
  theme: Literal["streamlit"] | None = "streamlit",
1494
1494
  key: Key | None = None,
1495
- on_select: Literal["rerun"] | WidgetCallback = "rerun",
1495
+ on_select: Literal["rerun"] | WidgetCallback,
1496
1496
  selection_mode: str | Iterable[str] | None = None,
1497
1497
  ) -> VegaLiteState: ...
1498
1498
 
@@ -1638,7 +1638,7 @@ class VegaChartsMixin:
1638
1638
  use_container_width: bool | None = None,
1639
1639
  theme: Literal["streamlit"] | None = "streamlit",
1640
1640
  key: Key | None = None,
1641
- on_select: Literal["ignore"], # No default value here to make it work with mypy
1641
+ on_select: Literal["ignore"] = "ignore",
1642
1642
  selection_mode: str | Iterable[str] | None = None,
1643
1643
  **kwargs: Any,
1644
1644
  ) -> DeltaGenerator: ...
@@ -1653,7 +1653,7 @@ class VegaChartsMixin:
1653
1653
  use_container_width: bool | None = None,
1654
1654
  theme: Literal["streamlit"] | None = "streamlit",
1655
1655
  key: Key | None = None,
1656
- on_select: Literal["rerun"] | WidgetCallback = "rerun",
1656
+ on_select: Literal["rerun"] | WidgetCallback,
1657
1657
  selection_mode: str | Iterable[str] | None = None,
1658
1658
  **kwargs: Any,
1659
1659
  ) -> VegaLiteState: ...
@@ -170,7 +170,7 @@ class FileUploaderMixin:
170
170
  disabled: bool = False,
171
171
  label_visibility: LabelVisibility = "visible",
172
172
  width: WidthWithoutContent = "stretch",
173
- ) -> list[UploadedFile] | None: ...
173
+ ) -> list[UploadedFile]: ...
174
174
 
175
175
  # 1. type is given as not a keyword-only argument
176
176
  # 2. accept_multiple_files = False or omitted
@@ -213,7 +213,7 @@ class FileUploaderMixin:
213
213
  disabled: bool = False,
214
214
  label_visibility: LabelVisibility = "visible",
215
215
  width: WidthWithoutContent = "stretch",
216
- ) -> list[UploadedFile] | None: ...
216
+ ) -> list[UploadedFile]: ...
217
217
 
218
218
  # 1. type is skipped or a keyword argument
219
219
  # 2. accept_multiple_files = False or omitted
@@ -116,7 +116,7 @@ class NumberInputMixin:
116
116
  def number_input(
117
117
  self,
118
118
  label: str,
119
- min_value: int | None = None,
119
+ min_value: None = None,
120
120
  *,
121
121
  max_value: int,
122
122
  value: IntOrNone | Literal["min"] = "min",
@@ -166,8 +166,8 @@ class NumberInputMixin:
166
166
  def number_input(
167
167
  self,
168
168
  label: str,
169
- min_value: int | None = None,
170
- max_value: int | None = None,
169
+ min_value: None = None,
170
+ max_value: None = None,
171
171
  value: IntOrNone | Literal["min"] = "min",
172
172
  *,
173
173
  step: int,
@@ -18,6 +18,8 @@ from dataclasses import dataclass
18
18
  from textwrap import dedent
19
19
  from typing import TYPE_CHECKING, Any, Callable, Generic, cast, overload
20
20
 
21
+ from typing_extensions import Never
22
+
21
23
  from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
22
24
  from streamlit.elements.lib.form_utils import current_form_id
23
25
  from streamlit.elements.lib.options_selector_utils import index_, maybe_coerce_enum
@@ -79,6 +81,25 @@ class RadioSerde(Generic[T]):
79
81
 
80
82
 
81
83
  class RadioMixin:
84
+ @overload
85
+ def radio(
86
+ self,
87
+ label: str,
88
+ options: Sequence[Never],
89
+ index: int = 0,
90
+ format_func: Callable[[Any], Any] = str,
91
+ key: Key | None = None,
92
+ help: str | None = None,
93
+ on_change: WidgetCallback | None = None,
94
+ args: WidgetArgs | None = None,
95
+ kwargs: WidgetKwargs | None = None,
96
+ *, # keyword-only args:
97
+ disabled: bool = False,
98
+ horizontal: bool = False,
99
+ captions: Sequence[str] | None = None,
100
+ label_visibility: LabelVisibility = "visible",
101
+ ) -> None: ...
102
+
82
103
  @overload
83
104
  def radio(
84
105
  self,
@@ -107,7 +107,7 @@ class SelectSliderSerde(Generic[T]):
107
107
 
108
108
  class SelectSliderMixin:
109
109
  @overload
110
- def select_slider( # type: ignore[overload-overlap]
110
+ def select_slider(
111
111
  self,
112
112
  label: str,
113
113
  options: OptionSequence[T],
@@ -124,18 +124,6 @@ class SelectSliderMixin:
124
124
  width: WidthWithoutContent = "stretch",
125
125
  ) -> tuple[T, T]: ...
126
126
 
127
- # The overload-overlap error given by mypy here stems from
128
- # the fact that
129
- #
130
- # > opt:List[object] = [1, 2, "3"]
131
- # > select_slider("foo", options=opt, value=[1, 2])
132
- #
133
- # matches both overloads; "opt" matches
134
- # OptionsSequence[T] in each case, binding T to object.
135
- # However, the list[int] type of "value" can be interpreted
136
- # as subtype of object, or as a subtype of List[object],
137
- # meaning it matches both signatures.
138
-
139
127
  @overload
140
128
  def select_slider(
141
129
  self,
@@ -16,6 +16,8 @@ from __future__ import annotations
16
16
  from textwrap import dedent
17
17
  from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, cast, overload
18
18
 
19
+ from typing_extensions import Never
20
+
19
21
  from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
20
22
  from streamlit.elements.lib.form_utils import current_form_id
21
23
  from streamlit.elements.lib.layout_utils import WidthWithoutContent, validate_width
@@ -132,6 +134,26 @@ class SelectboxSerde(Generic[T]):
132
134
 
133
135
 
134
136
  class SelectboxMixin:
137
+ @overload
138
+ def selectbox(
139
+ self,
140
+ label: str,
141
+ options: Sequence[Never], # Type for empty or Never-inferred options
142
+ index: int = 0,
143
+ format_func: Callable[[Any], str] = str,
144
+ key: Key | None = None,
145
+ help: str | None = None,
146
+ on_change: WidgetCallback | None = None,
147
+ args: WidgetArgs | None = None,
148
+ kwargs: WidgetKwargs | None = None,
149
+ *, # keyword-only arguments:
150
+ placeholder: str | None = None,
151
+ disabled: bool = False,
152
+ label_visibility: LabelVisibility = "visible",
153
+ accept_new_options: Literal[False] = False,
154
+ width: WidthWithoutContent = "stretch",
155
+ ) -> None: ... # Returns None if options is empty and accept_new_options is False
156
+
135
157
  @overload
136
158
  def selectbox(
137
159
  self,
@@ -23,6 +23,7 @@ from typing import (
23
23
  TYPE_CHECKING,
24
24
  Any,
25
25
  Final,
26
+ TypedDict,
26
27
  TypeVar,
27
28
  Union,
28
29
  cast,
@@ -155,6 +156,13 @@ def _micros_to_datetime(micros: int, orig_tz: tzinfo | None) -> datetime:
155
156
  return utc_dt.replace(tzinfo=orig_tz)
156
157
 
157
158
 
159
+ class SliderDefaultValues(TypedDict):
160
+ min_value: SliderScalar
161
+ max_value: SliderScalar
162
+ step: SliderStep
163
+ format: str
164
+
165
+
158
166
  @dataclass
159
167
  class SliderSerde:
160
168
  value: list[float]
@@ -192,14 +200,21 @@ class SliderSerde:
192
200
 
193
201
  def serialize(self, v: Any) -> list[Any]:
194
202
  range_value = isinstance(v, (list, tuple))
195
- value = list(v) if range_value else [v]
203
+ # Convert to list to handle tuples
204
+ processed_value = list(v) if range_value else [v]
205
+
196
206
  if self.data_type == SliderProto.DATE:
197
- value = [_datetime_to_micros(_date_to_datetime(v)) for v in value]
207
+ return [
208
+ _datetime_to_micros(_date_to_datetime(val)) for val in processed_value
209
+ ]
198
210
  if self.data_type == SliderProto.TIME:
199
- value = [_datetime_to_micros(_time_to_datetime(v)) for v in value]
211
+ return [
212
+ _datetime_to_micros(_time_to_datetime(val)) for val in processed_value
213
+ ]
200
214
  if self.data_type == SliderProto.DATETIME:
201
- value = [_datetime_to_micros(v) for v in value]
202
- return value
215
+ return [_datetime_to_micros(val) for val in processed_value]
216
+ # For numeric types, ensure they are floats if not already
217
+ return [float(val) for val in processed_value]
203
218
 
204
219
 
205
220
  class SliderMixin:
@@ -222,6 +237,7 @@ class SliderMixin:
222
237
  *,
223
238
  disabled: bool = False,
224
239
  label_visibility: LabelVisibility = "visible",
240
+ width: WidthWithoutContent = "stretch",
225
241
  ) -> int: ...
226
242
 
227
243
  # If min-value or max_value is provided and a numeric type, and value (if provided)
@@ -243,6 +259,7 @@ class SliderMixin:
243
259
  *,
244
260
  disabled: bool = False,
245
261
  label_visibility: LabelVisibility = "visible",
262
+ width: WidthWithoutContent = "stretch",
246
263
  ) -> SliderNumericT: ...
247
264
 
248
265
  # If value is provided and a sequence of numeric type,
@@ -264,6 +281,7 @@ class SliderMixin:
264
281
  kwargs: WidgetKwargs | None = None,
265
282
  disabled: bool = False,
266
283
  label_visibility: LabelVisibility = "visible",
284
+ width: WidthWithoutContent = "stretch",
267
285
  ) -> tuple[SliderNumericT, SliderNumericT]: ...
268
286
 
269
287
  # If value is provided positionally and a sequence of numeric type,
@@ -285,6 +303,7 @@ class SliderMixin:
285
303
  *,
286
304
  disabled: bool = False,
287
305
  label_visibility: LabelVisibility = "visible",
306
+ width: WidthWithoutContent = "stretch",
288
307
  ) -> tuple[SliderNumericT, SliderNumericT]: ...
289
308
 
290
309
  # If min-value is provided and a datelike type, and value (if provided)
@@ -306,6 +325,7 @@ class SliderMixin:
306
325
  *,
307
326
  disabled: bool = False,
308
327
  label_visibility: LabelVisibility = "visible",
328
+ width: WidthWithoutContent = "stretch",
309
329
  ) -> SliderDatelikeT: ...
310
330
 
311
331
  # If max-value is provided and a datelike type, and value (if provided)
@@ -314,7 +334,7 @@ class SliderMixin:
314
334
  def slider(
315
335
  self,
316
336
  label: str,
317
- min_value: SliderDatelikeT | None = None,
337
+ min_value: None = None,
318
338
  *,
319
339
  max_value: SliderDatelikeT,
320
340
  value: SliderDatelikeT | None = None,
@@ -327,6 +347,7 @@ class SliderMixin:
327
347
  kwargs: WidgetKwargs | None = None,
328
348
  disabled: bool = False,
329
349
  label_visibility: LabelVisibility = "visible",
350
+ width: WidthWithoutContent = "stretch",
330
351
  ) -> SliderDatelikeT: ...
331
352
 
332
353
  # If value is provided and a datelike type, return the same datelike type.
@@ -334,8 +355,8 @@ class SliderMixin:
334
355
  def slider(
335
356
  self,
336
357
  label: str,
337
- min_value: SliderDatelikeT | None = None,
338
- max_value: SliderDatelikeT | None = None,
358
+ min_value: None = None,
359
+ max_value: None = None,
339
360
  *,
340
361
  value: SliderDatelikeT,
341
362
  step: StepDatelikeT | None = None,
@@ -347,6 +368,7 @@ class SliderMixin:
347
368
  kwargs: WidgetKwargs | None = None,
348
369
  disabled: bool = False,
349
370
  label_visibility: LabelVisibility = "visible",
371
+ width: WidthWithoutContent = "stretch",
350
372
  ) -> SliderDatelikeT: ...
351
373
 
352
374
  # If value is provided and a sequence of datelike type,
@@ -358,7 +380,9 @@ class SliderMixin:
358
380
  min_value: SliderDatelikeT | None = None,
359
381
  max_value: SliderDatelikeT | None = None,
360
382
  *,
361
- value: SliderDatelikeSpanT[SliderDatelikeT],
383
+ value: list[SliderDatelikeT]
384
+ | tuple[SliderDatelikeT]
385
+ | tuple[SliderDatelikeT, SliderDatelikeT],
362
386
  step: StepDatelikeT | None = None,
363
387
  format: str | None = None,
364
388
  key: Key | None = None,
@@ -368,6 +392,7 @@ class SliderMixin:
368
392
  kwargs: WidgetKwargs | None = None,
369
393
  disabled: bool = False,
370
394
  label_visibility: LabelVisibility = "visible",
395
+ width: WidthWithoutContent = "stretch",
371
396
  ) -> tuple[SliderDatelikeT, SliderDatelikeT]: ...
372
397
 
373
398
  # If value is provided positionally and a sequence of datelike type,
@@ -390,6 +415,7 @@ class SliderMixin:
390
415
  *,
391
416
  disabled: bool = False,
392
417
  label_visibility: LabelVisibility = "visible",
418
+ width: WidthWithoutContent = "stretch",
393
419
  ) -> tuple[SliderDatelikeT, SliderDatelikeT]: ...
394
420
 
395
421
  # https://github.com/python/mypy/issues/17614
@@ -316,6 +316,11 @@ def get_data_cache_stats_provider() -> CacheStatsProvider:
316
316
  return _data_caches
317
317
 
318
318
 
319
+ # Type-annotate the decorator function.
320
+ # (See https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories)
321
+ F = TypeVar("F", bound=Callable[..., Any])
322
+
323
+
319
324
  class CacheDataAPI:
320
325
  """Implements the public st.cache_data API: the @st.cache_data decorator, and
321
326
  st.cache_data.clear().
@@ -336,10 +341,6 @@ class CacheDataAPI:
336
341
  decorator_metric_name, self._decorator
337
342
  )
338
343
 
339
- # Type-annotate the decorator function.
340
- # (See https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories)
341
- F = TypeVar("F", bound=Callable[..., Any])
342
-
343
344
  # Bare decorator usage
344
345
  @overload
345
346
  def __call__(self, func: F) -> F: ...
@@ -566,16 +567,19 @@ class CacheDataAPI:
566
567
  if experimental_allow_widgets:
567
568
  show_widget_replay_deprecation("cache_data")
568
569
 
569
- def wrapper(f): # noqa: ANN001, ANN202
570
- return make_cached_func_wrapper(
571
- CachedDataFuncInfo(
572
- func=f,
573
- persist=persist_string,
574
- show_spinner=show_spinner,
575
- max_entries=max_entries,
576
- ttl=ttl,
577
- hash_funcs=hash_funcs,
578
- )
570
+ def wrapper(f: F) -> F:
571
+ return cast(
572
+ "F",
573
+ make_cached_func_wrapper(
574
+ CachedDataFuncInfo(
575
+ func=f, # type: ignore
576
+ persist=persist_string,
577
+ show_spinner=show_spinner,
578
+ max_entries=max_entries,
579
+ ttl=ttl,
580
+ hash_funcs=hash_funcs,
581
+ )
582
+ ),
579
583
  )
580
584
 
581
585
  if func is None:
@@ -202,7 +202,7 @@ def connection_factory(
202
202
  pass
203
203
 
204
204
 
205
- def connection_factory(
205
+ def connection_factory( # type: ignore
206
206
  name,
207
207
  type=None,
208
208
  max_entries=None,
@@ -134,11 +134,10 @@ def _mpa_v1(main_script_path: str) -> None:
134
134
  PAGES_FOLDER = MAIN_SCRIPT_PATH.parent / "pages"
135
135
 
136
136
  # Read out the my_pages folder and create a page for every script:
137
- pages = PAGES_FOLDER.glob("*.py")
138
137
  pages = sorted(
139
138
  [
140
139
  page
141
- for page in pages
140
+ for page in PAGES_FOLDER.glob("*.py")
142
141
  if page.name.endswith(".py")
143
142
  and not page.name.startswith(".")
144
143
  and page.name != "__init__.py"
@@ -45,29 +45,31 @@ class SecretErrorMessages:
45
45
  """
46
46
 
47
47
  def __init__(self) -> None:
48
- self.missing_attr_message = lambda attr_name: (
48
+ self.missing_attr_message: Callable[[str], str] = lambda attr_name: (
49
49
  f'st.secrets has no attribute "{attr_name}". '
50
50
  "Did you forget to add it to secrets.toml, mount it to secret directory, or the app settings "
51
51
  "on Streamlit Cloud? More info: "
52
52
  "https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/secrets-management"
53
53
  )
54
- self.missing_key_message = lambda key: (
54
+ self.missing_key_message: Callable[[str], str] = lambda key: (
55
55
  f'st.secrets has no key "{key}". '
56
56
  "Did you forget to add it to secrets.toml, mount it to secret directory, or the app settings "
57
57
  "on Streamlit Cloud? More info: "
58
58
  "https://docs.streamlit.io/deploy/streamlit-community-cloud/deploy-your-app/secrets-management"
59
59
  )
60
- self.no_secrets_found = lambda file_paths: (
60
+ self.no_secrets_found: Callable[[list[str]], str] = lambda file_paths: (
61
61
  f"No secrets found. Valid paths for a secrets.toml file or secret directories are: {', '.join(file_paths)}"
62
62
  )
63
- self.error_parsing_file_at_path = (
63
+ self.error_parsing_file_at_path: Callable[[str, Exception], str] = (
64
64
  lambda path, ex: f"Error parsing secrets file at {path}: {ex}"
65
65
  )
66
- self.subfolder_path_is_not_a_folder = lambda sub_folder_path: (
67
- f"{sub_folder_path} is not a folder. "
68
- "To use directory based secrets, mount every secret in a subfolder under the secret directory"
66
+ self.subfolder_path_is_not_a_folder: Callable[[str], str] = (
67
+ lambda sub_folder_path: (
68
+ f"{sub_folder_path} is not a folder. "
69
+ "To use directory based secrets, mount every secret in a subfolder under the secret directory"
70
+ )
69
71
  )
70
- self.invalid_secret_path = lambda path: (
72
+ self.invalid_secret_path: Callable[[str], str] = lambda path: (
71
73
  f"Invalid secrets path: {path}: path is not a .toml file or a directory"
72
74
  )
73
75
 
@@ -15,7 +15,7 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from collections.abc import Iterable, Iterator, MutableMapping
18
- from typing import TYPE_CHECKING, overload
18
+ from typing import TYPE_CHECKING, Any, overload
19
19
 
20
20
  from streamlit.runtime.metrics_util import gather_metrics
21
21
  from streamlit.runtime.state.session_state_proxy import get_session_state
@@ -55,7 +55,7 @@ class QueryParamsProxy(MutableMapping[str, str]):
55
55
  del qp[key]
56
56
 
57
57
  @gather_metrics("query_params.set_item")
58
- def __setitem__(self, key: str, value: str | Iterable[str]) -> None:
58
+ def __setitem__(self, key: str, value: Any) -> None:
59
59
  with get_session_state().query_params() as qp:
60
60
  qp[key] = value
61
61
 
@@ -76,18 +76,18 @@ class QueryParamsProxy(MutableMapping[str, str]):
76
76
 
77
77
  @overload
78
78
  def update(
79
- self, mapping: SupportsKeysAndGetItem[str, str | Iterable[str]], /, **kwds: str
79
+ self, params: SupportsKeysAndGetItem[str, str | Iterable[str]], /, **kwds: str
80
80
  ) -> None: ...
81
81
 
82
82
  @overload
83
83
  def update(
84
- self, keys_and_values: Iterable[tuple[str, str | Iterable[str]]], /, **kwds: str
84
+ self, params: Iterable[tuple[str, str | Iterable[str]]], /, **kwds: str
85
85
  ) -> None: ...
86
86
 
87
87
  @overload
88
88
  def update(self, **kwds: str | Iterable[str]) -> None: ...
89
89
 
90
- def update(self, other=(), /, **kwds):
90
+ def update(self, params=(), /, **kwds) -> None: # type: ignore
91
91
  """
92
92
  Update one or more values in query_params at once from a dictionary or
93
93
  dictionary-like object.
@@ -102,10 +102,10 @@ class QueryParamsProxy(MutableMapping[str, str]):
102
102
  Additional key/value pairs to update passed as keyword arguments.
103
103
  """
104
104
  with get_session_state().query_params() as qp:
105
- qp.update(other, **kwds)
105
+ qp.update(params, **kwds)
106
106
 
107
107
  @gather_metrics("query_params.set_attr")
108
- def __setattr__(self, key: str, value: str | Iterable[str]) -> None:
108
+ def __setattr__(self, key: str, value: Any) -> None:
109
109
  with get_session_state().query_params() as qp:
110
110
  qp[key] = value
111
111
 
@@ -165,17 +165,19 @@ class QueryParamsProxy(MutableMapping[str, str]):
165
165
  return qp.to_dict()
166
166
 
167
167
  @overload
168
- def from_dict(
169
- self, keys_and_values: Iterable[tuple[str, str | Iterable[str]]]
170
- ) -> None: ...
168
+ def from_dict(self, params: Iterable[tuple[str, str | Iterable[str]]]) -> None: ...
171
169
 
172
170
  @overload
173
171
  def from_dict(
174
- self, mapping: SupportsKeysAndGetItem[str, str | Iterable[str]]
172
+ self, params: SupportsKeysAndGetItem[str, str | Iterable[str]]
175
173
  ) -> None: ...
176
174
 
177
175
  @gather_metrics("query_params.from_dict")
178
- def from_dict(self, params):
176
+ def from_dict(
177
+ self,
178
+ params: SupportsKeysAndGetItem[str, str | Iterable[str]]
179
+ | Iterable[tuple[str, str | Iterable[str]]],
180
+ ) -> None:
179
181
  """
180
182
  Set all of the query parameters from a dictionary or dictionary-like object.
181
183