streamlit 1.53.1__py3-none-any.whl → 1.54.0__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 (309) hide show
  1. streamlit/__init__.py +1 -31
  2. streamlit/auth_util.py +91 -2
  3. streamlit/cli_util.py +3 -2
  4. streamlit/commands/echo.py +2 -2
  5. streamlit/commands/execution_control.py +1 -1
  6. streamlit/commands/logo.py +76 -24
  7. streamlit/commands/navigation.py +1 -1
  8. streamlit/components/types/base_custom_component.py +0 -2
  9. streamlit/components/v1/custom_component.py +0 -2
  10. streamlit/components/v2/bidi_component/main.py +2 -2
  11. streamlit/components/v2/component_path_utils.py +17 -29
  12. streamlit/components/v2/manifest_scanner.py +8 -3
  13. streamlit/components/v2/presentation.py +1 -1
  14. streamlit/config.py +57 -13
  15. streamlit/config_util.py +5 -5
  16. streamlit/connections/snowflake_connection.py +5 -3
  17. streamlit/dataframe_util.py +10 -10
  18. streamlit/deprecation_util.py +19 -1
  19. streamlit/elements/arrow.py +18 -8
  20. streamlit/elements/deck_gl_json_chart.py +6 -2
  21. streamlit/elements/exception.py +4 -2
  22. streamlit/elements/form.py +1 -1
  23. streamlit/elements/layouts.py +1 -1
  24. streamlit/elements/lib/built_in_chart_utils.py +36 -13
  25. streamlit/elements/lib/color_util.py +21 -2
  26. streamlit/elements/lib/column_config_utils.py +9 -7
  27. streamlit/elements/lib/dialog.py +1 -1
  28. streamlit/elements/lib/image_utils.py +5 -5
  29. streamlit/elements/lib/layout_utils.py +1 -1
  30. streamlit/elements/lib/options_selector_utils.py +72 -22
  31. streamlit/elements/lib/policies.py +1 -1
  32. streamlit/elements/lib/streamlit_plotly_theme.py +9 -11
  33. streamlit/elements/lib/utils.py +1 -1
  34. streamlit/elements/map.py +6 -6
  35. streamlit/elements/plotly_chart.py +2 -2
  36. streamlit/elements/toast.py +1 -1
  37. streamlit/elements/vega_charts.py +30 -7
  38. streamlit/elements/widgets/button.py +3 -3
  39. streamlit/elements/widgets/button_group.py +3 -3
  40. streamlit/elements/widgets/chat.py +1 -1
  41. streamlit/elements/widgets/data_editor.py +6 -6
  42. streamlit/elements/widgets/multiselect.py +1 -1
  43. streamlit/elements/widgets/number_input.py +1 -1
  44. streamlit/elements/widgets/radio.py +91 -31
  45. streamlit/elements/widgets/select_slider.py +123 -37
  46. streamlit/elements/widgets/slider.py +5 -5
  47. streamlit/elements/widgets/time_widgets.py +150 -18
  48. streamlit/elements/write.py +2 -3
  49. streamlit/env_util.py +1 -1
  50. streamlit/errors.py +2 -14
  51. streamlit/external/langchain/streamlit_callback_handler.py +1 -1
  52. streamlit/hello/dataframe_demo.py +1 -1
  53. streamlit/hello/plotting_demo.py +19 -12
  54. streamlit/path_security.py +98 -0
  55. streamlit/proto/Alert_pb2.py +2 -3
  56. streamlit/proto/AppPage_pb2.py +2 -3
  57. streamlit/proto/ArrowData_pb2.py +2 -3
  58. streamlit/proto/ArrowNamedDataSet_pb2.py +2 -3
  59. streamlit/proto/ArrowVegaLiteChart_pb2.py +2 -3
  60. streamlit/proto/Arrow_pb2.py +2 -3
  61. streamlit/proto/AudioInput_pb2.py +2 -3
  62. streamlit/proto/Audio_pb2.py +2 -3
  63. streamlit/proto/AuthRedirect_pb2.py +2 -3
  64. streamlit/proto/AutoRerun_pb2.py +2 -3
  65. streamlit/proto/BackMsg_pb2.py +2 -3
  66. streamlit/proto/Balloons_pb2.py +2 -3
  67. streamlit/proto/BidiComponent_pb2.py +2 -3
  68. streamlit/proto/Block_pb2.py +2 -3
  69. streamlit/proto/BokehChart_pb2.py +2 -3
  70. streamlit/proto/ButtonGroup_pb2.py +2 -3
  71. streamlit/proto/ButtonLikeIconPosition_pb2.py +2 -3
  72. streamlit/proto/Button_pb2.py +2 -3
  73. streamlit/proto/CameraInput_pb2.py +2 -3
  74. streamlit/proto/ChatInput_pb2.py +2 -3
  75. streamlit/proto/Checkbox_pb2.py +2 -3
  76. streamlit/proto/ClientState_pb2.py +2 -3
  77. streamlit/proto/Code_pb2.py +2 -3
  78. streamlit/proto/ColorPicker_pb2.py +2 -3
  79. streamlit/proto/Common_pb2.py +2 -3
  80. streamlit/proto/Components_pb2.py +2 -3
  81. streamlit/proto/DataFrame_pb2.py +2 -3
  82. streamlit/proto/DateInput_pb2.py +2 -3
  83. streamlit/proto/DateTimeInput_pb2.py +2 -3
  84. streamlit/proto/DeckGlJsonChart_pb2.py +2 -3
  85. streamlit/proto/Delta_pb2.py +2 -3
  86. streamlit/proto/DocString_pb2.py +2 -3
  87. streamlit/proto/DownloadButton_pb2.py +2 -3
  88. streamlit/proto/Element_pb2.py +2 -3
  89. streamlit/proto/Empty_pb2.py +2 -3
  90. streamlit/proto/Exception_pb2.py +2 -3
  91. streamlit/proto/Favicon_pb2.py +2 -3
  92. streamlit/proto/FileUploader_pb2.py +2 -3
  93. streamlit/proto/ForwardMsg_pb2.py +2 -3
  94. streamlit/proto/GapSize_pb2.py +2 -3
  95. streamlit/proto/GitInfo_pb2.py +2 -3
  96. streamlit/proto/GraphVizChart_pb2.py +2 -3
  97. streamlit/proto/Heading_pb2.py +2 -3
  98. streamlit/proto/HeightConfig_pb2.py +2 -3
  99. streamlit/proto/Html_pb2.py +2 -3
  100. streamlit/proto/IFrame_pb2.py +2 -3
  101. streamlit/proto/Image_pb2.py +2 -3
  102. streamlit/proto/Json_pb2.py +2 -3
  103. streamlit/proto/LabelVisibilityMessage_pb2.py +2 -3
  104. streamlit/proto/LinkButton_pb2.py +2 -3
  105. streamlit/proto/Logo_pb2.py +6 -5
  106. streamlit/proto/Logo_pb2.pyi +25 -1
  107. streamlit/proto/Markdown_pb2.py +2 -3
  108. streamlit/proto/Metric_pb2.py +2 -3
  109. streamlit/proto/MetricsEvent_pb2.py +2 -3
  110. streamlit/proto/MultiSelect_pb2.py +2 -3
  111. streamlit/proto/NamedDataSet_pb2.py +2 -3
  112. streamlit/proto/Navigation_pb2.py +2 -3
  113. streamlit/proto/NewSession_pb2.py +25 -24
  114. streamlit/proto/NewSession_pb2.pyi +28 -2
  115. streamlit/proto/NumberInput_pb2.py +2 -3
  116. streamlit/proto/PageConfig_pb2.py +2 -3
  117. streamlit/proto/PageInfo_pb2.py +2 -3
  118. streamlit/proto/PageLink_pb2.py +2 -3
  119. streamlit/proto/PageNotFound_pb2.py +2 -3
  120. streamlit/proto/PageProfile_pb2.py +2 -3
  121. streamlit/proto/PagesChanged_pb2.py +2 -3
  122. streamlit/proto/ParentMessage_pb2.py +2 -3
  123. streamlit/proto/PlotlyChart_pb2.py +2 -3
  124. streamlit/proto/Progress_pb2.py +2 -3
  125. streamlit/proto/Radio_pb2.py +5 -4
  126. streamlit/proto/Radio_pb2.pyi +20 -3
  127. streamlit/proto/RootContainer_pb2.py +2 -3
  128. streamlit/proto/Selectbox_pb2.py +2 -3
  129. streamlit/proto/SessionEvent_pb2.py +2 -3
  130. streamlit/proto/SessionStatus_pb2.py +2 -3
  131. streamlit/proto/Skeleton_pb2.py +2 -3
  132. streamlit/proto/Slider_pb2.py +7 -8
  133. streamlit/proto/Slider_pb2.pyi +9 -1
  134. streamlit/proto/Snow_pb2.py +2 -3
  135. streamlit/proto/Space_pb2.py +2 -3
  136. streamlit/proto/Spinner_pb2.py +2 -3
  137. streamlit/proto/TextAlignmentConfig_pb2.py +2 -3
  138. streamlit/proto/TextArea_pb2.py +2 -3
  139. streamlit/proto/TextInput_pb2.py +2 -3
  140. streamlit/proto/Text_pb2.py +2 -3
  141. streamlit/proto/TimeInput_pb2.py +2 -3
  142. streamlit/proto/Toast_pb2.py +2 -3
  143. streamlit/proto/Transient_pb2.py +2 -3
  144. streamlit/proto/VegaLiteChart_pb2.py +2 -3
  145. streamlit/proto/Video_pb2.py +2 -3
  146. streamlit/proto/WidgetStates_pb2.py +2 -3
  147. streamlit/proto/WidthConfig_pb2.py +2 -3
  148. streamlit/proto/openmetrics_data_model_pb2.py +2 -3
  149. streamlit/runtime/app_session.py +106 -60
  150. streamlit/runtime/caching/cache_data_api.py +3 -3
  151. streamlit/runtime/caching/cache_errors.py +0 -2
  152. streamlit/runtime/caching/cache_resource_api.py +1 -1
  153. streamlit/runtime/caching/cache_utils.py +2 -2
  154. streamlit/runtime/caching/hashing.py +1 -3
  155. streamlit/runtime/caching/storage/cache_storage_protocol.py +0 -3
  156. streamlit/runtime/connection_factory.py +1 -1
  157. streamlit/runtime/credentials.py +2 -2
  158. streamlit/runtime/metrics_util.py +3 -3
  159. streamlit/runtime/runtime.py +6 -6
  160. streamlit/runtime/scriptrunner/script_runner.py +17 -0
  161. streamlit/runtime/scriptrunner_utils/exceptions.py +0 -4
  162. streamlit/runtime/scriptrunner_utils/script_run_context.py +13 -31
  163. streamlit/runtime/secrets.py +3 -4
  164. streamlit/runtime/state/__init__.py +7 -1
  165. streamlit/runtime/state/common.py +13 -0
  166. streamlit/runtime/state/query_params.py +493 -24
  167. streamlit/runtime/state/session_state.py +179 -4
  168. streamlit/runtime/state/widgets.py +26 -1
  169. streamlit/runtime/stats.py +1 -10
  170. streamlit/static/index.html +1 -1
  171. streamlit/static/manifest.json +304 -304
  172. streamlit/static/static/js/{ErrorOutline.esm.CScZvf44.js → ErrorOutline.esm.BWk6F-Tz.js} +1 -1
  173. streamlit/static/static/js/{FileDownload.esm.COCxTZxP.js → FileDownload.esm.AllYUuOW.js} +1 -1
  174. streamlit/static/static/js/{FileHelper.Bhs-iVRI.js → FileHelper.BvVTNdmy.js} +1 -1
  175. streamlit/static/static/js/{FormClearHelper.CA_5b-Ut.js → FormClearHelper.C__r5Llk.js} +1 -1
  176. streamlit/static/static/js/{InputInstructions.Bzb0MCfv.js → InputInstructions.DOtkdOMV.js} +1 -1
  177. streamlit/static/static/js/Particles.DCsqQZlE.js +1 -0
  178. streamlit/static/static/js/{ProgressBar.DyQNhVsJ.js → ProgressBar.DLCRvt4m.js} +2 -2
  179. streamlit/static/static/js/{StreamlitSyntaxHighlighter.BOkJThtV.js → StreamlitSyntaxHighlighter.CYFWoZHb.js} +1 -1
  180. streamlit/static/static/js/{TableChart.esm.a60nntBC.js → TableChart.esm.D6ydHcIm.js} +1 -1
  181. streamlit/static/static/js/Toolbar.BHDNzWBx.js +1 -0
  182. streamlit/static/static/js/{WidgetLabelHelpIconInline.BjIku2ic.js → WidgetLabelHelpIconInline.DEXBrVlc.js} +1 -1
  183. streamlit/static/static/js/{base-input.avGkArOc.js → base-input.TSQjctlq.js} +4 -4
  184. streamlit/static/static/js/{checkbox.Q8mCuqps.js → checkbox.BKgfzJZV.js} +1 -1
  185. streamlit/static/static/js/{createDownloadLinkElement.CfqHRpxo.js → createDownloadLinkElement.CG7nr2a4.js} +1 -1
  186. streamlit/static/static/js/{data-grid-overlay-editor.PuoMl3yV.js → data-grid-overlay-editor.ChXO__lP.js} +1 -1
  187. streamlit/static/static/js/{downloader.CjG2csSm.js → downloader.DJ3R_zWA.js} +1 -1
  188. streamlit/static/static/js/embed.u3PPfLkw.js +193 -0
  189. streamlit/static/static/js/{es6.CQD6uUK7.js → es6.C5Mfy8nd.js} +2 -2
  190. streamlit/static/static/js/{formatNumber.CtjUO-if.js → formatNumber.CMRgW9EJ.js} +1 -1
  191. streamlit/static/static/js/{iconPosition.7Qt6oUiI.js → iconPosition.B4EEXI3E.js} +1 -1
  192. streamlit/static/static/js/{iframeResizer.contentWindow._oj2Xh0v.js → iframeResizer.contentWindow.WSvOiTW0.js} +1 -1
  193. streamlit/static/static/js/index.-FOBV3nz.js +1 -0
  194. streamlit/static/static/js/{index.BuBkymZd.js → index.-NF8OSF5.js} +1 -1
  195. streamlit/static/static/js/{index.B-XrnnK6.js → index.4cBg8kn5.js} +1 -1
  196. streamlit/static/static/js/{index.B_ylV_tl.js → index.B0pzzCsH.js} +1 -1
  197. streamlit/static/static/js/{index.BhJwyXH6.js → index.BID6ND5j.js} +2 -2
  198. streamlit/static/static/js/index.BMp5bGjh.js +1 -0
  199. streamlit/static/static/js/{index.Cptu1tS-.js → index.BQcmlvas.js} +1 -1
  200. streamlit/static/static/js/{index.DXQ_Fvpt.js → index.BRcmclgI.js} +1 -1
  201. streamlit/static/static/js/index.BaUZR4IG.js +1 -0
  202. streamlit/static/static/js/{index.CMBgAPh6.js → index.BbMJj4PN.js} +1 -1
  203. streamlit/static/static/js/{index.CVRgrLT-.js → index.BdCTJtq3.js} +2 -2
  204. streamlit/static/static/js/index.BdETLMuI.js +1 -0
  205. streamlit/static/static/js/index.BnKMWhs1.js +1 -0
  206. streamlit/static/static/js/index.Br1kXwQW.js +2 -0
  207. streamlit/static/static/js/{index.XGft6-dq.js → index.Bt2olRE4.js} +1 -1
  208. streamlit/static/static/js/{index.B2fAYU1N.js → index.Bxwsv5T8.js} +1 -1
  209. streamlit/static/static/js/index.C4KskYz6.js +1 -0
  210. streamlit/static/static/js/{index.DZE_91Ym.js → index.C6bmbXk0.js} +1 -1
  211. streamlit/static/static/js/{index.Egabyb7u.js → index.CEfKfbta.js} +1 -1
  212. streamlit/static/static/js/index.CIuaA8q0.js +2 -0
  213. streamlit/static/static/js/{index.DVtfSohT.js → index.CV1sObFX.js} +1 -1
  214. streamlit/static/static/js/{index.BlJhnb4M.js → index.CbR6dgaV.js} +1 -1
  215. streamlit/static/static/js/index.Cq6szKqJ.js +1 -0
  216. streamlit/static/static/js/index.CyouXqCz.js +1 -0
  217. streamlit/static/static/js/{index.B5wmZkRW.js → index.D1NUgMFI.js} +1 -1
  218. streamlit/static/static/js/{index.euRMkmNi.js → index.D7SWG4Om.js} +1 -1
  219. streamlit/static/static/js/{index.Bg-9YNUa.js → index.DAYPEwLI.js} +1 -1
  220. streamlit/static/static/js/index.DKS75Vfg.js +11 -0
  221. streamlit/static/static/js/{index.CIizdLeb.js → index.DOXrMIxB.js} +1 -1
  222. streamlit/static/static/js/{index.BRegnbUa.js → index.DOzYX8yS.js} +3 -3
  223. streamlit/static/static/js/{index.BksGMsW0.js → index.DRFMYcC4.js} +4 -4
  224. streamlit/static/static/js/{index.B8PovXCX.js → index.Divl5FCY.js} +1 -1
  225. streamlit/static/static/js/{index.DxQuXlXH.js → index.DjAJ_CUa.js} +1 -1
  226. streamlit/static/static/js/{index.BrRuSP42.js → index.Dncue2pm.js} +33 -33
  227. streamlit/static/static/js/{index.DSTThs-t.js → index.Drusyo5m.js} +47 -47
  228. streamlit/static/static/js/{index.BOafPwIE.js → index.DuUyDGnP.js} +1 -1
  229. streamlit/static/static/js/{index.D1bkwsLT.js → index.DvgT2rB2.js} +223 -223
  230. streamlit/static/static/js/{index.BmDXWfgx.js → index.DzutABu5.js} +2 -2
  231. streamlit/static/static/js/index.Dzw2iPzi.js +3 -0
  232. streamlit/static/static/js/{index.DJsqD2Sc.js → index.FsTmxLbT.js} +1 -1
  233. streamlit/static/static/js/{index.BOTEMJfV.js → index.OIwPqGYN.js} +1 -1
  234. streamlit/static/static/js/{index.CBqST2Yj.js → index.RXLN7YFT.js} +2 -2
  235. streamlit/static/static/js/{index.Ft2Zxbhr.js → index.YYb2u0jk.js} +2 -2
  236. streamlit/static/static/js/{index.BWCFtBS4.js → index.h8ejt-W3.js} +1 -1
  237. streamlit/static/static/js/{index.KuLql7H0.js → index.lFMCi9am.js} +1 -1
  238. streamlit/static/static/js/{index.D8t7R4QQ.js → index.pOgf4cEj.js} +1 -1
  239. streamlit/static/static/js/{index.CsoN0h7K.js → index.s_E0s7LB.js} +51 -51
  240. streamlit/static/static/js/{index.BVX_bqnf.js → index.xLCbzoqj.js} +1 -1
  241. streamlit/static/static/js/{input.Cf97CQME.js → input.BLG7kWaj.js} +2 -2
  242. streamlit/static/static/js/{main.Ccuk53yQ.js → main.D_CmqChN.js} +1 -1
  243. streamlit/static/static/js/{memory.Bng6Ij0g.js → memory.T8u9KqIQ.js} +1 -1
  244. streamlit/static/static/js/{number-overlay-editor.CFLv-CWC.js → number-overlay-editor.BKBSXkAM.js} +2 -2
  245. streamlit/static/static/js/{pandasStylerUtils.C2hcAKiv.js → pandasStylerUtils.B4tLYMwS.js} +1 -1
  246. streamlit/static/static/js/{sandbox.BXdeD-wA.js → sandbox.jRlkcPem.js} +1 -1
  247. streamlit/static/static/js/{styled-components.Br04Ogac.js → styled-components.D2QhNwzd.js} +1 -1
  248. streamlit/static/static/js/{throttle.mI9ItGre.js → throttle.Cyw_V0Dq.js} +1 -1
  249. streamlit/static/static/js/{timepicker.poFdB0sd.js → timepicker.PzyuDDWl.js} +1 -1
  250. streamlit/static/static/js/{toConsumableArray.92-fANS-.js → toConsumableArray.gE9fMkLj.js} +1 -1
  251. streamlit/static/static/js/uniqueId.B1GeHnT1.js +1 -0
  252. streamlit/static/static/js/{useBasicWidgetState.DzKGLAv_.js → useBasicWidgetState.DFklfao0.js} +1 -1
  253. streamlit/static/static/js/{useIntlLocale.BMma2iiY.js → useIntlLocale.C3tUGWTU.js} +8 -8
  254. streamlit/static/static/js/{useTextInputAutoExpand.DQbIhdma.js → useTextInputAutoExpand.D9nU_y-e.js} +1 -1
  255. streamlit/static/static/js/useUpdateUiValue.ClTdrkJN.js +1 -0
  256. streamlit/static/static/js/{useWaveformController.AH0ggRyc.js → useWaveformController.lzTbjMW2.js} +1 -1
  257. streamlit/static/static/js/{withCalculatedWidth.G5xJ-MbS.js → withCalculatedWidth.Dxs9I5Oe.js} +1 -1
  258. streamlit/static/static/js/{withFullScreenWrapper.rdRu6zZ4.js → withFullScreenWrapper.DfpAcJxf.js} +1 -1
  259. streamlit/string_util.py +2 -2
  260. streamlit/testing/v1/app_test.py +1 -1
  261. streamlit/testing/v1/element_tree.py +33 -20
  262. streamlit/type_util.py +2 -2
  263. streamlit/url_util.py +2 -2
  264. streamlit/user_info.py +2 -41
  265. streamlit/util.py +1 -1
  266. streamlit/watcher/event_based_path_watcher.py +37 -7
  267. streamlit/watcher/path_watcher.py +61 -2
  268. streamlit/watcher/util.py +26 -10
  269. streamlit/web/bootstrap.py +16 -4
  270. streamlit/web/cli.py +1 -4
  271. streamlit/web/server/app_discovery.py +2 -1
  272. streamlit/web/server/app_static_file_handler.py +9 -0
  273. streamlit/web/server/bidi_component_request_handler.py +4 -4
  274. streamlit/web/server/component_file_utils.py +14 -6
  275. streamlit/web/server/component_request_handler.py +2 -2
  276. streamlit/web/server/oauth_authlib_routes.py +14 -42
  277. streamlit/web/server/server.py +1 -1
  278. streamlit/web/server/server_util.py +23 -1
  279. streamlit/web/server/starlette/starlette_app.py +7 -1
  280. streamlit/web/server/starlette/starlette_auth_routes.py +94 -16
  281. streamlit/web/server/starlette/starlette_path_security_middleware.py +97 -0
  282. streamlit/web/server/starlette/starlette_routes.py +16 -9
  283. streamlit/web/server/starlette/starlette_server.py +2 -2
  284. streamlit/web/server/starlette/starlette_static_routes.py +14 -4
  285. streamlit/web/server/stats_request_handler.py +1 -3
  286. {streamlit-1.53.1.dist-info → streamlit-1.54.0.dist-info}/METADATA +10 -25
  287. {streamlit-1.53.1.dist-info → streamlit-1.54.0.dist-info}/RECORD +290 -290
  288. {streamlit-1.53.1.dist-info → streamlit-1.54.0.dist-info}/WHEEL +1 -1
  289. streamlit/commands/experimental_query_params.py +0 -169
  290. streamlit/static/static/js/Particles.ix5_l22I.js +0 -1
  291. streamlit/static/static/js/Toolbar.CxkcuBQ8.js +0 -1
  292. streamlit/static/static/js/embed.DZ-CLCPz.js +0 -195
  293. streamlit/static/static/js/index.B6ZAXv47.js +0 -1
  294. streamlit/static/static/js/index.BDm-Ia27.js +0 -1
  295. streamlit/static/static/js/index.BeCZLkzg.js +0 -1
  296. streamlit/static/static/js/index.BuEBeckn.js +0 -11
  297. streamlit/static/static/js/index.CL2eCR01.js +0 -1
  298. streamlit/static/static/js/index.CdLlbsiN.js +0 -1
  299. streamlit/static/static/js/index.CwIIk90V.js +0 -1
  300. streamlit/static/static/js/index.DDk0U8rh.js +0 -2
  301. streamlit/static/static/js/index.DNB79dOd.js +0 -3
  302. streamlit/static/static/js/index.DNj5S4tY.js +0 -1
  303. streamlit/static/static/js/index.DOY0ZriT.js +0 -2
  304. streamlit/static/static/js/index.r0gCrMFP.js +0 -1
  305. streamlit/static/static/js/uniqueId.BUj-C6GA.js +0 -1
  306. streamlit/static/static/js/useUpdateUiValue.Bk5OIXup.js +0 -1
  307. streamlit-1.53.1.data/scripts/streamlit.cmd +0 -16
  308. {streamlit-1.53.1.dist-info → streamlit-1.54.0.dist-info}/entry_points.txt +0 -0
  309. {streamlit-1.53.1.dist-info → streamlit-1.54.0.dist-info}/top_level.txt +0 -0
