streamlit-nightly 1.45.2.dev20250512__py3-none-any.whl → 1.45.2.dev20250513__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 (131) hide show
  1. streamlit/__init__.py +1 -0
  2. streamlit/auth_util.py +6 -6
  3. streamlit/commands/echo.py +5 -3
  4. streamlit/components/v1/custom_component.py +2 -2
  5. streamlit/config.py +7 -7
  6. streamlit/config_util.py +5 -6
  7. streamlit/delta_generator.py +4 -1
  8. streamlit/deprecation_util.py +5 -5
  9. streamlit/elements/doc_string.py +4 -6
  10. streamlit/elements/lib/built_in_chart_utils.py +13 -8
  11. streamlit/elements/lib/policies.py +1 -1
  12. streamlit/elements/spinner.py +1 -1
  13. streamlit/elements/vega_charts.py +1 -1
  14. streamlit/elements/widgets/slider.py +1 -1
  15. streamlit/elements/write.py +2 -2
  16. streamlit/error_util.py +15 -8
  17. streamlit/errors.py +10 -7
  18. streamlit/file_util.py +6 -3
  19. streamlit/git_util.py +26 -21
  20. streamlit/hello/dataframe_demo.py +1 -1
  21. streamlit/hello/mapping_demo.py +1 -1
  22. streamlit/hello/plotting_demo.py +3 -3
  23. streamlit/hello/streamlit_app.py +1 -1
  24. streamlit/hello/utils.py +2 -1
  25. streamlit/runtime/app_session.py +4 -4
  26. streamlit/runtime/caching/cache_data_api.py +2 -2
  27. streamlit/runtime/caching/cache_resource_api.py +1 -1
  28. streamlit/runtime/caching/cache_utils.py +3 -3
  29. streamlit/runtime/caching/hashing.py +2 -2
  30. streamlit/runtime/credentials.py +4 -4
  31. streamlit/runtime/forward_msg_queue.py +1 -1
  32. streamlit/runtime/memory_uploaded_file_manager.py +1 -1
  33. streamlit/runtime/metrics_util.py +1 -1
  34. streamlit/runtime/runtime.py +1 -1
  35. streamlit/runtime/scriptrunner/exec_code.py +1 -1
  36. streamlit/runtime/scriptrunner/script_cache.py +1 -1
  37. streamlit/runtime/scriptrunner/script_runner.py +9 -2
  38. streamlit/runtime/scriptrunner_utils/script_requests.py +3 -3
  39. streamlit/runtime/scriptrunner_utils/script_run_context.py +3 -3
  40. streamlit/runtime/secrets.py +6 -7
  41. streamlit/runtime/state/query_params.py +1 -1
  42. streamlit/runtime/stats.py +1 -1
  43. streamlit/static/index.html +1 -1
  44. streamlit/static/static/js/{ErrorOutline.esm.Cfhrjz42.js → ErrorOutline.esm.CxkgXqSh.js} +1 -1
  45. streamlit/static/static/js/{FileDownload.esm.BN5DkI-d.js → FileDownload.esm.DVrjmwoh.js} +1 -1
  46. streamlit/static/static/js/{FileHelper.BWWhRdUs.js → FileHelper.CMA9s0t3.js} +1 -1
  47. streamlit/static/static/js/{FormClearHelper.CHPGUkGG.js → FormClearHelper.Ca3GFjxv.js} +1 -1
  48. streamlit/static/static/js/{Hooks.DjxyUmgD.js → Hooks.BpCPXt5n.js} +1 -1
  49. streamlit/static/static/js/{InputInstructions.Bkai2tFZ.js → InputInstructions.BO_BnHv5.js} +1 -1
  50. streamlit/static/static/js/{ProgressBar.DFiqS51i.js → ProgressBar.Ctk1m4EX.js} +1 -1
  51. streamlit/static/static/js/{RenderInPortalIfExists.DWTzV71R.js → RenderInPortalIfExists.kuKoxpXt.js} +1 -1
  52. streamlit/static/static/js/{Toolbar.Dk2A3VxL.js → Toolbar.Cde1fEcQ.js} +1 -1
  53. streamlit/static/static/js/{base-input.DfiT3r4p.js → base-input.BwCmIYba.js} +1 -1
  54. streamlit/static/static/js/{checkbox.DLXFjls2.js → checkbox.CwPOyuag.js} +1 -1
  55. streamlit/static/static/js/{createSuper.n2DV0o-4.js → createSuper.BMtevhyt.js} +1 -1
  56. streamlit/static/static/js/{data-grid-overlay-editor.v1LF25Ml.js → data-grid-overlay-editor.gtfE9z1L.js} +1 -1
  57. streamlit/static/static/js/{downloader.CI8EFE9Y.js → downloader.-58ZXBvx.js} +1 -1
  58. streamlit/static/static/js/{es6.CH6Tf3Uw.js → es6.6JpsZqpF.js} +2 -2
  59. streamlit/static/static/js/{iframeResizer.contentWindow.VCjyiSg6.js → iframeResizer.contentWindow.Dvm_jxul.js} +1 -1
  60. streamlit/static/static/js/{index.BEE4v1Vc.js → index.9Bu4pGgs.js} +1 -1
  61. streamlit/static/static/js/{index.DM_jnlWC.js → index.B1T1N6vQ.js} +1 -1
  62. streamlit/static/static/js/{index.CmsMgepL.js → index.B9LBeTzL.js} +1 -1
  63. streamlit/static/static/js/{index.hFB9saa3.js → index.BXdNB_A0.js} +1 -1
  64. streamlit/static/static/js/{index.STF1QdPr.js → index.Bd91GXu8.js} +1 -1
  65. streamlit/static/static/js/{index.LqvX_Kr6.js → index.BdEKCy-o.js} +1 -1
  66. streamlit/static/static/js/{index.C1P3O0oI.js → index.BhODUTaJ.js} +1 -1
  67. streamlit/static/static/js/{index.nmbrjghZ.js → index.BjtSRm-c.js} +1 -1
  68. streamlit/static/static/js/{index.C9ORVZvA.js → index.BnK8pWHN.js} +1 -1
  69. streamlit/static/static/js/{index.BWVpiUBA.js → index.C5xsotRs.js} +1 -1
  70. streamlit/static/static/js/{index.DUU38l7N.js → index.CD3lJu6g.js} +1 -1
  71. streamlit/static/static/js/{index.B-Q1qQil.js → index.CGJjlswG.js} +1 -1
  72. streamlit/static/static/js/{index.uN3TP5oq.js → index.CIZd1q4K.js} +1 -1
  73. streamlit/static/static/js/{index.DoM9A12Z.js → index.CZy9JHE4.js} +2 -2
  74. streamlit/static/static/js/{index.9p279joF.js → index.Ce-7kIl6.js} +1 -1
  75. streamlit/static/static/js/{index.D_Bv6KD1.js → index.CiiU1-bS.js} +1 -1
  76. streamlit/static/static/js/{index.D1An7GDs.js → index.ClE8XHxl.js} +1 -1
  77. streamlit/static/static/js/{index.SPkHHODG.js → index.CvKH37SN.js} +1 -1
  78. streamlit/static/static/js/{index.BFEA8ufN.js → index.D0G-y_z6.js} +1 -1
  79. streamlit/static/static/js/{index.uhNJX5pn.js → index.D1ccH_2Z.js} +1 -1
  80. streamlit/static/static/js/{index.DKsDSPTo.js → index.D3ES4sSL.js} +1 -1
  81. streamlit/static/static/js/{index.BROoC18J.js → index.DJ0X7aeY.js} +1 -1
  82. streamlit/static/static/js/{index.BgY_Js0s.js → index.DNNQBTM6.js} +1 -1
  83. streamlit/static/static/js/{index.Ovig-AMR.js → index.DQJE0i9s.js} +5 -5
  84. streamlit/static/static/js/{index.ZuW7Olhm.js → index.DR9ekgzX.js} +1 -1
  85. streamlit/static/static/js/{index.DXDmqevk.js → index.DUizq_aW.js} +1 -1
  86. streamlit/static/static/js/{index.D1DxKfIm.js → index.DVE5BhiT.js} +1 -1
  87. streamlit/static/static/js/{index.7XN_jSTW.js → index.DW60zbv4.js} +1 -1
  88. streamlit/static/static/js/{index.Cdsxte9t.js → index.DenamHJl.js} +1 -1
  89. streamlit/static/static/js/{index.DMDjQhhk.js → index.DgnhzFgr.js} +1 -1
  90. streamlit/static/static/js/{index.DgeyRl4J.js → index.Dk_aZplH.js} +1 -1
  91. streamlit/static/static/js/{index.C1TEsRV0.js → index.Dqcp7EZB.js} +43 -43
  92. streamlit/static/static/js/{index.CXpQxU0G.js → index.NfOJ2GJ6.js} +1 -1
  93. streamlit/static/static/js/{index.CR4eM0Q3.js → index.WVgPkrrw.js} +1 -1
  94. streamlit/static/static/js/{index.jZkr87Ly.js → index.bkU6rhIM.js} +1 -1
  95. streamlit/static/static/js/{index.DcH46Eo2.js → index.hQ5adhxG.js} +1 -1
  96. streamlit/static/static/js/{index.B1j5m20t.js → index.lYSTjxV_.js} +1 -1
  97. streamlit/static/static/js/{input.BAfiLByr.js → input.JEUWF6Z-.js} +1 -1
  98. streamlit/static/static/js/{memory.CvD1KGKJ.js → memory.BToPJrCN.js} +1 -1
  99. streamlit/static/static/js/{mergeWith.Dy4BuY-h.js → mergeWith.DGon2YId.js} +1 -1
  100. streamlit/static/static/js/{number-overlay-editor.Bl84FLfp.js → number-overlay-editor.kqkFTYSn.js} +1 -1
  101. streamlit/static/static/js/{possibleConstructorReturn.gffiKeDQ.js → possibleConstructorReturn.twGQoCQl.js} +1 -1
  102. streamlit/static/static/js/{sandbox.BXw8ya9t.js → sandbox.o85HOKwq.js} +1 -1
  103. streamlit/static/static/js/{textarea.DNNNKi6n.js → textarea.CdOYpTta.js} +1 -1
  104. streamlit/static/static/js/{timepicker.CgHlrhoy.js → timepicker.Cy1BKBo3.js} +1 -1
  105. streamlit/static/static/js/{toConsumableArray.MtZ-3vir.js → toConsumableArray.BVXfsvDc.js} +1 -1
  106. streamlit/static/static/js/{uniqueId.CFcd6g0d.js → uniqueId.Dz7-nY8K.js} +1 -1
  107. streamlit/static/static/js/{useBasicWidgetState.DadZUraL.js → useBasicWidgetState.CeKdNkz-.js} +1 -1
  108. streamlit/static/static/js/{useOnInputChange.V6d5TCFH.js → useOnInputChange.CM8BtP-c.js} +1 -1
  109. streamlit/static/static/js/{withFullScreenWrapper.8qpius26.js → withFullScreenWrapper.DuyW554J.js} +1 -1
  110. streamlit/temporary_directory.py +2 -2
  111. streamlit/testing/v1/app_test.py +2 -2
  112. streamlit/testing/v1/element_tree.py +5 -5
  113. streamlit/watcher/folder_black_list.py +1 -1
  114. streamlit/watcher/local_sources_watcher.py +5 -3
  115. streamlit/watcher/path_watcher.py +1 -1
  116. streamlit/watcher/polling_path_watcher.py +1 -1
  117. streamlit/watcher/util.py +6 -5
  118. streamlit/web/bootstrap.py +4 -4
  119. streamlit/web/cli.py +13 -13
  120. streamlit/web/server/app_static_file_handler.py +1 -1
  121. streamlit/web/server/authlib_tornado_integration.py +6 -1
  122. streamlit/web/server/oauth_authlib_routes.py +3 -3
  123. streamlit/web/server/oidc_mixin.py +15 -3
  124. streamlit/web/server/routes.py +11 -11
  125. streamlit/web/server/stats_request_handler.py +2 -2
  126. {streamlit_nightly-1.45.2.dev20250512.dist-info → streamlit_nightly-1.45.2.dev20250513.dist-info}/METADATA +1 -1
  127. {streamlit_nightly-1.45.2.dev20250512.dist-info → streamlit_nightly-1.45.2.dev20250513.dist-info}/RECORD +131 -131
  128. {streamlit_nightly-1.45.2.dev20250512.data → streamlit_nightly-1.45.2.dev20250513.data}/scripts/streamlit.cmd +0 -0
  129. {streamlit_nightly-1.45.2.dev20250512.dist-info → streamlit_nightly-1.45.2.dev20250513.dist-info}/WHEEL +0 -0
  130. {streamlit_nightly-1.45.2.dev20250512.dist-info → streamlit_nightly-1.45.2.dev20250513.dist-info}/entry_points.txt +0 -0
  131. {streamlit_nightly-1.45.2.dev20250512.dist-info → streamlit_nightly-1.45.2.dev20250513.dist-info}/top_level.txt +0 -0
