streamlit 1.45.1__py3-none-any.whl → 1.46.1__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.
- streamlit/__init__.py +5 -1
- streamlit/auth_util.py +12 -12
- streamlit/cli_util.py +4 -3
- streamlit/column_config.py +11 -9
- streamlit/commands/echo.py +6 -4
- streamlit/commands/execution_control.py +33 -32
- streamlit/commands/experimental_query_params.py +2 -2
- streamlit/commands/logo.py +9 -4
- streamlit/commands/navigation.py +61 -18
- streamlit/commands/page_config.py +57 -47
- streamlit/components/types/base_custom_component.py +7 -7
- streamlit/components/v1/component_registry.py +7 -3
- streamlit/components/v1/components.py +1 -1
- streamlit/components/v1/custom_component.py +8 -8
- streamlit/config.py +289 -144
- streamlit/config_option.py +19 -15
- streamlit/config_util.py +29 -23
- streamlit/connections/__init__.py +2 -2
- streamlit/connections/base_connection.py +5 -5
- streamlit/connections/snowflake_connection.py +13 -11
- streamlit/connections/snowpark_connection.py +3 -3
- streamlit/connections/sql_connection.py +20 -18
- streamlit/connections/util.py +2 -2
- streamlit/cursor.py +6 -6
- streamlit/dataframe_util.py +52 -52
- streamlit/delta_generator.py +46 -48
- streamlit/delta_generator_singletons.py +3 -3
- streamlit/deprecation_util.py +6 -6
- streamlit/elements/alert.py +37 -29
- streamlit/elements/arrow.py +40 -22
- streamlit/elements/code.py +46 -13
- streamlit/elements/deck_gl_json_chart.py +38 -27
- streamlit/elements/dialog_decorator.py +3 -4
- streamlit/elements/doc_string.py +64 -58
- streamlit/elements/exception.py +23 -27
- streamlit/elements/form.py +41 -0
- streamlit/elements/graphviz_chart.py +1 -1
- streamlit/elements/heading.py +60 -9
- streamlit/elements/html.py +3 -4
- streamlit/elements/image.py +8 -9
- streamlit/elements/json.py +21 -2
- streamlit/elements/layouts.py +120 -31
- streamlit/elements/lib/built_in_chart_utils.py +96 -73
- streamlit/elements/lib/color_util.py +3 -3
- streamlit/elements/lib/column_config_utils.py +2 -4
- streamlit/elements/lib/column_types.py +14 -8
- streamlit/elements/lib/dialog.py +9 -5
- streamlit/elements/lib/image_utils.py +39 -40
- streamlit/elements/lib/js_number.py +4 -4
- streamlit/elements/lib/layout_utils.py +65 -1
- streamlit/elements/lib/mutable_status_container.py +14 -3
- streamlit/elements/lib/options_selector_utils.py +22 -12
- streamlit/elements/lib/pandas_styler_utils.py +25 -21
- streamlit/elements/lib/policies.py +6 -5
- streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
- streamlit/elements/lib/subtitle_utils.py +6 -9
- streamlit/elements/lib/utils.py +20 -5
- streamlit/elements/map.py +32 -56
- streamlit/elements/markdown.py +101 -12
- streamlit/elements/media.py +78 -21
- streamlit/elements/metric.py +32 -16
- streamlit/elements/plotly_chart.py +15 -15
- streamlit/elements/progress.py +33 -15
- streamlit/elements/spinner.py +31 -6
- streamlit/elements/text.py +21 -1
- streamlit/elements/toast.py +1 -2
- streamlit/elements/vega_charts.py +54 -23
- streamlit/elements/widgets/audio_input.py +24 -7
- streamlit/elements/widgets/button.py +26 -19
- streamlit/elements/widgets/button_group.py +10 -15
- streamlit/elements/widgets/camera_input.py +27 -7
- streamlit/elements/widgets/chat.py +91 -38
- streamlit/elements/widgets/checkbox.py +45 -4
- streamlit/elements/widgets/color_picker.py +40 -17
- streamlit/elements/widgets/data_editor.py +76 -37
- streamlit/elements/widgets/file_uploader.py +42 -13
- streamlit/elements/widgets/multiselect.py +7 -10
- streamlit/elements/widgets/number_input.py +123 -47
- streamlit/elements/widgets/radio.py +59 -13
- streamlit/elements/widgets/select_slider.py +35 -30
- streamlit/elements/widgets/selectbox.py +56 -9
- streamlit/elements/widgets/slider.py +190 -99
- streamlit/elements/widgets/text_widgets.py +54 -8
- streamlit/elements/widgets/time_widgets.py +53 -14
- streamlit/elements/write.py +5 -8
- streamlit/env_util.py +2 -7
- streamlit/error_util.py +16 -9
- streamlit/errors.py +69 -48
- streamlit/external/langchain/streamlit_callback_handler.py +10 -5
- streamlit/file_util.py +27 -10
- streamlit/git_util.py +29 -24
- streamlit/hello/animation_demo.py +9 -9
- streamlit/hello/dataframe_demo.py +5 -5
- streamlit/hello/hello.py +1 -0
- streamlit/hello/mapping_demo.py +7 -8
- streamlit/hello/plotting_demo.py +3 -3
- streamlit/hello/streamlit_app.py +28 -26
- streamlit/hello/utils.py +2 -1
- streamlit/logger.py +10 -11
- streamlit/navigation/page.py +11 -8
- streamlit/proto/Audio_pb2.py +4 -3
- streamlit/proto/Audio_pb2.pyi +8 -1
- streamlit/proto/Block_pb2.py +38 -29
- streamlit/proto/Block_pb2.pyi +72 -4
- streamlit/proto/ClientState_pb2.py +4 -4
- streamlit/proto/ClientState_pb2.pyi +7 -2
- streamlit/proto/Code_pb2.py +4 -2
- streamlit/proto/Code_pb2.pyi +1 -0
- streamlit/proto/DataFrame_pb2.pyi +1 -1
- streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
- streamlit/proto/Element_pb2.py +5 -3
- streamlit/proto/Element_pb2.pyi +20 -3
- streamlit/proto/GapSize_pb2.py +29 -0
- streamlit/proto/GapSize_pb2.pyi +70 -0
- streamlit/proto/HeightConfig_pb2.py +27 -0
- streamlit/proto/HeightConfig_pb2.pyi +48 -0
- streamlit/proto/NamedDataSet_pb2.pyi +1 -1
- streamlit/proto/Navigation_pb2.py +3 -3
- streamlit/proto/Navigation_pb2.pyi +4 -0
- streamlit/proto/NewSession_pb2.py +18 -16
- streamlit/proto/NewSession_pb2.pyi +29 -3
- streamlit/proto/PageConfig_pb2.py +7 -7
- streamlit/proto/PageConfig_pb2.pyi +21 -1
- streamlit/proto/Video_pb2.py +8 -7
- streamlit/proto/Video_pb2.pyi +8 -1
- streamlit/proto/WidthConfig_pb2.py +2 -2
- streamlit/proto/WidthConfig_pb2.pyi +15 -1
- streamlit/runtime/__init__.py +1 -1
- streamlit/runtime/app_session.py +53 -40
- streamlit/runtime/caching/__init__.py +9 -9
- streamlit/runtime/caching/cache_data_api.py +36 -30
- streamlit/runtime/caching/cache_errors.py +4 -4
- streamlit/runtime/caching/cache_resource_api.py +8 -8
- streamlit/runtime/caching/cache_utils.py +15 -14
- streamlit/runtime/caching/cached_message_replay.py +14 -8
- streamlit/runtime/caching/hashing.py +91 -97
- streamlit/runtime/caching/legacy_cache_api.py +2 -2
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
- streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
- streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
- streamlit/runtime/connection_factory.py +36 -36
- streamlit/runtime/context.py +58 -9
- streamlit/runtime/credentials.py +29 -40
- streamlit/runtime/forward_msg_queue.py +11 -11
- streamlit/runtime/fragment.py +7 -7
- streamlit/runtime/media_file_manager.py +3 -4
- streamlit/runtime/memory_media_file_storage.py +6 -5
- streamlit/runtime/memory_uploaded_file_manager.py +2 -2
- streamlit/runtime/metrics_util.py +11 -12
- streamlit/runtime/pages_manager.py +4 -6
- streamlit/runtime/runtime.py +8 -6
- streamlit/runtime/runtime_util.py +7 -6
- streamlit/runtime/scriptrunner/__init__.py +4 -4
- streamlit/runtime/scriptrunner/exec_code.py +12 -5
- streamlit/runtime/scriptrunner/magic.py +16 -12
- streamlit/runtime/scriptrunner/script_cache.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +53 -29
- streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
- streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
- streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
- streamlit/runtime/secrets.py +40 -35
- streamlit/runtime/session_manager.py +2 -1
- streamlit/runtime/state/__init__.py +5 -5
- streamlit/runtime/state/common.py +2 -2
- streamlit/runtime/state/query_params.py +13 -15
- streamlit/runtime/state/query_params_proxy.py +17 -13
- streamlit/runtime/state/safe_session_state.py +2 -2
- streamlit/runtime/state/session_state.py +52 -34
- streamlit/runtime/stats.py +2 -2
- streamlit/runtime/uploaded_file_manager.py +1 -1
- streamlit/runtime/websocket_session_manager.py +10 -6
- streamlit/source_util.py +8 -6
- streamlit/static/index.html +3 -17
- streamlit/static/manifest.json +1180 -0
- streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.DU9IrB3M.js → ErrorOutline.esm.DitPpe1Y.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.AI3watX9.js} +1 -1
- streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.kt7mhnu8.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.D1M9GM_c.js} +1 -1
- streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.BGwHKeUc.js} +1 -1
- streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.DaZ89mzH.js} +1 -1
- streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.C0zPMe-p.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.Ox8gQvdz.js} +1 -1
- streamlit/static/static/js/Toolbar.KhlcEc0K.js +1 -0
- streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
- streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.BJ4qsfSq.js} +4 -4
- streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.DSDh78Xz.js} +2 -2
- streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.wQ9SIXEJ.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.DvbdPJ15.js} +1 -1
- streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CD9rzih5.js} +1 -1
- streamlit/static/static/js/{es6.CxQz807-.js → es6.48Q9Qjgb.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.CKdem3Bn.js} +1 -1
- streamlit/static/static/js/{index.LaIasviC.js → index.6md5Qhod.js} +1 -1
- streamlit/static/static/js/index.7hy6AeJ1.js +1 -0
- streamlit/static/static/js/index.B4CGJiBW.js +1 -0
- streamlit/static/static/js/index.B8oW0ZTD.js +1 -0
- streamlit/static/static/js/index.BU6RnlHI.js +73 -0
- streamlit/static/static/js/index.BUq9Wcf8.js +197 -0
- streamlit/static/static/js/{index.BFz9U2y0.js → index.BXXo-Yoj.js} +1 -1
- streamlit/static/static/js/index.Bae9H0OS.js +1 -0
- streamlit/static/static/js/{index.-5ruC9At.js → index.BhTl2Uyb.js} +1 -1
- streamlit/static/static/js/{index.BpILzHf_.js → index.BiSaCB1o.js} +20 -20
- streamlit/static/static/js/{index.xNQq3Ei5.js → index.BulSAJ9z.js} +1 -1
- streamlit/static/static/js/{index.9V1KdxfP.js → index.Bv-EuTKR.js} +1 -1
- streamlit/static/static/js/index.BvMLYCHi.js +1 -0
- streamlit/static/static/js/index.C1NIn1Y2.js +783 -0
- streamlit/static/static/js/index.CP-fthOJ.js +2 -0
- streamlit/static/static/js/{index.BoigZiu7.js → index.CS9guO3p.js} +1 -1
- streamlit/static/static/js/index.CYTBHth8.js +1 -0
- streamlit/static/static/js/{index.CmTAF0dM.js → index.CcJufcuD.js} +1 -1
- streamlit/static/static/js/index.CnENU1yn.js +1 -0
- streamlit/static/static/js/index.Cns13qBb.js +1 -0
- streamlit/static/static/js/index.Ct_xXq7w.js +1 -0
- streamlit/static/static/js/{index.BqfdT8-Q.js → index.CxGSemHL.js} +1 -1
- streamlit/static/static/js/index.D5S0ldVb.js +1 -0
- streamlit/static/static/js/index.D72B_ksb.js +2 -0
- streamlit/static/static/js/index.DI4yZ27M.js +1 -0
- streamlit/static/static/js/index.DN51vLxR.js +1 -0
- streamlit/static/static/js/index.DRtq5dka.js +1 -0
- streamlit/static/static/js/{index.BHXxWdde.js → index.DX-oiXlb.js} +1 -1
- streamlit/static/static/js/index.DlFE4_Aq.js +12 -0
- streamlit/static/static/js/{index.BHGGDa8K.js → index.J7BJwXOi.js} +2 -2
- streamlit/static/static/js/index.Jg38kJPP.js +1 -0
- streamlit/static/static/js/index.JhIO6abf.js +3 -0
- streamlit/static/static/js/{index.DeB9iKFW.js → index.NkRcWwc5.js} +255 -255
- streamlit/static/static/js/{index.BGga-hcS.js → index.prekPLrm.js} +25 -25
- streamlit/static/static/js/{index.BRXmLIsC.js → index.wyzngKUE.js} +1 -1
- streamlit/static/static/js/index.xW7mVdI8.js +1 -0
- streamlit/static/static/js/index.yk07dYGx.js +1 -0
- streamlit/static/static/js/{input.DsCfafm0.js → input.CxKZ5Wrc.js} +2 -2
- streamlit/static/static/js/{memory.nY_lMTtu.js → memory.DeZ9VUvl.js} +1 -1
- streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.CVkhrWUb.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Bpkm3nTq.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CIDCId52.js} +1 -1
- streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.TrkMaokR.js} +1 -1
- streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.QKjxR64N.js} +2 -2
- streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.DJYmE1dK.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.BZoworE-.js} +1 -1
- streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.O0UbJ2Bu.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Ci89jaH5.js} +1 -1
- streamlit/static/static/js/useOnInputChange.Cxh6ExEn.js +1 -0
- streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.iW37lS8Z.js} +1 -1
- streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
- streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
- streamlit/string_util.py +14 -19
- streamlit/temporary_directory.py +13 -4
- streamlit/testing/v1/app_test.py +15 -10
- streamlit/testing/v1/element_tree.py +157 -178
- streamlit/testing/v1/local_script_runner.py +11 -15
- streamlit/testing/v1/util.py +11 -4
- streamlit/type_util.py +8 -12
- streamlit/url_util.py +1 -1
- streamlit/user_info.py +6 -5
- streamlit/util.py +25 -1
- streamlit/vendor/pympler/asizeof.py +3 -2
- streamlit/watcher/event_based_path_watcher.py +21 -2
- streamlit/watcher/folder_black_list.py +2 -2
- streamlit/watcher/local_sources_watcher.py +64 -18
- streamlit/watcher/path_watcher.py +6 -10
- streamlit/watcher/polling_path_watcher.py +8 -7
- streamlit/watcher/util.py +7 -6
- streamlit/web/bootstrap.py +16 -14
- streamlit/web/cli.py +52 -45
- streamlit/web/server/__init__.py +7 -3
- streamlit/web/server/app_static_file_handler.py +1 -1
- streamlit/web/server/authlib_tornado_integration.py +9 -4
- streamlit/web/server/browser_websocket_handler.py +8 -2
- streamlit/web/server/component_request_handler.py +14 -10
- streamlit/web/server/media_file_handler.py +14 -7
- streamlit/web/server/oauth_authlib_routes.py +41 -9
- streamlit/web/server/oidc_mixin.py +35 -17
- streamlit/web/server/routes.py +32 -22
- streamlit/web/server/server.py +13 -24
- streamlit/web/server/server_util.py +43 -9
- streamlit/web/server/stats_request_handler.py +7 -5
- streamlit/web/server/upload_file_request_handler.py +22 -19
- streamlit/web/server/websocket_headers.py +1 -1
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/METADATA +4 -4
- streamlit-1.46.1.dist-info/RECORD +559 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/WHEEL +1 -1
- streamlit/elements/lib/event_utils.py +0 -39
- streamlit/static/static/js/Toolbar.D9RUZv9G.js +0 -1
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
- streamlit/static/static/js/index.8jhZBWF2.js +0 -3
- streamlit/static/static/js/index.BCx3C6e_.js +0 -1
- streamlit/static/static/js/index.BRuTz_S4.js +0 -1
- streamlit/static/static/js/index.Bcru_ti-.js +0 -1
- streamlit/static/static/js/index.Bl1FMJRd.js +0 -1
- streamlit/static/static/js/index.C1z8KpLA.js +0 -779
- streamlit/static/static/js/index.C32I2PUe.js +0 -2
- streamlit/static/static/js/index.C5GnDRB7.js +0 -1
- streamlit/static/static/js/index.CG4qPaaW.js +0 -2
- streamlit/static/static/js/index.C_msmT1u.js +0 -1
- streamlit/static/static/js/index.CbeNTdd6.js +0 -1
- streamlit/static/static/js/index.CnGQVJcw.js +0 -12
- streamlit/static/static/js/index.CopVVq4l.js +0 -1
- streamlit/static/static/js/index.CtXupx4d.js +0 -197
- streamlit/static/static/js/index.DGmCchO7.js +0 -1
- streamlit/static/static/js/index.DH6zBk0e.js +0 -1
- streamlit/static/static/js/index.DHVlVWsm.js +0 -1
- streamlit/static/static/js/index.DRKIVBoi.js +0 -1
- streamlit/static/static/js/index.DUd-lFXx.js +0 -73
- streamlit/static/static/js/index.D_uRBA4B.js +0 -1
- streamlit/static/static/js/index.QHNfgPJd.js +0 -1
- streamlit/static/static/js/index.a-RJocYL.js +0 -1
- streamlit/static/static/js/index.cvz4B1gy.js +0 -1
- streamlit/static/static/js/index.t--hEgTQ.js +0 -6
- streamlit/static/static/js/useOnInputChange.z04u96A8.js +0 -1
- streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
- streamlit-1.45.1.dist-info/RECORD +0 -568
- {streamlit-1.45.1.data → streamlit-1.46.1.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/entry_points.txt +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/top_level.txt +0 -0
streamlit/config_option.py
CHANGED
|
@@ -108,7 +108,8 @@ class ConfigOption:
|
|
|
108
108
|
replaced_by: str | None = None,
|
|
109
109
|
type_: type = str,
|
|
110
110
|
sensitive: bool = False,
|
|
111
|
-
|
|
111
|
+
multiple: bool = False,
|
|
112
|
+
) -> None:
|
|
112
113
|
"""Create a ConfigOption with the given name.
|
|
113
114
|
|
|
114
115
|
Parameters
|
|
@@ -142,6 +143,8 @@ class ConfigOption:
|
|
|
142
143
|
Useful to cast the config params sent by cmd option parameter.
|
|
143
144
|
sensitive: bool
|
|
144
145
|
Sensitive configuration options cannot be set by CLI parameter.
|
|
146
|
+
multiple: bool
|
|
147
|
+
Whether this config option can have multiple values.
|
|
145
148
|
"""
|
|
146
149
|
# Parse out the section and name.
|
|
147
150
|
self.key = key
|
|
@@ -167,7 +170,8 @@ class ConfigOption:
|
|
|
167
170
|
r")$"
|
|
168
171
|
)
|
|
169
172
|
match = re.match(key_format, self.key)
|
|
170
|
-
|
|
173
|
+
if match is None:
|
|
174
|
+
raise ValueError(f'Key "{self.key}" has invalid format.')
|
|
171
175
|
self.section, self.name = match.group("section"), match.group("name")
|
|
172
176
|
|
|
173
177
|
self.description = description
|
|
@@ -182,17 +186,18 @@ class ConfigOption:
|
|
|
182
186
|
self.where_defined = ConfigOption.DEFAULT_DEFINITION
|
|
183
187
|
self.type = type_
|
|
184
188
|
self.sensitive = sensitive
|
|
185
|
-
|
|
186
|
-
self.multiple = isinstance(default_val, (list, tuple))
|
|
189
|
+
self.multiple = multiple
|
|
187
190
|
|
|
188
191
|
if self.replaced_by:
|
|
189
192
|
self.deprecated = True
|
|
190
193
|
if deprecation_text is None:
|
|
191
|
-
deprecation_text = "Replaced by
|
|
194
|
+
deprecation_text = f"Replaced by {self.replaced_by}."
|
|
192
195
|
|
|
193
196
|
if self.deprecated:
|
|
194
|
-
|
|
195
|
-
|
|
197
|
+
if not expiration_date:
|
|
198
|
+
raise ValueError("expiration_date is required for deprecated items.")
|
|
199
|
+
if not deprecation_text:
|
|
200
|
+
raise ValueError("deprecation_text is required for deprecated items.")
|
|
196
201
|
self.expiration_date = expiration_date
|
|
197
202
|
self.deprecation_text = textwrap.dedent(deprecation_text)
|
|
198
203
|
|
|
@@ -218,9 +223,10 @@ class ConfigOption:
|
|
|
218
223
|
Returns self, which makes testing easier. See config_test.py.
|
|
219
224
|
|
|
220
225
|
"""
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
226
|
+
if get_val_func.__doc__ is None:
|
|
227
|
+
raise RuntimeError(
|
|
228
|
+
"Complex config options require doc strings for their description."
|
|
229
|
+
)
|
|
224
230
|
self.description = get_val_func.__doc__
|
|
225
231
|
self._get_val_func = get_val_func
|
|
226
232
|
return self
|
|
@@ -257,8 +263,7 @@ class ConfigOption:
|
|
|
257
263
|
# Import here to avoid circular imports
|
|
258
264
|
from streamlit.logger import get_logger
|
|
259
265
|
|
|
260
|
-
|
|
261
|
-
LOGGER.error(
|
|
266
|
+
get_logger(__name__).error(
|
|
262
267
|
textwrap.dedent(
|
|
263
268
|
f"""
|
|
264
269
|
════════════════════════════════════════════════
|
|
@@ -275,8 +280,7 @@ class ConfigOption:
|
|
|
275
280
|
# Import here to avoid circular imports
|
|
276
281
|
from streamlit.logger import get_logger
|
|
277
282
|
|
|
278
|
-
|
|
279
|
-
LOGGER.warning(
|
|
283
|
+
get_logger(__name__).warning(
|
|
280
284
|
textwrap.dedent(
|
|
281
285
|
f"""s
|
|
282
286
|
════════════════════════════════════════════════
|
|
@@ -301,7 +305,7 @@ class ConfigOption:
|
|
|
301
305
|
return now > expiration_date
|
|
302
306
|
|
|
303
307
|
@property
|
|
304
|
-
def env_var(self):
|
|
308
|
+
def env_var(self) -> str:
|
|
305
309
|
"""Get the name of the environment variable that can be used to set the option."""
|
|
306
310
|
name = self.key.replace(".", "_")
|
|
307
311
|
return f"STREAMLIT_{to_snake_case(name).upper()}"
|
streamlit/config_util.py
CHANGED
|
@@ -54,19 +54,19 @@ 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
|
-
for section
|
|
69
|
+
for section in section_descriptions:
|
|
70
70
|
# We inject a fake config section used for unit tests that we exclude here as
|
|
71
71
|
# its options are often missing required properties, which confuses the code
|
|
72
72
|
# below.
|
|
@@ -84,10 +84,10 @@ def show_config(
|
|
|
84
84
|
continue
|
|
85
85
|
|
|
86
86
|
out.append("")
|
|
87
|
-
append_section("[
|
|
87
|
+
append_section(f"[{section}]")
|
|
88
88
|
out.append("")
|
|
89
89
|
|
|
90
|
-
for
|
|
90
|
+
for option in section_options.values():
|
|
91
91
|
key = option.key.split(".")[-1]
|
|
92
92
|
description_paragraphs = _clean_paragraphs(option.description or "")
|
|
93
93
|
|
|
@@ -112,7 +112,21 @@ def show_config(
|
|
|
112
112
|
|
|
113
113
|
# # Add a line break after a paragraph only if it's not the last paragraph
|
|
114
114
|
if i != last_paragraph_idx:
|
|
115
|
-
|
|
115
|
+
append_comment("")
|
|
116
|
+
|
|
117
|
+
if option.deprecated:
|
|
118
|
+
if out[-1] != "#":
|
|
119
|
+
append_comment("")
|
|
120
|
+
append_comment(
|
|
121
|
+
cli_util.style_for_cli("THIS IS DEPRECATED.", fg="yellow")
|
|
122
|
+
)
|
|
123
|
+
append_comment("")
|
|
124
|
+
for line in _clean_paragraphs(option.deprecation_text):
|
|
125
|
+
append_comment(line)
|
|
126
|
+
append_comment("")
|
|
127
|
+
append_comment(
|
|
128
|
+
f"This option will be removed on or after {option.expiration_date}."
|
|
129
|
+
)
|
|
116
130
|
|
|
117
131
|
import toml
|
|
118
132
|
|
|
@@ -121,29 +135,22 @@ def show_config(
|
|
|
121
135
|
|
|
122
136
|
if len(toml_default) > 0:
|
|
123
137
|
# Ensure a line break before appending "Default" comment, if not already there
|
|
124
|
-
if out[-1] != "":
|
|
125
|
-
|
|
126
|
-
append_comment("Default:
|
|
138
|
+
if out[-1] != "#":
|
|
139
|
+
append_comment("")
|
|
140
|
+
append_comment(f"Default: {toml_default}")
|
|
127
141
|
else:
|
|
128
142
|
# Don't say "Default: (unset)" here because this branch applies
|
|
129
143
|
# to complex config settings too.
|
|
130
144
|
pass
|
|
131
145
|
|
|
132
|
-
if option.deprecated:
|
|
133
|
-
append_comment(cli_util.style_for_cli("DEPRECATED.", fg="yellow"))
|
|
134
|
-
for line in _clean_paragraphs(option.deprecation_text):
|
|
135
|
-
append_comment(line)
|
|
136
|
-
append_comment(
|
|
137
|
-
"This option will be removed on or after %s."
|
|
138
|
-
% option.expiration_date
|
|
139
|
-
)
|
|
140
|
-
|
|
141
146
|
option_is_manually_set = (
|
|
142
147
|
option.where_defined != ConfigOption.DEFAULT_DEFINITION
|
|
143
148
|
)
|
|
144
149
|
|
|
145
150
|
if option_is_manually_set:
|
|
146
|
-
|
|
151
|
+
if out[-1] != "# ":
|
|
152
|
+
append_comment("")
|
|
153
|
+
append_comment(f"The value below was set in {option.where_defined}")
|
|
147
154
|
|
|
148
155
|
toml_setting = toml.dumps({key: option.value})
|
|
149
156
|
|
|
@@ -170,8 +177,7 @@ def _clean_paragraphs(txt: str) -> list[str]:
|
|
|
170
177
|
# Strip both leading and trailing newlines.
|
|
171
178
|
txt = txt.strip("\n")
|
|
172
179
|
paragraphs = txt.split("\n\n")
|
|
173
|
-
|
|
180
|
+
return [
|
|
174
181
|
"\n".join(_clean(line) for line in paragraph.split("\n"))
|
|
175
182
|
for paragraph in paragraphs
|
|
176
183
|
]
|
|
177
|
-
return cleaned_paragraphs
|
|
@@ -43,7 +43,7 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
|
43
43
|
reads and a ``session`` property for more complex operations.
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
|
-
def __init__(self, connection_name: str, **kwargs) -> None:
|
|
46
|
+
def __init__(self, connection_name: str, **kwargs: Any) -> None:
|
|
47
47
|
"""Create a BaseConnection.
|
|
48
48
|
|
|
49
49
|
This constructor is called by the connection factory machinery when a user
|
|
@@ -78,16 +78,16 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
|
78
78
|
def __getattribute__(self, name: str) -> Any:
|
|
79
79
|
try:
|
|
80
80
|
return object.__getattribute__(self, name)
|
|
81
|
-
except AttributeError
|
|
81
|
+
except AttributeError:
|
|
82
82
|
if hasattr(self._instance, name):
|
|
83
83
|
raise AttributeError(
|
|
84
84
|
f"`{name}` doesn't exist here, but you can call `._instance.{name}` instead"
|
|
85
85
|
)
|
|
86
|
-
raise
|
|
86
|
+
raise
|
|
87
87
|
|
|
88
88
|
# Methods with default implementations that we don't expect subclasses to want or
|
|
89
89
|
# need to overwrite.
|
|
90
|
-
def _on_secrets_changed(self, _) -> None:
|
|
90
|
+
def _on_secrets_changed(self, _: str) -> None:
|
|
91
91
|
"""Reset the raw connection object when this connection's secrets change.
|
|
92
92
|
|
|
93
93
|
We don't expect either user scripts or connection authors to have to use or
|
|
@@ -155,7 +155,7 @@ class BaseConnection(ABC, Generic[RawConnectionT]):
|
|
|
155
155
|
|
|
156
156
|
# Abstract fields/methods that subclasses of BaseConnection must implement
|
|
157
157
|
@abstractmethod
|
|
158
|
-
def _connect(self, **kwargs) -> RawConnectionT:
|
|
158
|
+
def _connect(self, **kwargs: Any) -> RawConnectionT:
|
|
159
159
|
"""Create an instance of an underlying connection object.
|
|
160
160
|
|
|
161
161
|
This abstract method is the one method that we require subclasses of
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
-
from typing import TYPE_CHECKING, Final, cast
|
|
23
|
+
from typing import TYPE_CHECKING, Any, Final, cast
|
|
24
24
|
|
|
25
25
|
from streamlit import logger
|
|
26
26
|
from streamlit.connections import BaseConnection
|
|
@@ -41,6 +41,10 @@ if TYPE_CHECKING:
|
|
|
41
41
|
SnowflakeConnection as InternalSnowflakeConnection,
|
|
42
42
|
)
|
|
43
43
|
|
|
44
|
+
# the ANSI-compliant SQL code for "connection was not established"
|
|
45
|
+
# (see docs: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#id6)
|
|
46
|
+
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED: Final = "08001"
|
|
47
|
+
|
|
44
48
|
|
|
45
49
|
class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
46
50
|
"""A connection to Snowflake using the Snowflake Connector for Python.
|
|
@@ -218,7 +222,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
218
222
|
|
|
219
223
|
"""
|
|
220
224
|
|
|
221
|
-
def _connect(self, **kwargs) -> InternalSnowflakeConnection:
|
|
225
|
+
def _connect(self, **kwargs: Any) -> InternalSnowflakeConnection:
|
|
222
226
|
import snowflake.connector # type:ignore[import]
|
|
223
227
|
from snowflake.connector import Error as SnowflakeError # type:ignore[import]
|
|
224
228
|
|
|
@@ -263,16 +267,17 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
263
267
|
return snowflake.connector.connect()
|
|
264
268
|
|
|
265
269
|
return snowflake.connector.connect(**kwargs)
|
|
266
|
-
except SnowflakeError
|
|
270
|
+
except SnowflakeError:
|
|
267
271
|
if not len(st_secrets) and not kwargs:
|
|
268
272
|
raise StreamlitAPIException(
|
|
269
273
|
"Missing Snowflake connection configuration. "
|
|
270
274
|
"Did you forget to set this in `secrets.toml`, a Snowflake configuration file, "
|
|
271
275
|
"or as kwargs to `st.connection`? "
|
|
272
|
-
"See the [SnowflakeConnection configuration documentation]
|
|
276
|
+
"See the [SnowflakeConnection configuration documentation]"
|
|
277
|
+
"(https://docs.streamlit.io/st.connections.snowflakeconnection-configuration) "
|
|
273
278
|
"for more details and examples."
|
|
274
279
|
)
|
|
275
|
-
raise
|
|
280
|
+
raise
|
|
276
281
|
|
|
277
282
|
def query(
|
|
278
283
|
self,
|
|
@@ -280,8 +285,8 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
280
285
|
*, # keyword-only arguments:
|
|
281
286
|
ttl: float | int | timedelta | None = None,
|
|
282
287
|
show_spinner: bool | str = "Running `snowflake.query(...)`.",
|
|
283
|
-
params=None,
|
|
284
|
-
**kwargs,
|
|
288
|
+
params: Any = None,
|
|
289
|
+
**kwargs: Any,
|
|
285
290
|
) -> DataFrame:
|
|
286
291
|
"""Run a read-only SQL query.
|
|
287
292
|
|
|
@@ -334,9 +339,6 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
334
339
|
"""
|
|
335
340
|
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_fixed
|
|
336
341
|
|
|
337
|
-
# the ANSI-compliant SQL code for "connection was not established" (see docs: https://docs.snowflake.com/en/developer-guide/python-connector/python-connector-api#id6)
|
|
338
|
-
SQLSTATE_CONNECTION_WAS_NOT_ESTABLISHED = "08001"
|
|
339
|
-
|
|
340
342
|
@retry(
|
|
341
343
|
after=lambda _: self.reset(),
|
|
342
344
|
stop=stop_after_attempt(3),
|
|
@@ -377,7 +379,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
|
377
379
|
database: str | None = None,
|
|
378
380
|
schema: str | None = None,
|
|
379
381
|
chunk_size: int | None = None,
|
|
380
|
-
**kwargs,
|
|
382
|
+
**kwargs: Any,
|
|
381
383
|
) -> tuple[bool, int, int]:
|
|
382
384
|
"""Write a ``pandas.DataFrame`` to a table in a Snowflake database.
|
|
383
385
|
|
|
@@ -23,7 +23,7 @@ from __future__ import annotations
|
|
|
23
23
|
import threading
|
|
24
24
|
from collections import ChainMap
|
|
25
25
|
from contextlib import contextmanager
|
|
26
|
-
from typing import TYPE_CHECKING, cast
|
|
26
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
27
27
|
|
|
28
28
|
from streamlit.connections import BaseConnection
|
|
29
29
|
from streamlit.connections.util import (
|
|
@@ -61,11 +61,11 @@ class SnowparkConnection(BaseConnection["Session"]):
|
|
|
61
61
|
over the single underlying Session object under high load.
|
|
62
62
|
"""
|
|
63
63
|
|
|
64
|
-
def __init__(self, connection_name: str, **kwargs) -> None:
|
|
64
|
+
def __init__(self, connection_name: str, **kwargs: Any) -> None:
|
|
65
65
|
self._lock = threading.RLock()
|
|
66
66
|
super().__init__(connection_name, **kwargs)
|
|
67
67
|
|
|
68
|
-
def _connect(self, **kwargs) -> Session:
|
|
68
|
+
def _connect(self, **kwargs: Any) -> Session:
|
|
69
69
|
from snowflake.snowpark.context import get_active_session # type:ignore[import]
|
|
70
70
|
from snowflake.snowpark.session import Session
|
|
71
71
|
|
|
@@ -21,7 +21,7 @@ from __future__ import annotations
|
|
|
21
21
|
|
|
22
22
|
from collections import ChainMap
|
|
23
23
|
from copy import deepcopy
|
|
24
|
-
from typing import TYPE_CHECKING, cast
|
|
24
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
25
25
|
|
|
26
26
|
from streamlit.connections import BaseConnection
|
|
27
27
|
from streamlit.connections.util import extract_from_dict
|
|
@@ -176,7 +176,7 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
|
176
176
|
|
|
177
177
|
"""
|
|
178
178
|
|
|
179
|
-
def _connect(self, autocommit: bool = False, **kwargs) -> Engine:
|
|
179
|
+
def _connect(self, autocommit: bool = False, **kwargs: Any) -> Engine:
|
|
180
180
|
import sqlalchemy
|
|
181
181
|
|
|
182
182
|
kwargs = deepcopy(kwargs)
|
|
@@ -207,7 +207,7 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
|
207
207
|
host=conn_params["host"],
|
|
208
208
|
port=int(conn_params["port"]) if "port" in conn_params else None,
|
|
209
209
|
database=conn_params.get("database"),
|
|
210
|
-
query=conn_params
|
|
210
|
+
query=conn_params.get("query", {}),
|
|
211
211
|
)
|
|
212
212
|
|
|
213
213
|
create_engine_kwargs = ChainMap(
|
|
@@ -217,8 +217,7 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
|
217
217
|
|
|
218
218
|
if autocommit:
|
|
219
219
|
return cast("Engine", eng.execution_options(isolation_level="AUTOCOMMIT"))
|
|
220
|
-
|
|
221
|
-
return cast("Engine", eng)
|
|
220
|
+
return cast("Engine", eng)
|
|
222
221
|
|
|
223
222
|
def query(
|
|
224
223
|
self,
|
|
@@ -228,8 +227,8 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
|
228
227
|
ttl: float | int | timedelta | None = None,
|
|
229
228
|
index_col: str | list[str] | None = None,
|
|
230
229
|
chunksize: int | None = None,
|
|
231
|
-
params=None,
|
|
232
|
-
**kwargs,
|
|
230
|
+
params: Any | None = None,
|
|
231
|
+
**kwargs: Any,
|
|
233
232
|
) -> DataFrame:
|
|
234
233
|
"""Run a read-only query.
|
|
235
234
|
|
|
@@ -312,21 +311,24 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
|
312
311
|
)
|
|
313
312
|
def _query(
|
|
314
313
|
sql: str,
|
|
315
|
-
index_col=None,
|
|
316
|
-
chunksize=None,
|
|
317
|
-
params=None,
|
|
318
|
-
**kwargs,
|
|
314
|
+
index_col: str | list[str] | None = None,
|
|
315
|
+
chunksize: int | None = None,
|
|
316
|
+
params: Any | None = None,
|
|
317
|
+
**kwargs: Any,
|
|
319
318
|
) -> DataFrame:
|
|
320
319
|
import pandas as pd
|
|
321
320
|
|
|
322
321
|
instance = self._instance.connect()
|
|
323
|
-
return
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
+
),
|
|
330
332
|
)
|
|
331
333
|
|
|
332
334
|
# We modify our helper function's `__qualname__` here to work around default
|
streamlit/connections/util.py
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
23
|
import os
|
|
24
|
-
from typing import TYPE_CHECKING, Any
|
|
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
|
|
95
|
+
return is_in_stored_procedure() # type: ignore
|
|
96
96
|
except ModuleNotFoundError:
|
|
97
97
|
return False
|
streamlit/cursor.py
CHANGED
|
@@ -91,7 +91,7 @@ class Cursor:
|
|
|
91
91
|
def is_locked(self) -> bool:
|
|
92
92
|
raise NotImplementedError()
|
|
93
93
|
|
|
94
|
-
def get_locked_cursor(self, **props) -> LockedCursor:
|
|
94
|
+
def get_locked_cursor(self, **props: Any) -> LockedCursor:
|
|
95
95
|
raise NotImplementedError()
|
|
96
96
|
|
|
97
97
|
@property
|
|
@@ -105,7 +105,7 @@ class Cursor:
|
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
class RunningCursor(Cursor):
|
|
108
|
-
def __init__(self, root_container: int, parent_path: tuple[int, ...] = ()):
|
|
108
|
+
def __init__(self, root_container: int, parent_path: tuple[int, ...] = ()) -> None:
|
|
109
109
|
"""A moving pointer to a delta location in the app.
|
|
110
110
|
|
|
111
111
|
RunningCursors auto-increment to the next available location when you
|
|
@@ -140,7 +140,7 @@ class RunningCursor(Cursor):
|
|
|
140
140
|
def is_locked(self) -> bool:
|
|
141
141
|
return False
|
|
142
142
|
|
|
143
|
-
def get_locked_cursor(self, **props) -> LockedCursor:
|
|
143
|
+
def get_locked_cursor(self, **props: Any) -> LockedCursor:
|
|
144
144
|
locked_cursor = LockedCursor(
|
|
145
145
|
root_container=self._root_container,
|
|
146
146
|
parent_path=self._parent_path,
|
|
@@ -159,8 +159,8 @@ class LockedCursor(Cursor):
|
|
|
159
159
|
root_container: int,
|
|
160
160
|
parent_path: tuple[int, ...] = (),
|
|
161
161
|
index: int = 0,
|
|
162
|
-
**props,
|
|
163
|
-
):
|
|
162
|
+
**props: Any,
|
|
163
|
+
) -> None:
|
|
164
164
|
"""A locked pointer to a location in the app.
|
|
165
165
|
|
|
166
166
|
LockedCursors always point to the same location, even when you call
|
|
@@ -201,7 +201,7 @@ class LockedCursor(Cursor):
|
|
|
201
201
|
def is_locked(self) -> bool:
|
|
202
202
|
return True
|
|
203
203
|
|
|
204
|
-
def get_locked_cursor(self, **props) -> LockedCursor:
|
|
204
|
+
def get_locked_cursor(self, **props: Any) -> LockedCursor:
|
|
205
205
|
self._props = props
|
|
206
206
|
return self
|
|
207
207
|
|