streamlit/config_util.py CHANGED
@@ -194,7 +194,7 @@ def _clean(txt: str) -> str:
194
194
 
195
195
  Preserves leading and trailing spaces, and does not modify spaces in between lines.
196
196
  """
197
- return re.sub(" +", " ", txt)
197
+ return re.sub(r" +", " ", txt)
198
198
 
199
199
 
200
200
  def _clean_paragraphs(txt: str) -> list[str]:
@@ -741,7 +741,7 @@ def process_theme_inheritance(
741
741
  base_value = base_option.value
742
742
 
743
743
  # Check if it's a file path or URL (not just "light" or "dark")
744
- if base_value in ("light", "dark"):
744
+ if base_value in {"light", "dark"}:
745
745
  return
746
746
 
747
747
  def _raise_invalid_nested_base() -> None:
@@ -756,7 +756,7 @@ def process_theme_inheritance(
756
756
 
757
757
  # Validate that theme.base of the referenced theme file doesn't reference another file
758
758
  theme_base = theme_file_content.get("theme", {}).get("base")
759
- if theme_base and theme_base not in ("light", "dark"):
759
+ if theme_base and theme_base not in {"light", "dark"}:
760
760
  _raise_invalid_nested_base()
761
761
 
762
762
  # Get current theme options from main config.toml
@@ -777,10 +777,10 @@ def process_theme_inheritance(
777
777
  opt_name.startswith("theme.")
778
778
  and opt_name != "theme.base"
779
779
  and opt_config.where_defined
780
- in (
780
+ in {
781
781
  "environment variable",
782
782
  "command-line argument or environment variable",
783
- )
783
+ }
784
784
  ):
785
785
  high_precedence_theme_options[opt_name] = {
786
786
  "value": opt_config.value,
@@ -135,7 +135,9 @@ class BaseSnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
135
135
  ),
136
136
  wait=wait_fixed(1),
137
137
  )
138
- def _query(sql: str) -> DataFrame:
138
+ # `params` must be an explicit parameter (not captured from closure) so that
139
+ # `@st.cache_data` includes it in the cache key.
140
+ def _query(sql: str, params: Any = None) -> DataFrame:
139
141
  cur = self._instance.cursor()
140
142
  cur.execute(sql, params=params, **kwargs)
141
143
  return cur.fetch_pandas_all() # type: ignore
@@ -153,7 +155,7 @@ class BaseSnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
153
155
  ttl=ttl,
154
156
  )(_query)
155
157
 
156
- return _query(sql)
158
+ return _query(sql, params)
157
159
 
158
160
  def write_pandas(
159
161
  self,
@@ -685,7 +687,7 @@ class SnowflakeCallersRightsConnection(SnowflakeConnection):
685
687
  @classmethod
686
688
  def _read_token_file(cls) -> str:
687
689
  """Returns the contents of the Snowpark token file on disk."""
688
- with open(SNOWPARK_CONNECTION_TOKEN_FILE) as token_file:
690
+ with open(SNOWPARK_CONNECTION_TOKEN_FILE, encoding="utf-8") as token_file:
689
691
  return token_file.read()
690
692
 
691
693
  @classmethod
@@ -464,7 +464,7 @@ def _is_list_of_scalars(data: Iterable[Any]) -> bool:
464
464
 
465
465
  # Overview on all value that are interpreted as scalar:
466
466
  # https://pandas.pydata.org/docs/reference/api/pandas.api.types.is_scalar.html
467
- return infer_dtype(data, skipna=True) not in ["mixed", "unknown-array"]
467
+ return infer_dtype(data, skipna=True) not in {"mixed", "unknown-array"}
468
468
 
469
469
 
470
470
  def _iterable_to_list(
@@ -1056,9 +1056,7 @@ def is_colum_type_arrow_incompatible(column: Series[Any] | Index[Any]) -> bool:
1056
1056
  """