streamlit/__init__.py CHANGED
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  # isort: skip_file
16
+ # ruff: noqa: E402, PLC0414, A001
16
17
 
17
18
  """Streamlit.
18
19
 
streamlit/auth_util.py CHANGED
@@ -32,21 +32,21 @@ if TYPE_CHECKING:
32
32
  class AuthCache:
33
33
  """Simple cache implementation for storing info required for Authlib."""
34
34
 
35
- def __init__(self):
36
- self.cache = {}
35
+ def __init__(self) -> None:
36
+ self.cache: dict[str, Any] = {}
37
37
 
38
- def get(self, key):
38
+ def get(self, key: str) -> Any:
39
39
  return self.cache.get(key)
40
40
 
41
41
  # for set method, we are follow the same signature used in Authlib
42
42
  # the expires_in is not used in our case
43
- def set(self, key, value, expires_in): # noqa: ARG002
43
+ def set(self, key: str, value: Any, expires_in: int | None = None) -> None: # noqa: ARG002
44
44
  self.cache[key] = value
45
45
 
46
- def get_dict(self):
46
+ def get_dict(self) -> dict[str, Any]:
47
47
  return self.cache
48
48
 
49
- def delete(self, key):
49
+ def delete(self, key: str) -> None:
50
50
  self.cache.pop(key, None)
51
51
 
52
52
 
@@ -19,12 +19,12 @@ import contextlib
19
19
  import re
20
20
  import textwrap
21
21
  import traceback
22
- from typing import TYPE_CHECKING, Any
22
+ from typing import TYPE_CHECKING, Any, Literal
23
23
 
24
24
  from streamlit.runtime.metrics_util import gather_metrics
25
25
 
26
26
  if TYPE_CHECKING:
27
- from collections.abc import Iterable
27
+ from collections.abc import Generator, Iterable
28
28
 
29
29
  _SPACES_RE = re.compile("\\s*")
30
30
  _EMPTY_LINE_RE = re.compile("\\s*\n")
@@ -32,7 +32,9 @@ _EMPTY_LINE_RE = re.compile("\\s*\n")
32
32
 
33
33
  @gather_metrics("echo")
34
34
  @contextlib.contextmanager
35
- def echo(code_location="above"):
35
+ def echo(
36
+ code_location: Literal["above", "below"] = "above",
37
+ ) -> Generator[None, None, None]:
36
38
  """Use in a `with` block to draw some code on the app, then execute it.
37
39
 
38
40
  Parameters
@@ -183,7 +183,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
183
183
  # other arguments change, and the component's iframe won't be
184
184
  # remounted on the frontend.
185
185
 
186
- def marshall_element_args():
186
+ def marshall_element_args() -> None:
187
187
  element.component_instance.json_args = serialized_json_args
188
188
  element.component_instance.special_args.extend(special_args)
189
189
 
@@ -210,7 +210,7 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
210
210
  )
211
211
  element.component_instance.id = computed_id
212
212
 
213
- def deserialize_component(ui_value):
213
+ def deserialize_component(ui_value: Any) -> Any:
214
214
  # ui_value is an object from json, an ArrowTable proto, or a bytearray
215
215
  return ui_value
216
216
 
streamlit/config.py CHANGED
@@ -1651,7 +1651,7 @@ def _set_development_mode() -> None:
1651
1651
 
1652
1652
  def on_config_parsed(
1653
1653
  func: Callable[[], None], force_connect: bool = False, lock: bool = False
1654
- ) -> Callable[[], bool]:
1654
+ ) -> Callable[[], None]:
1655
1655
  """Wait for the config file to be parsed then call func.
1656
1656
 
1657
1657
  If the config file has already been parsed, just calls func immediately
@@ -1671,7 +1671,7 @@ def on_config_parsed(
1671
1671
 
1672
1672
  Returns
1673
1673
  -------
1674
- Callable[[], bool]
1674
+ Callable[[], None]
1675
1675
  A function that the caller can use to deregister func.
1676
1676
  """