1057
1057
  from pandas.api.types import infer_dtype, is_dict_like, is_list_like
1058
1058
 
1059
- if column.dtype.kind in [
1060
- "c", # complex64, complex128, complex256
1061
- ]:
1059
+ if column.dtype.kind == "c": # complex64, complex128, complex256
1062
1060
  return True
1063
1061
 
1064
1062
  if str(column.dtype) in {
@@ -1074,15 +1072,17 @@ def is_colum_type_arrow_incompatible(column: Series[Any] | Index[Any]) -> bool:
1074
1072
  return True
1075
1073
 
1076
1074
  if column.dtype == "object":
1077
- # The dtype of mixed type columns is always object, the actual type of the column
1078
- # values can be determined via the infer_dtype function:
1075
+ # The dtype of mixed type columns is always object. In pandas 3.0+, pure
1076
+ # string columns use StringDtype instead of object, so they won't enter
1077
+ # this block (and they're Arrow-compatible anyway). The actual type of
1078
+ # object dtype column values can be determined via the infer_dtype function:
1079
1079
  # https://pandas.pydata.org/docs/reference/api/pandas.api.types.infer_dtype.html
1080
1080
  inferred_type = infer_dtype(column, skipna=True)
1081
1081
 
1082
- if inferred_type in [
1082
+ if inferred_type in {
1083
1083
  "mixed-integer",
1084
1084
  "complex",
1085
- ]:
1085
+ }:
1086
1086
  return True
1087
1087
  if inferred_type == "mixed":
1088
1088
  # This includes most of the more complex/custom types (objects, dicts,
@@ -1405,11 +1405,11 @@ def convert_pandas_df_to_data_format(
1405
1405
  return _unify_missing_values(df).to_dict(orient="list")
1406
1406
  if data_format == DataFormat.COLUMN_SERIES_MAPPING:
1407
1407
  return df.to_dict(orient="series")
1408
- if data_format in [
1408
+ if data_format in {
1409
1409
  DataFormat.LIST_OF_VALUES,
1410
1410
  DataFormat.TUPLE_OF_VALUES,
1411
1411
  DataFormat.SET_OF_VALUES,
1412
- ]:
1412
+ }:
1413
1413
  df = _unify_missing_values(df)
1414
1414
  return_list = []
1415
1415
  if len(df.columns) == 1:
@@ -21,12 +21,17 @@ from typing import Any, Final, TypeVar, cast
21
21
  import streamlit
22
22
  from streamlit import config
23
23
  from streamlit.logger import get_logger
24
+ from streamlit.util import calc_md5
24
25
 
25
26
  _LOGGER: Final = get_logger(__name__)
26
27
 
27
28
  TFunc = TypeVar("TFunc", bound=Callable[..., Any])
28
29
  TObj = TypeVar("TObj", bound=object)
29
30
 
31
+ # Set to track which deprecation warnings have been shown (by message hash)
32
+ # when show_once=True is used
33
+ _shown_warnings: set[str] = set()
34
+
30
35
 
31
36
  def _error_details_in_browser_enabled() -> bool:
32
37
  """True if we should print deprecation warnings to the browser.
@@ -42,7 +47,9 @@ def _error_details_in_browser_enabled() -> bool:
42
47
  )
43
48
 
44
49
 
45
- def show_deprecation_warning(message: str, show_in_browser: bool = True) -> None:
50
+ def show_deprecation_warning(
51
+ message: str, show_in_browser: bool = True, show_once: bool = False
52
+ ) -> None:
46
53
  """Show a deprecation warning message.
47
54
 
48
55
  Parameters
@@ -55,7 +62,18 @@ def show_deprecation_warning(message: str, show_in_browser: bool = True) -> None
55
62
  set `client.showErrorDetails` to "full" or the legacy True value. All
56
63
  other values ("stacktrace", "type", "none", False) will hide deprecation
57
64
  warnings in the browser (but still log them to the console).
65
+ show_once : bool, default=False
66
+ If True, the warning will only be shown once per unique message (based on
67
+ message hash). Subsequent calls with the same message will be skipped.
68
+ This is useful for warnings that may be triggered many times during a
69
+ script run.
58
70
  """
71
+ if show_once:
72
+ message_hash = calc_md5(message)
73
+ if message_hash in _shown_warnings:
74
+ return
75
+ _shown_warnings.add(message_hash)
76
+
59
77
  if _error_details_in_browser_enabled() and show_in_browser:
60
78
  streamlit.warning(message)
61
79
 
@@ -647,7 +647,7 @@ class ArrowMixin:
647
647
  """
648
648
  import pyarrow as pa
649
649
 
650
- if on_select not in ["ignore", "rerun"] and not callable(on_select):
650
+ if on_select not in {"ignore", "rerun"} and not callable(on_select):
651
651
  raise StreamlitAPIException(
652
652
  f"You have passed {on_select} to `on_select`. But only 'ignore', "
653
653
  "'rerun', or a callable is supported."
@@ -744,13 +744,18 @@ class ArrowMixin:
744
744
  elif (
745
745
  # Hide index column if row selections are activated and the dataframe has a range index.
746
746
  # The range index usually does not add a lot of value.
747
- is_selection_activated
748
- and selection_mode in ["multi-row", "single-row"]
749
- and has_range_index
747
+ is_selection_activated and has_range_index
750
748
  ):
751
- update_column_config(
752
- column_config_mapping, INDEX_IDENTIFIER, {"hidden": True}
749
+ # Normalize selection_mode to a set to check for row selection modes
750
+ mode_set = (
751
+ {selection_mode}
752
+ if isinstance(selection_mode, str)
753
+ else set(selection_mode)
753
754
  )
755
+ if mode_set & {"multi-row", "single-row"}:
756
+ update_column_config(
757
+ column_config_mapping, INDEX_IDENTIFIER, {"hidden": True}
758
+ )
754
759
 
755
760
  marshall_column_config(proto, column_config_mapping)
756
761
 
@@ -771,7 +776,11 @@ class ArrowMixin:
771
776
  proto.id = compute_and_register_element_id(
772
777
  "dataframe",
773
778
  user_key=key,
774
- key_as_main_identity=False,
779
+ # There are some edge cases where selections can become orphaned when the data changes
780
+ # - e.g. when rows get removed. The frontend can handle this without errors,
781
+ # but it might be a nice enhancement to automatically reset the backend & frontend
782
+ # selection state in this case.
783
+ key_as_main_identity={"selection_mode", "is_selection_activated"},
775
784
  dg=self.dg,
776
785
  data=proto.data,
777
786
  width=width,
@@ -974,7 +983,8 @@ class ArrowMixin:
974
983
  " If you have a specific use-case that requires the `add_rows` "
975
984
  "functionality, please tell us via this "
976
985
  "[issue on Github](https://github.com/streamlit/streamlit/issues/13063).",
977
- show_in_browser=False,
986
+ show_in_browser=True,
987
+ show_once=True,
978
988
  )
979
989
 
980
990
  return _arrow_add_rows(self.dg, data, **kwargs)
@@ -531,7 +531,7 @@ class PydeckMixin:
531
531
  key = to_key(key)
532
532
  is_selection_activated = on_select != "ignore"
533
533
 
534
- if on_select not in ["ignore", "rerun"] and not callable(on_select):
534
+ if on_select not in {"ignore", "rerun"} and not callable(on_select):
535
535
  raise StreamlitAPIException(
536
536
  f"You have passed {on_select} to `on_select`. "
537
537
  "But only 'ignore', 'rerun', or a callable is supported."
@@ -556,7 +556,11 @@ class PydeckMixin:
556
556
  pydeck_proto.id = compute_and_register_element_id(
557
557
  "deck_gl_json_chart",
558
558
  user_key=key,
559
- key_as_main_identity=False,
559
+ # When a key is provided, only selection_mode affects the element ID.
560
+ # This allows selection state to persist across data/spec changes.
561
+ # Note: This can lead to orphaned selections if data length shrinks,
562
+ # but the frontend handles this by sanitizing invalid indices.
563
+ key_as_main_identity={"selection_mode"},
560
564
  dg=self.dg,
561
565
  is_selection_activated=is_selection_activated,
562
566
  selection_mode=selection_mode,
@@ -278,8 +278,10 @@ def _get_stack_trace_str_list(exception: BaseException) -> list[str]:
278
278
  # Format the extracted traceback and add it to the protobuf element.
279
279
  if extracted_traceback is None:
280
280
  trace_str_list = [
281
- "Cannot extract the stack trace for this exception. "
282
- "Try calling exception() within the `catch` block."
281
+ (
282
+ "Cannot extract the stack trace for this exception. "
283
+ "Try calling exception() within the `catch` block."
284
+ )
283
285
  ]
284
286
  else:
285
287
  internal_frames, external_frames = _split_internal_streamlit_frames(
@@ -413,7 +413,7 @@ class FormMixin:
413
413
  width = "stretch" if use_container_width else "content"
414
414
 
415
415
  # Checks whether the entered button type is one of the allowed options
416
- if type not in ["primary", "secondary", "tertiary"]:
416
+ if type not in {"primary", "secondary", "tertiary"}:
417
417
  raise StreamlitAPIException(
418
418
  'The type argument to st.form_submit_button must be "primary", "secondary", or "tertiary". \n'
419
419
  f'The argument passed was "{type}".'
@@ -1036,7 +1036,7 @@ class LayoutsMixin:
1036
1036
  width = "stretch" if use_container_width else "content"
1037
1037
 
1038
1038
  # Checks whether the entered button type is one of the allowed options
1039
- if type not in ["primary", "secondary", "tertiary"]:
1039
+ if type not in {"primary", "secondary", "tertiary"}:
1040
1040
  raise StreamlitAPIException(
1041
1041
  'The type argument to st.popover must be "primary", "secondary", or "tertiary". '
1042
1042
  f'\nThe argument passed was "{type}".'
@@ -24,6 +24,7 @@ from typing import TYPE_CHECKING, Any, Final, Literal, TypeAlias, TypedDict, cas
24
24
  from streamlit import dataframe_util, type_util
25
25
  from streamlit.elements.lib.color_util import (
26
26
  Color,
27
+ is_builtin_color_name,
27
28
  is_color_like,
28
29
  is_color_tuple_like,
29
30
  is_hex_color_like,
@@ -136,7 +137,7 @@ def maybe_raise_stack_warning(
136
137
  stack: bool | ChartStackType | None, command: str | None, docs_link: str
137
138
  ) -> None:
138
139
  # Check that the stack parameter is valid, raise more informative error if not
139
- if stack not in (None, True, False, "normalize", "center", "layered"):
140
+ if stack not in {None, True, False, "normalize", "center", "layered"}:
140
141
  raise StreamlitAPIException(
141
142
  f"Invalid value for stack parameter: {stack}. Stack must be one of True, "
142
143
  'False, "normalize", "center", "layered" or None. See documentation '
@@ -425,13 +426,13 @@ def _infer_vegalite_type(
425
426
  # requires Pandas 1.3.
426
427
  typ = infer_dtype(data)
427
428
 
428
- if typ in [
429
+ if typ in {
429
430
  "floating",
430
431
  "mixed-integer-float",
431
432
  "integer",
432
433
  "mixed-integer",
433
434
  "complex",
434
- ]:
435
+ }:
435
436
  return "quantitative"
436
437
 
437
438
  if typ == "categorical" and data.cat.ordered:
@@ -442,9 +443,9 @@ def _infer_vegalite_type(
442
443
  # Altair already extracts the correct sort order somewhere else.
443
444
  # More info about the issue here: https://github.com/streamlit/streamlit/issues/7776
444
445
  return "ordinal"
445
- if typ in ["string", "bytes", "categorical", "boolean", "mixed", "unicode"]:
446
+ if typ in {"string", "bytes", "categorical", "boolean", "mixed", "unicode"}:
446
447
  return "nominal"
447
- if typ in [
448
+ if typ in {
448
449
  "datetime",
449
450
  "datetime64",
450
451
  "timedelta",
@@ -452,7 +453,7 @@ def _infer_vegalite_type(
452
453
  "date",
453
454
  "time",
454
455
  "period",
455
- ]:
456
+ }:
456
457
  return "temporal"
457
458
  # STREAMLIT MOD: I commented this out since Streamlit doesn't use warnings.warn.
458
459
  # > warnings.warn(
@@ -611,6 +612,9 @@ def _melt_data(
611
612
 
612
613
  y_series = melted_df[new_y_column_name]
613
614
  if (
615
+ # After melting columns of different dtypes, the result has object dtype.
616
+ # In pandas 3.0+, melting columns with the same StringDtype keeps StringDtype,
617
+ # so this check correctly identifies only truly mixed-type scenarios.
614
618
  y_series.dtype == "object"
615
619
  and "mixed" in infer_dtype(y_series)
616
620
  and len(y_series.unique()) > 100
@@ -859,9 +863,9 @@ def _maybe_melt(
859
863
  color_column = _MELTED_COLOR_COLUMN_NAME
860
864
 
861
865
  columns_to_leave_alone = [x_column]
862
- if size_column:
866
+ if size_column and size_column not in columns_to_leave_alone:
863
867
  columns_to_leave_alone.append(size_column)
864
- if sort_column:
868
+ if sort_column and sort_column not in columns_to_leave_alone:
865
869
  columns_to_leave_alone.append(sort_column)
866
870
 
867
871
  df = _melt_data(
@@ -913,7 +917,7 @@ def _get_axis_encodings(
913
917
  _update_encoding_with_stack(stack, stack_encoding)
914
918
 
915
919
  # Handle sorting - only relevant for bar charts
916
- if chart_type in (ChartType.VERTICAL_BAR, ChartType.HORIZONTAL_BAR):
920
+ if chart_type in {ChartType.VERTICAL_BAR, ChartType.HORIZONTAL_BAR}:
917
921
  _update_encoding_with_sort(sort_from_user, sort_encoding)
918
922
 
919
923
  return x_encoding, y_encoding
@@ -1077,6 +1081,14 @@ def _get_color_encoding(
1077
1081
 
1078
1082
  return alt.ColorValue(to_css_color(cast("Any", color_value)))
1079
1083
 
1084
+ # Check for built-in color names (resolved on frontend, not converted here)
1085
+ if isinstance(color_value, str) and is_builtin_color_name(color_value):
1086
+ if len(y_column_list) != 1:
1087
+ raise StreamlitColorLengthError(
1088
+ [color_value] if color_value else [], y_column_list
1089
+ )
1090
+ return alt.ColorValue(color_value)
1091
+
1080
1092
  # If the color value is a list of colors of appropriate length, return that.
1081
1093
  if isinstance(color_value, (list, tuple)):
1082
1094
  color_values = cast("Collection[Color]", color_value)
@@ -1085,12 +1097,23 @@ def _get_color_encoding(
1085
1097
  raise StreamlitColorLengthError(color_values, y_column_list)
1086
1098
 
1087
1099
  if len(color_values) == 1:
1088
- return alt.ColorValue(to_css_color(cast("Any", color_value[0])))
1100
+ first_color = cast("Any", color_value[0])
1101
+ # Pass through built-in color names as-is (resolved on frontend)
1102
+ if isinstance(first_color, str) and is_builtin_color_name(first_color):
1103
+ return alt.ColorValue(first_color)
1104
+ return alt.ColorValue(to_css_color(first_color))
1105
+
1106
+ # Convert colors, but pass through built-in color names as-is
1107
+ resolved_colors: list[Color] = []
1108
+ for c in color_values:
1109
+ if isinstance(c, str) and is_builtin_color_name(c):
1110
+ resolved_colors.append(c)
1111
+ else:
1112
+ resolved_colors.append(to_css_color(c))
1113
+
1089
1114
  return alt.Color(
1090
1115
  field=color_column if color_column is not None else alt.Undefined,
1091
- scale=alt.Scale(
1092
- domain=y_column_list, range=[to_css_color(c) for c in color_values]
1093
- ),
1116
+ scale=alt.Scale(domain=y_column_list, range=resolved_colors),
1094
1117
  legend=_COLOR_LEGEND_SETTINGS,
1095
1118
  type="nominal",
1096
1119
  title=" ",
@@ -15,10 +15,16 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  from collections.abc import Callable, Collection
18
- from typing import Any, TypeAlias, cast
18
+ from typing import Any, Final, TypeAlias, cast
19
19
 
20
20
  from streamlit.errors import StreamlitInvalidColorError
21
21
 
22
+ # Built-in color names that map to Streamlit theme colors.
23
+ # These are resolved to actual color values on the frontend.
24
+ BUILTIN_COLOR_NAMES: Final[frozenset[str]] = frozenset(
25
+ {"red", "orange", "yellow", "green", "blue", "violet", "gray", "grey", "primary"}
26
+ )
27
+
22
28
  # components go from 0.0 to 1.0
23
29
  # Supported by Pillow and pretty common.
24
30
  FloatRGBColorTuple: TypeAlias = tuple[float, float, float]
@@ -131,11 +137,24 @@ def is_color_tuple_like(color: MaybeColor) -> bool:
131
137
  )
132
138
 
133
139
 
140
+ def is_builtin_color_name(color: MaybeColor) -> bool:
141
+ """Check whether the input is a built-in Streamlit color name.
142
+
143
+ Built-in color names (red, orange, yellow, green, blue, violet, gray/grey, primary)
144
+ are resolved to theme colors on the frontend.
145
+ """
146
+ return isinstance(color, str) and color.lower() in BUILTIN_COLOR_NAMES
147
+
148
+
134
149
  def is_color_like(color: MaybeColor) -> bool:
135
150
  """A fairly lightweight check of whether the input is a color.
136
151
 
137
152
  This isn't meant to be a definitive answer. The definitive solution is to
138
153
  try to convert and see if an error is thrown.
154
+
155
+ NOTE: This does NOT include built-in color names (red, blue, etc.) because
156
+ those require special handling and cannot be converted via to_css_color().
157
+ Use is_builtin_color_name() separately when validating color parameter arguments.
139
158
  """
140
159
  return is_css_color_like(color) or is_color_tuple_like(color)
141
160
 
@@ -245,7 +264,7 @@ def _float_formatter(component: float, color: MaybeColor) -> float:
245
264
  Anything too small will become 0.0, and anything too large will become 1.0.
246
265
  """
247
266
  if isinstance(component, int):
248
- component = component / 255.0
267
+ component /= 255.0
249
268
 
250
269
  if isinstance(component, float):
251
270
  return min(1.0, max(component, 0.0))
@@ -255,7 +255,9 @@ def _determine_data_kind_via_pandas_dtype(
255
255
  if pd.api.types.is_object_dtype(
256
256
  column_dtype
257
257
  ) is False and pd.api.types.is_string_dtype(column_dtype):
258
- # The is_string_dtype
258
+ # This handles pandas 3.0+ StringDtype (and PyArrow-backed string types).
259
+ # We exclude object dtype here because object columns with string values
260
+ # are handled via _determine_data_kind_via_inferred_type in the caller.
259
261
  return ColumnDataKind.STRING
260
262
 
261
263
  return ColumnDataKind.UNKNOWN
@@ -289,7 +291,7 @@ def _determine_data_kind_via_inferred_type(
289
291
  if inferred_type == "bytes":
290
292
  return ColumnDataKind.BYTES
291
293
 
292
- if inferred_type in ["floating", "mixed-integer-float"]:
294
+ if inferred_type in {"floating", "mixed-integer-float"}:
293
295
  return ColumnDataKind.FLOAT
294
296
 
295
297
  if inferred_type == "integer":
@@ -304,13 +306,13 @@ def _determine_data_kind_via_inferred_type(
304
306
  if inferred_type == "boolean":
305
307
  return ColumnDataKind.BOOLEAN
306
308
 
307
- if inferred_type in ["datetime64", "datetime"]:
309
+ if inferred_type in {"datetime64", "datetime"}:
308
310
  return ColumnDataKind.DATETIME
309
311
 
310
312
  if inferred_type == "date":
311
313
  return ColumnDataKind.DATE
312
314
 
313
- if inferred_type in ["timedelta64", "timedelta"]:
315
+ if inferred_type in {"timedelta64", "timedelta"}:
314
316
  return ColumnDataKind.TIMEDELTA
315
317
 
316
318
  if inferred_type == "time":
@@ -411,7 +413,7 @@ ColumnConfigMappingInput: TypeAlias = Mapping[
411
413
  # allowing int here leads mypy to complain about simple dict[str, ...]
412
414
  # as input -> which seems like a mypy bug.
413
415
  IndexIdentifierType | str,
414
- ColumnConfig | None | str,
416
+ ColumnConfig | str | None,
415
417
  ]
416
418
 
417
419
 
@@ -499,7 +501,7 @@ def apply_data_specific_configs(
499
501
  # Pandas adds a range index as default to all datastructures
500
502
  # but for most of the non-pandas data objects it is unnecessary
501
503
  # to show this index to the user. Therefore, we will hide it as default.
502
- if data_format in [
504
+ if data_format in {
503
505
  DataFormat.SET_OF_VALUES,
504
506
  DataFormat.TUPLE_OF_VALUES,
505
507
  DataFormat.LIST_OF_VALUES,
@@ -516,7 +518,7 @@ def apply_data_specific_configs(
516
518
  DataFormat.POLARS_LAZYFRAME,
517
519
  DataFormat.PYARROW_ARRAY,
518
520
  DataFormat.RAY_DATASET,
519
- ]:
521
+ }:
520
522
  update_column_config(columns_config, INDEX_IDENTIFIER, {"hidden": True})
521
523
 
522
524
 
@@ -91,7 +91,7 @@ class Dialog(DeltaGenerator):
91
91
  on_dismiss: Literal["ignore", "rerun"] | WidgetCallback = "ignore",
92
92
  ) -> Dialog:
93
93
  # Validation for on_dismiss parameter
94
- if on_dismiss not in ["ignore", "rerun"] and not callable(on_dismiss):
94
+ if on_dismiss not in {"ignore", "rerun"} and not callable(on_dismiss):
95
95
  raise StreamlitAPIException(
96
96
  f"You have passed {on_dismiss} to `on_dismiss`. But only 'ignore', "
97
97
  "'rerun', or a callable is supported."
@@ -80,7 +80,7 @@ its column width"""
80
80
 
81
81
 
82
82
  def _image_may_have_alpha_channel(image: PILImage) -> bool:
83
- return image.mode in ("RGBA", "LA", "P")
83
+ return image.mode in {"RGBA", "LA", "P"}
84
84
 
85
85
 
86
86
  def _image_is_gif(image: PILImage) -> bool:
@@ -155,9 +155,9 @@ def _np_array_to_bytes(array: npt.NDArray[Any], output_format: str = "JPEG") ->
155
155
 
156
156
  def _verify_np_shape(array: npt.NDArray[Any]) -> npt.NDArray[Any]:
157
157
  shape: NumpyShape = array.shape
158
- if len(shape) not in (2, 3):
158
+ if len(shape) not in {2, 3}:
159
159
  raise StreamlitAPIException("Numpy shape has to be of length 2 or 3.")
160
- if len(shape) == 3 and shape[-1] not in (1, 3, 4):
160
+ if len(shape) == 3 and shape[-1] not in {1, 3, 4}:
161
161
  raise StreamlitAPIException(
162
162
  f"Channel can only be 1, 3, or 4 got {shape[-1]}. Shape is {shape}"
163
163
  )
@@ -224,7 +224,7 @@ def _clip_image(image: npt.NDArray[Any], clamp: bool) -> npt.NDArray[Any]:
224
224
  data = np.clip(image, 0, 1.0)
225
225
  elif np.amin(image) < 0.0 or np.amax(image) > 1.0:
226
226
  raise RuntimeError("Data is outside [0.0, 1.0] and clamp is not set.")
227
- data = data * 255
227
+ data = data * 255 # noqa: PLR6104
228
228
  elif clamp:
229
229
  data = np.clip(image, 0, 255)
230
230
  elif np.amin(image) < 0 or np.amax(image) > 255:
@@ -265,7 +265,7 @@ def image_to_url(
265
265
 
266
266
  if image.endswith(".svg") and os.path.isfile(image):
267
267
  # Unpack local SVG image file to an SVG string
268
- with open(image) as textfile:
268
+ with open(image, encoding="utf-8") as textfile:
269
269
  image = textfile.read()
270
270
 
271
271
  # Following regex allows svg image files to start either via a "<?xml...>" tag
@@ -273,7 +273,7 @@ def get_justify(
273
273
  justify = map_to_flex_terminology[alignment]
274
274
  if justify not in valid_justify:
275
275
  return Block.FlexContainer.Justify.JUSTIFY_UNDEFINED
276
- if justify in ["start", "end", "center"]:
276
+ if justify in {"start", "end", "center"}:
277
277
  return cast(
278
278
  "Block.FlexContainer.Justify.ValueType",
279
279
  getattr(Block.FlexContainer.Justify, f"JUSTIFY_{justify.upper()}"),