1677
1677
 
@@ -1680,13 +1680,13 @@ def on_config_parsed(
1680
1680
  # leading to a memory leak because the Signal will keep a reference of the
1681
1681
  # callable argument. When the callable argument is an object method, then
1682
1682
  # the reference to that object won't be released.
1683
- def receiver(_):
1684
- return func_with_lock()
1683
+ def receiver(_: Any) -> None:
1684
+ func_with_lock()
1685
1685
 
1686
- def disconnect():
1687
- return _on_config_parsed.disconnect(receiver)
1686
+ def disconnect() -> None:
1687
+ _on_config_parsed.disconnect(receiver)
1688
1688
 
1689
- def func_with_lock():
1689
+ def func_with_lock() -> None:
1690
1690
  if lock:
1691
1691
  with _config_lock:
1692
1692
  func()
streamlit/config_util.py CHANGED
@@ -54,16 +54,16 @@ def show_config(
54
54
  )
55
55
  )
56
56
 
57
- def append_desc(text):
57
+ def append_desc(text: str) -> None:
58
58
  out.append("# " + cli_util.style_for_cli(text, bold=True))
59
59
 
60
- def append_comment(text):
60
+ def append_comment(text: str) -> None:
61
61
  out.append("# " + cli_util.style_for_cli(text))
62
62
 
63
- def append_section(text):
63
+ def append_section(text: str) -> None:
64
64
  out.append(cli_util.style_for_cli(text, bold=True, fg="green"))
65
65
 
66
- def append_setting(text):
66
+ def append_setting(text: str) -> None:
67
67
  out.append(cli_util.style_for_cli(text, fg="green"))
68
68
 
69
69
  for section in section_descriptions:
@@ -178,8 +178,7 @@ def _clean_paragraphs(txt: str) -> list[str]:
178
178
  # Strip both leading and trailing newlines.
179
179
  txt = txt.strip("\n")
180
180
  paragraphs = txt.split("\n\n")
181
- cleaned_paragraphs = [
181
+ return [
182
182
  "\n".join(_clean(line) for line in paragraph.split("\n"))
183
183
  for paragraph in paragraphs
184
184
  ]
185
- return cleaned_paragraphs
@@ -522,9 +522,12 @@ class DeltaGenerator(
522
522
 
523
523
  def _block(
524
524
  self,
525
- block_proto: Block_pb2.Block = Block_pb2.Block(),
525
+ block_proto: Block_pb2.Block | None = None,
526
526
  dg_type: type | None = None,
527
527
  ) -> DeltaGenerator:
528
+ if block_proto is None:
529
+ block_proto = Block_pb2.Block()
530
+
528
531
  # Operate on the active DeltaGenerator, in case we're in a `with` block.
529
532
  dg = self._active_dg
530
533
 
@@ -93,7 +93,7 @@ def deprecate_func_name(
93
93
  """
94
94
 
95
95
  @functools.wraps(func)
96
- def wrapped_func(*args, **kwargs):
96
+ def wrapped_func(*args: Any, **kwargs: Any) -> Any:
97
97
  result = func(*args, **kwargs)
98
98
  show_deprecation_warning(
99
99
  make_deprecated_name_warning(
@@ -167,7 +167,7 @@ def _create_deprecated_obj_wrapper(obj: TObj, show_warning: Callable[[], Any]) -
167
167
  show_warning()
168
168
 
169
169
  class Wrapper:
170
- def __init__(self):
170
+ def __init__(self) -> None:
171
171
  # Override all the Wrapped object's magic functions
172
172
  for name in Wrapper._get_magic_functions(obj.__class__):
173
173
  setattr(
@@ -176,7 +176,7 @@ def _create_deprecated_obj_wrapper(obj: TObj, show_warning: Callable[[], Any]) -
176
176
  property(self._make_magic_function_proxy(name)),
177
177
  )
178
178
 
179
- def __getattr__(self, attr):
179
+ def __getattr__(self, attr: str) -> Any:
180
180
  # We handle __getattr__ separately from our other magic
181
181
  # functions. The wrapped class may not actually implement it,
182
182
  # but we still need to implement it to call all its normal
@@ -199,8 +199,8 @@ def _create_deprecated_obj_wrapper(obj: TObj, show_warning: Callable[[], Any]) -
199
199
  ]
200
200
 
201
201
  @staticmethod
202
- def _make_magic_function_proxy(name):
203
- def proxy(self, *args): # noqa: ARG001
202
+ def _make_magic_function_proxy(name: str) -> Callable[[Any], Any]:
203
+ def proxy(_self: Any, *args: Any) -> Any:
204
204
  maybe_show_warning()
205
205
  return getattr(obj, name)
206
206
 
@@ -283,9 +283,7 @@ def _get_variable_name_from_code_str(code: str) -> str | None:
283
283
  ):
284
284
  # A common pattern is to add "," at the end of a magic command to make it print.
285
285
  # This removes that final ",", so it looks nicer.
286
- code = code.removesuffix(",")
287
-
288
- return code
286
+ return code.removesuffix(",")
289
287
 
290
288
  arg_node = _get_stcommand_arg(tree)
291
289
 
@@ -427,7 +425,7 @@ def _get_weight(value: Any) -> int:
427
425
  return 0
428
426
 
429
427
 
430
- def _get_value(obj, var_name):
428
+ def _get_value(obj: object, var_name: str | None) -> str | None:
431
429
  obj_value = _get_human_readable_value(obj)
432
430
 
433
431
  if obj_value is not None:
@@ -459,7 +457,7 @@ def _get_value(obj, var_name):
459
457
  return obj_value
460
458
 
461
459
 
462
- def _get_human_readable_value(value):
460
+ def _get_human_readable_value(value: Any) -> str | None:
463
461
  if isinstance(value, Secrets):
464
462
  # Don't want to read secrets.toml because that will show a warning if there's no
465
463
  # secrets.toml file.
@@ -508,7 +506,7 @@ def _is_computed_property(obj: object, attr_name: str) -> bool:
508
506
  return False
509
507
 
510
508
 
511
- def _get_members(obj):
509
+ def _get_members(obj: object) -> list[MemberProto]:
512
510
  members_for_sorting = []
513
511
 
514
512
  for attr_name in dir(obj):
@@ -954,7 +954,9 @@ def _get_color_encoding(
954
954
  # If the color value is color-like, return that.
955
955
  if is_color_like(cast("Any", color_value)):
956
956
  if len(y_column_list) != 1:
957
- raise StreamlitColorLengthError([color_value], y_column_list)
957
+ raise StreamlitColorLengthError(
958
+ [color_value] if color_value else [], y_column_list
959
+ )
958
960
 
959
961
  return alt.ColorValue(to_css_color(cast("Any", color_value)))
960
962
 
@@ -975,7 +977,7 @@ def _get_color_encoding(
975
977
  title=" ",
976
978
  )
977
979
 
978
- raise StreamlitInvalidColorError(df, color_from_user)
980
+ raise StreamlitInvalidColorError(color_from_user)
979
981
 
980
982
  if color_column is not None:
981
983
  column_type: VegaLiteType
@@ -1132,7 +1134,7 @@ def _get_y_encoding_type(
1132
1134
 
1133
1135
 
1134
1136
  class StreamlitColumnNotFoundError(StreamlitAPIException):
1135
- def __init__(self, df, col_name, *args):
1137
+ def __init__(self, df: pd.DataFrame, col_name: str, *args: Any) -> None:
1136
1138
  available_columns = ", ".join(str(c) for c in list(df.columns))
1137
1139
  message = (
1138
1140
  f'Data does not have a column named `"{col_name}"`. '
@@ -1142,8 +1144,7 @@ class StreamlitColumnNotFoundError(StreamlitAPIException):
1142
1144
 
1143
1145
 
1144
1146
  class StreamlitInvalidColorError(StreamlitAPIException):
1145
- def __init__(self, df, color_from_user, *args):
1146
- ", ".join(str(c) for c in list(df.columns))
1147
+ def __init__(self, color_from_user: str | Color | list[Color] | None) -> None:
1147
1148
  message = f"""
1148
1149
  This does not look like a valid color argument: `{color_from_user}`.
1149
1150
 
@@ -1156,14 +1157,18 @@ The color argument can be:
1156
1157
  * The name of a column.
1157
1158
  * Or a list of colors, matching the number of y columns to draw.
1158
1159
  """
1159
- super().__init__(message, *args)
1160
+ super().__init__(message)
1160
1161
 
1161
1162
 
1162
1163
  class StreamlitColorLengthError(StreamlitAPIException):
1163
- def __init__(self, color_values, y_column_list, *args):
1164
+ def __init__(
1165
+ self,
1166
+ color_values: str | Color | Collection[Color] | None,
1167
+ y_column_list: list[str],
1168
+ ) -> None:
1164
1169
  message = (
1165
1170
  f"The list of colors `{color_values}` must have the same "
1166
1171
  "length as the list of columns to be colored "
1167
1172
  f"`{y_column_list}`."
1168
1173
  )
1169
- super().__init__(message, *args)
1174
+ super().__init__(message)
@@ -97,7 +97,7 @@ def check_session_state_rules(
97
97
 
98
98
 
99
99
  class CachedWidgetWarning(StreamlitAPIWarning):
100
- def __init__(self):
100
+ def __init__(self) -> None:
101
101
  super().__init__(
102
102
  """
103
103
  Your script uses a widget command in a cached function
@@ -83,7 +83,7 @@ def spinner(
83
83
 
84
84
  try:
85
85
 
86
- def set_message():
86
+ def set_message() -> None:
87
87
  with display_message_lock:
88
88
  if display_message:
89
89
  spinner_proto = SpinnerProto()
@@ -360,7 +360,7 @@ def _convert_altair_to_vega_lite_spec(
360
360
  datasets[name] = data_bytes
361
361
  return {"name": name}
362
362
 
363
- alt.data_transformers.register("id", id_transform) # type: ignore[attr-defined,unused-ignore]
363
+ alt.data_transformers.register("id", id_transform) # type: ignore[arg-type,attr-defined,unused-ignore]
364
364
 
365
365
  # The default altair theme has some width/height defaults defined
366
366
  # which are not useful for Streamlit. Therefore, we change the theme to
@@ -692,7 +692,7 @@ class SliderMixin:
692
692
  if single_value:
693
693
  value = [value]
694
694
 
695
- def value_to_generic_type(v):
695
+ def value_to_generic_type(v: Any) -> SliderProto.DataType.ValueType:
696
696
  if isinstance(v, Integral):
697
697
  return SUPPORTED_TYPES[Integral]
698
698
  if isinstance(v, Real):
@@ -156,7 +156,7 @@ class WriteMixin:
156
156
  streamed_response: str = ""
157
157
  written_content: list[Any] = StreamingOutput()
158
158
 
159
- def flush_stream_response():
159
+ def flush_stream_response() -> None:
160
160
  """Write the full response to the app."""
161
161
  nonlocal streamed_response
162
162
  nonlocal stream_container
@@ -428,7 +428,7 @@ class WriteMixin:
428
428
  "when called as `st.write()` or `st.sidebar.write()`."
429
429
  )
430
430
 
431
- def flush_buffer():
431
+ def flush_buffer() -> None:
432
432
  if string_buffer:
433
433
  text_content = " ".join(string_buffer)
434
434
  # The usage of empty here prevents
streamlit/error_util.py CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Final
17
+ from typing import Any, Final
18
18
 
19
19
  import streamlit
20
20
  from streamlit import config
@@ -26,17 +26,24 @@ _LOGGER: Final = get_logger(__name__)
26
26
 
27
27
 
28
28
  def _print_rich_exception(e: BaseException) -> None:
29
- from rich import box, panel
29
+ from rich.box import Box
30
+ from rich.panel import Panel
30
31
 
31
32
  # Monkey patch the panel to use our custom box style
32
- class ConfigurablePanel(panel.Panel):
33
+ class ConfigurablePanel(Panel):
33
34
  def __init__(
34
35
  self,
35
- renderable,
36
- box=box.Box("────\n \n────\n \n────\n────\n \n────\n"),
37
- **kwargs,
38
- ):
39
- super().__init__(renderable, box, **kwargs)
36
+ renderable: Any,
37
+ box: Box | None = None,
38
+ **kwargs: Any,
39
+ ) -> None:
40
+ super().__init__(
41
+ renderable,
42
+ box
43
+ if box is not None
44
+ else Box("────\n \n────\n \n────\n────\n \n────\n"),
45
+ **kwargs,
46
+ )
40
47
 
41
48
  from rich import traceback as rich_traceback
42
49
 
streamlit/errors.py CHANGED
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, Literal
20
20
  from streamlit import util
21
21
 
22
22
  if TYPE_CHECKING:
23
+ from collections.abc import Collection
23
24
  from datetime import date, time
24
25
 
25
26
 
@@ -140,7 +141,7 @@ class StreamlitAPIWarning(StreamlitAPIException, Warning):
140
141
  instead.
141
142
  """
142
143
 
143
- def __init__(self, *args):
144
+ def __init__(self, *args: Any) -> None:
144
145
  super().__init__(*args)
145
146
  import inspect
146
147
  import traceback
@@ -157,7 +158,7 @@ class StreamlitModuleNotFoundError(StreamlitAPIWarning):
157
158
  that is not one of our core dependencies.
158
159
  """
159
160
 
160
- def __init__(self, module_name, *args):
161
+ def __init__(self, module_name: str, *args: Any) -> None:
161
162
  message = (
162
163
  f'This Streamlit command requires module "{module_name}" to be installed.'
163
164
  )
@@ -220,7 +221,7 @@ class StreamlitInvalidURLError(LocalizableStreamlitException):
220
221
  class StreamlitInvalidColumnSpecError(LocalizableStreamlitException):
221
222
  """Exception raised when no weights are specified, or a negative weight is specified."""
222
223
 
223
- def __init__(self):
224
+ def __init__(self) -> None:
224
225
  super().__init__(
225
226
  "The `spec` argument to `st.columns` must be either a "
226
227
  "positive integer (number of columns) or a list of positive numbers (width ratios of the columns). "
@@ -370,7 +371,7 @@ class StreamlitInvalidNumberFormatError(LocalizableStreamlitException):
370
371
  class StreamlitMissingPageLabelError(LocalizableStreamlitException):
371
372
  """Exception raised when a page_link is created without a label."""
372
373
 
373
- def __init__(self):
374
+ def __init__(self) -> None:
374
375
  super().__init__(
375
376
  "The `label` param is required for external links used with `st.page_link` - please provide a `label`."
376
377
  )
@@ -409,7 +410,7 @@ class StreamlitPageNotFoundError(LocalizableStreamlitException):
409
410
  class StreamlitFragmentWidgetsNotAllowedOutsideError(LocalizableStreamlitException):
410
411
  """Exception raised when the fragment attempts to write to an element outside of its container."""
411
412
 
412
- def __init__(self):
413
+ def __init__(self) -> None:
413
414
  super().__init__("Fragments cannot write widgets to outside containers.")
414
415
 
415
416
 
@@ -418,7 +419,7 @@ class StreamlitInvalidFormCallbackError(LocalizableStreamlitException):
418
419
  the `st.form_submit_button`.
419
420
  """
420
421
 
421
- def __init__(self):
422
+ def __init__(self) -> None:
422
423
  super().__init__(
423
424
  "Within a form, callbacks can only be defined on `st.form_submit_button`. "
424
425
  "Defining callbacks on other widgets inside a form is not allowed."
@@ -436,7 +437,9 @@ class StreamlitValueAssignmentNotAllowedError(LocalizableStreamlitException):
436
437
 
437
438
 
438
439
  class StreamlitInvalidColorError(LocalizableStreamlitException):
439
- def __init__(self, color):
440
+ def __init__(
441
+ self, color: str | Collection[Any] | tuple[int, int, int, int]
442
+ ) -> None:
440
443
  super().__init__(
441
444
  "This does not look like a valid color: {color}.\n\n"
442
445
  "Colors must be in one of the following formats:"
streamlit/file_util.py CHANGED
@@ -19,11 +19,14 @@ import errno
19
19
  import io
20
20
  import os
21
21
  from pathlib import Path
22
- from typing import Final
22
+ from typing import IO, TYPE_CHECKING, Any, Final
23
23
 
24
24
  from streamlit import env_util, errors
25
25
  from streamlit.string_util import is_binary_string
26
26
 
27
+ if TYPE_CHECKING:
28
+ from collections.abc import Generator
29
+
27
30
  # Configuration and credentials are stored inside the ~/.streamlit folder
28
31
  CONFIG_FOLDER_NAME: Final = ".streamlit"
29
32
 
@@ -63,7 +66,7 @@ def get_encoded_file_data(
63
66
 
64
67
 
65
68
  @contextlib.contextmanager
66
- def streamlit_read(path, binary=False):
69
+ def streamlit_read(path: str, binary: bool = False) -> Generator[IO[Any], None, None]:
67
70
  """Opens a context to read this file relative to the streamlit path.
68
71
 
69
72
  For example:
@@ -88,7 +91,7 @@ def streamlit_read(path, binary=False):
88
91
 
89
92
 
90
93
  @contextlib.contextmanager
91
- def streamlit_write(path, binary=False):
94
+ def streamlit_write(path: str, binary: bool = False) -> Generator[IO[Any], None, None]:
92
95
  """Opens a file for writing within the streamlit path, and
93
96
  ensuring that the path exists.
94
97
 
streamlit/git_util.py CHANGED
@@ -16,10 +16,13 @@ from __future__ import annotations
16
16
 
17
17
  import os
18
18
  import re
19
- from typing import Any
19
+ from typing import TYPE_CHECKING, cast
20
20
 
21
21
  from streamlit import util
22
22
 
23
+ if TYPE_CHECKING:
24
+ from git import Commit, Remote, RemoteReference, Repo
25
+
23
26
  # Github has two URLs, one that is https and one that is ssh
24
27
  GITHUB_HTTP_URL = r"^https://(www\.)?github.com/(.+)/(.+)(?:.git)?$"
25
28
  GITHUB_SSH_URL = r"^git@github.com:(.+)/(.+)(?:.git)?$"
@@ -31,7 +34,9 @@ MIN_GIT_VERSION = (2, 7, 0)
31
34
 
32
35
 
33
36
  class GitRepo:
34
- def __init__(self, path):
37
+ repo: Repo | None
38
+
39
+ def __init__(self, path: str) -> None:
35
40
  # If we have a valid repo, git_version will be a tuple
36
41
  # of 3+ ints: (major, minor, patch, possible_additional_patch_number)
37
42
  self.git_version: tuple[int, ...] | None = None
@@ -39,11 +44,7 @@ class GitRepo:
39
44
  try:
40
45
  import git
41
46
 
42
- # GitPython is not fully typed, and mypy is outputting inconsistent
43
- # type errors on Mac and Linux. We bypass type checking entirely
44
- # by redeclaring the `git` import as an "Any".
45
- git_package: Any = git
46
- self.repo = git_package.Repo(path, search_parent_directories=True)
47
+ self.repo = git.Repo(path, search_parent_directories=True)
47
48
  self.git_version = self.repo.git.version_info
48
49
 
49
50
  if self.git_version >= MIN_GIT_VERSION:
@@ -69,8 +70,8 @@ class GitRepo:
69
70
  )
70
71
 
71
72
  @property
72
- def tracking_branch(self):
73
- if not self.is_valid():
73
+ def tracking_branch(self) -> RemoteReference | None:
74
+ if self.repo is None or not self.is_valid():
74
75
  return None
75
76
 
76
77
  if self.is_head_detached:
@@ -79,41 +80,45 @@ class GitRepo:
79
80
  return self.repo.active_branch.tracking_branch()
80
81
 
81
82
  @property
82
- def untracked_files(self):
83
- if not self.is_valid():
83
+ def untracked_files(self) -> list[str] | None:
84
+ if self.repo is None or not self.is_valid():
84
85
  return None
85
86
 
86
87
  return self.repo.untracked_files
87
88
 
88
89
  @property
89
- def is_head_detached(self):
90
- if not self.is_valid():
90
+ def is_head_detached(self) -> bool:
91
+ if self.repo is None or not self.is_valid():
91
92
  return False
92
93
 
93
94
  return self.repo.head.is_detached
94
95
 
95
96
  @property
96
- def uncommitted_files(self):
97
- if not self.is_valid():
97
+ def uncommitted_files(self) -> list[str] | None:
98
+ if self.repo is None or not self.is_valid():
98
99
  return None
99
100
 
100
- return [item.a_path for item in self.repo.index.diff(None)]
101
+ return [cast("str", item.a_path) for item in self.repo.index.diff(None)]
101
102
 
102
103
  @property
103
- def ahead_commits(self):
104
- if not self.is_valid():
104
+ def ahead_commits(self) -> list[Commit] | None:
105
+ if self.repo is None or not self.is_valid():
105
106
  return None
106
107
 
107
108
  try:
108
- remote, branch_name = self.get_tracking_branch_remote()
109
+ tracking_branch_info = self.get_tracking_branch_remote()
110
+ if tracking_branch_info is None:
111
+ return None
112
+
113
+ remote, branch_name = tracking_branch_info
109
114
  remote_branch = f"{remote.name}/{branch_name}"
110
115
 
111
116
  return list(self.repo.iter_commits(f"{remote_branch}..{branch_name}"))
112
117
  except Exception:
113
118
  return []
114
119
 
115
- def get_tracking_branch_remote(self):
116
- if not self.is_valid():
120
+ def get_tracking_branch_remote(self) -> tuple[Remote, str] | None:
121
+ if self.repo is None or not self.is_valid():
117
122
  return None
118
123
 
119
124
  tracking_branch = self.tracking_branch
@@ -21,7 +21,7 @@ import streamlit as st
21
21
  from streamlit.hello.utils import show_code
22
22
 
23
23
 
24
- def data_frame_demo():
24
+ def data_frame_demo() -> None:
25
25
  @st.cache_data
26
26
  def get_un_data() -> pd.DataFrame:
27
27
  AWS_BUCKET_URL = "https://streamlit-demo-data.s3-us-west-2.amazonaws.com"
@@ -21,7 +21,7 @@ import streamlit as st
21
21
  from streamlit.hello.utils import show_code
22
22
 
23
23
 
24
- def mapping_demo():
24
+ def mapping_demo() -> None:
25
25
  @st.cache_data
26
26
  def from_data_file(filename: str) -> pd.DataFrame:
27
27
  url = (
@@ -20,14 +20,14 @@ import streamlit as st
20
20
  from streamlit.hello.utils import show_code
21
21
 
22
22
 
23
- def plotting_demo():
23
+ def plotting_demo() -> None:
24
24
  progress_bar = st.sidebar.progress(0)
25
25
  status_text = st.sidebar.empty()
26
- last_rows = np.random.randn(1, 1)
26
+ last_rows = np.random.randn(1, 1) # noqa: NPY002
27
27
  chart = st.line_chart(last_rows)
28
28
 
29
29
  for i in range(1, 101):
30
- new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
30
+ new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0) # noqa: NPY002
31
31
  status_text.text(f"{i}% complete")
32
32
  chart.add_rows(new_rows)
33
33
  progress_bar.progress(i)
@@ -20,7 +20,7 @@ dir_path = Path(__file__).parent
20
20
 
21
21
 
22
22
  # Note that this needs to be in a method so we can have an e2e playwright test.
23
- def run():
23
+ def run() -> None:
24
24
  page = st.navigation(
25
25
  [
26
26
  st.Page(