streamlit-nightly 1.37.2.dev20240819__py2.py3-none-any.whl → 1.37.2.dev20240822__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. streamlit/elements/arrow.py +33 -8
  2. streamlit/elements/code.py +7 -0
  3. streamlit/elements/image.py +15 -25
  4. streamlit/elements/json.py +12 -5
  5. streamlit/elements/lib/column_types.py +3 -3
  6. streamlit/elements/lib/policies.py +10 -9
  7. streamlit/elements/map.py +13 -18
  8. streamlit/elements/vega_charts.py +6 -14
  9. streamlit/elements/widgets/button_group.py +2 -2
  10. streamlit/elements/widgets/data_editor.py +9 -6
  11. streamlit/elements/widgets/multiselect.py +4 -4
  12. streamlit/elements/widgets/radio.py +43 -4
  13. streamlit/elements/widgets/select_slider.py +63 -11
  14. streamlit/elements/widgets/selectbox.py +4 -4
  15. streamlit/elements/write.py +1 -1
  16. streamlit/proto/Code_pb2.py +2 -2
  17. streamlit/proto/Code_pb2.pyi +4 -1
  18. streamlit/runtime/caching/__init__.py +1 -11
  19. streamlit/runtime/caching/cache_data_api.py +10 -81
  20. streamlit/runtime/caching/cache_errors.py +13 -9
  21. streamlit/runtime/caching/cache_resource_api.py +8 -56
  22. streamlit/runtime/caching/cache_utils.py +7 -12
  23. streamlit/runtime/caching/cached_message_replay.py +29 -185
  24. streamlit/runtime/caching/legacy_cache_api.py +15 -11
  25. streamlit/runtime/scriptrunner_utils/script_run_context.py +9 -4
  26. streamlit/runtime/state/widgets.py +0 -5
  27. streamlit/static/asset-manifest.json +24 -24
  28. streamlit/static/index.html +1 -1
  29. streamlit/static/static/js/{1074.0db34d15.chunk.js → 1074.9d1e63cc.chunk.js} +1 -1
  30. streamlit/static/static/js/{1116.22f8322c.chunk.js → 1116.85ec79d5.chunk.js} +1 -1
  31. streamlit/static/static/js/{1168.2a9806f0.chunk.js → 1168.7c30158a.chunk.js} +1 -1
  32. streamlit/static/static/js/1307.2bdac721.chunk.js +1 -0
  33. streamlit/static/static/js/{1451.d93e956f.chunk.js → 1451.7ff31fc7.chunk.js} +1 -1
  34. streamlit/static/static/js/1792.d126bbd9.chunk.js +1 -0
  35. streamlit/static/static/js/3513.5e3a04f2.chunk.js +1 -0
  36. streamlit/static/static/js/3599.963d0e5a.chunk.js +5 -0
  37. streamlit/static/static/js/{4335.bc097c4d.chunk.js → 4335.b166a7b6.chunk.js} +1 -1
  38. streamlit/static/static/js/{4477.edb1d80a.chunk.js → 4477.568118b6.chunk.js} +1 -1
  39. streamlit/static/static/js/5106.62135ac5.chunk.js +1 -0
  40. streamlit/static/static/js/{5441.4cdb2690.chunk.js → 5441.63087272.chunk.js} +1 -1
  41. streamlit/static/static/js/6013.b6375a8d.chunk.js +5 -0
  42. streamlit/static/static/js/6718.f5745d2b.chunk.js +1 -0
  43. streamlit/static/static/js/{7175.70728640.chunk.js → 7175.a10184bd.chunk.js} +1 -1
  44. streamlit/static/static/js/{7323.4e64ad2c.chunk.js → 7323.05e7058a.chunk.js} +2 -2
  45. streamlit/static/static/js/7602.a6e1d802.chunk.js +1 -0
  46. streamlit/static/static/js/7702.b905bebd.chunk.js +1 -0
  47. streamlit/static/static/js/7805.23670b3c.chunk.js +1 -0
  48. streamlit/static/static/js/8148.8bd2f9d3.chunk.js +1 -0
  49. streamlit/static/static/js/8536.bdf41383.chunk.js +1 -0
  50. streamlit/static/static/js/8691.ee55fefc.chunk.js +5 -0
  51. streamlit/static/static/js/main.33cac65c.js +28 -0
  52. {streamlit_nightly-1.37.2.dev20240819.dist-info → streamlit_nightly-1.37.2.dev20240822.dist-info}/METADATA +1 -1
  53. {streamlit_nightly-1.37.2.dev20240819.dist-info → streamlit_nightly-1.37.2.dev20240822.dist-info}/RECORD +59 -59
  54. {streamlit_nightly-1.37.2.dev20240819.dist-info → streamlit_nightly-1.37.2.dev20240822.dist-info}/WHEEL +1 -1
  55. streamlit/static/static/js/1307.74a443f7.chunk.js +0 -1
  56. streamlit/static/static/js/1792.eb8a836f.chunk.js +0 -1
  57. streamlit/static/static/js/3513.577f3dc5.chunk.js +0 -1
  58. streamlit/static/static/js/3599.eaeac234.chunk.js +0 -5
  59. streamlit/static/static/js/4666.0e91bb87.chunk.js +0 -1
  60. streamlit/static/static/js/5106.4c60cfa4.chunk.js +0 -1
  61. streamlit/static/static/js/6013.fb4531df.chunk.js +0 -5
  62. streamlit/static/static/js/6718.6fb2aa21.chunk.js +0 -1
  63. streamlit/static/static/js/7602.33571c14.chunk.js +0 -1
  64. streamlit/static/static/js/7805.ba32ae70.chunk.js +0 -1
  65. streamlit/static/static/js/8148.b905db99.chunk.js +0 -1
  66. streamlit/static/static/js/8536.b7b2ef90.chunk.js +0 -1
  67. streamlit/static/static/js/8691.93a29403.chunk.js +0 -5
  68. streamlit/static/static/js/main.8c6fc86e.js +0 -28
  69. /streamlit/static/static/js/{7323.4e64ad2c.chunk.js.LICENSE.txt → 7323.05e7058a.chunk.js.LICENSE.txt} +0 -0
  70. /streamlit/static/static/js/{main.8c6fc86e.js.LICENSE.txt → main.33cac65c.js.LICENSE.txt} +0 -0
  71. {streamlit_nightly-1.37.2.dev20240819.data → streamlit_nightly-1.37.2.dev20240822.data}/scripts/streamlit.cmd +0 -0
  72. {streamlit_nightly-1.37.2.dev20240819.dist-info → streamlit_nightly-1.37.2.dev20240822.dist-info}/entry_points.txt +0 -0
  73. {streamlit_nightly-1.37.2.dev20240819.dist-info → streamlit_nightly-1.37.2.dev20240822.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
 
16
16
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1astreamlit/proto/Code.proto\"F\n\x04\x43ode\x12\x11\n\tcode_text\x18\x01 \x01(\t\x12\x10\n\x08language\x18\x02 \x01(\t\x12\x19\n\x11show_line_numbers\x18\x03 \x01(\x08\x42)\n\x1c\x63om.snowflake.apps.streamlitB\tCodeProtob\x06proto3')
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1astreamlit/proto/Code.proto\"Z\n\x04\x43ode\x12\x11\n\tcode_text\x18\x01 \x01(\t\x12\x10\n\x08language\x18\x02 \x01(\t\x12\x19\n\x11show_line_numbers\x18\x03 \x01(\x08\x12\x12\n\nwrap_lines\x18\x04 \x01(\x08\x42)\n\x1c\x63om.snowflake.apps.streamlitB\tCodeProtob\x06proto3')
18
18
 
19
19
  _globals = globals()
20
20
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -23,5 +23,5 @@ if not _descriptor._USE_C_DESCRIPTORS:
23
23
  _globals['DESCRIPTOR']._loaded_options = None
24
24
  _globals['DESCRIPTOR']._serialized_options = b'\n\034com.snowflake.apps.streamlitB\tCodeProto'
25
25
  _globals['_CODE']._serialized_start=30
26
- _globals['_CODE']._serialized_end=100
26
+ _globals['_CODE']._serialized_end=120
27
27
  # @@protoc_insertion_point(module_scope)
@@ -33,17 +33,20 @@ class Code(google.protobuf.message.Message):
33
33
  CODE_TEXT_FIELD_NUMBER: builtins.int
34
34
  LANGUAGE_FIELD_NUMBER: builtins.int
35
35
  SHOW_LINE_NUMBERS_FIELD_NUMBER: builtins.int
36
+ WRAP_LINES_FIELD_NUMBER: builtins.int
36
37
  code_text: builtins.str
37
38
  """Content to display."""
38
39
  language: builtins.str
39
40
  show_line_numbers: builtins.bool
41
+ wrap_lines: builtins.bool
40
42
  def __init__(
41
43
  self,
42
44
  *,
43
45
  code_text: builtins.str = ...,
44
46
  language: builtins.str = ...,
45
47
  show_line_numbers: builtins.bool = ...,
48
+ wrap_lines: builtins.bool = ...,
46
49
  ) -> None: ...
47
- def ClearField(self, field_name: typing.Literal["code_text", b"code_text", "language", b"language", "show_line_numbers", b"show_line_numbers"]) -> None: ...
50
+ def ClearField(self, field_name: typing.Literal["code_text", b"code_text", "language", b"language", "show_line_numbers", b"show_line_numbers", "wrap_lines", b"wrap_lines"]) -> None: ...
48
51
 
49
52
  global___Code = Code
@@ -14,7 +14,7 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import TYPE_CHECKING, Any
17
+ from typing import TYPE_CHECKING
18
18
 
19
19
  from streamlit.runtime.caching.cache_data_api import (
20
20
  CACHE_DATA_MESSAGE_REPLAY_CTX,
@@ -33,7 +33,6 @@ if TYPE_CHECKING:
33
33
  from google.protobuf.message import Message
34
34
 
35
35
  from streamlit.proto.Block_pb2 import Block
36
- from streamlit.runtime.state.common import WidgetMetadata
37
36
 
38
37
 
39
38
  def save_element_message(
@@ -73,14 +72,6 @@ def save_block_message(
73
72
  )
74
73
 
75
74
 
76
- def save_widget_metadata(metadata: WidgetMetadata[Any]) -> None:
77
- """Save a widget's metadata to a thread-local callstack, so the widget
78
- can be registered again when that widget is replayed.
79
- """
80
- CACHE_DATA_MESSAGE_REPLAY_CTX.save_widget_metadata(metadata)
81
- CACHE_RESOURCE_MESSAGE_REPLAY_CTX.save_widget_metadata(metadata)
82
-
83
-
84
75
  def save_media_data(image_data: bytes | str, mimetype: str, image_id: str) -> None:
85
76
  CACHE_DATA_MESSAGE_REPLAY_CTX.save_image_data(image_data, mimetype, image_id)
86
77
  CACHE_RESOURCE_MESSAGE_REPLAY_CTX.save_image_data(image_data, mimetype, image_id)
@@ -99,7 +90,6 @@ __all__ = [
99
90
  "CACHE_DOCS_URL",
100
91
  "save_element_message",
101
92
  "save_block_message",
102
- "save_widget_metadata",
103
93
  "save_media_data",
104
94
  "get_data_cache_stats_provider",
105
95
  "get_resource_cache_stats_provider",
@@ -47,9 +47,7 @@ from streamlit.runtime.caching.cache_utils import (
47
47
  from streamlit.runtime.caching.cached_message_replay import (
48
48
  CachedMessageReplayContext,
49
49
  CachedResult,
50
- ElementMsgData,
51
50
  MsgData,
52
- MultiCacheResults,
53
51
  show_widget_replay_deprecation,
54
52
  )
55
53
  from streamlit.runtime.caching.storage import (
@@ -66,7 +64,6 @@ from streamlit.runtime.caching.storage.dummy_cache_storage import (
66
64
  MemoryCacheStorageManager,
67
65
  )
68
66
  from streamlit.runtime.metrics_util import gather_metrics
69
- from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
70
67
  from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
71
68
  from streamlit.time_util import time_to_seconds
72
69
 
@@ -93,13 +90,11 @@ class CachedDataFuncInfo(CachedFuncInfo):
93
90
  persist: CachePersistType,
94
91
  max_entries: int | None,
95
92
  ttl: float | timedelta | str | None,
96
- allow_widgets: bool,
97
93
  hash_funcs: HashFuncsDict | None = None,
98
94
  ):
99
95
  super().__init__(
100
96
  func,
101
97
  show_spinner=show_spinner,
102
- allow_widgets=allow_widgets,
103
98
  hash_funcs=hash_funcs,
104
99
  )
105
100
  self.persist = persist
@@ -128,7 +123,6 @@ class CachedDataFuncInfo(CachedFuncInfo):
128
123
  max_entries=self.max_entries,
129
124
  ttl=self.ttl,
130
125
  display_name=self.display_name,
131
- allow_widgets=self.allow_widgets,
132
126
  )
133
127
 
134
128
  def validate_params(self) -> None:
@@ -160,7 +154,6 @@ class DataCaches(CacheStatsProvider):
160
154
  max_entries: int | None,
161
155
  ttl: int | float | timedelta | str | None,
162
156
  display_name: str,
163
- allow_widgets: bool,
164
157
  ) -> DataCache:
165
158
  """Return the mem cache for the given key.
166
159
 
@@ -220,7 +213,6 @@ class DataCaches(CacheStatsProvider):
220
213
  max_entries=max_entries,
221
214
  ttl_seconds=ttl_seconds,
222
215
  display_name=display_name,
223
- allow_widgets=allow_widgets,
224
216
  )
225
217
  self._function_caches[key] = cache
226
218
  return cache
@@ -443,9 +435,6 @@ class CacheDataAPI:
443
435
 
444
436
  experimental_allow_widgets : bool
445
437
  Allow widgets to be used in the cached function. Defaults to False.
446
- Support for widgets in cached functions is currently experimental.
447
- Setting this parameter to True may lead to excessive memory use since the
448
- widget value is treated as an additional input parameter to the cache.
449
438
 
450
439
  hash_funcs : dict or None
451
440
  Mapping of types or fully qualified names to hash functions.
@@ -456,8 +445,10 @@ class CacheDataAPI:
456
445
  of how this can be used.
457
446
 
458
447
  .. deprecated::
459
- ``experimental_allow_widgets`` is deprecated and will be removed in
460
- a later version.
448
+ The cached widget replay functionality was removed in 1.38. Please
449
+ remove the ``experimental_allow_widgets`` parameter from your
450
+ caching decorators. This parameter will be removed in a future
451
+ version.
461
452
 
462
453
  Example
463
454
  -------
@@ -574,7 +565,6 @@ class CacheDataAPI:
574
565
  show_spinner=show_spinner,
575
566
  max_entries=max_entries,
576
567
  ttl=ttl,
577
- allow_widgets=experimental_allow_widgets,
578
568
  hash_funcs=hash_funcs,
579
569
  )
580
570
  )
@@ -589,7 +579,6 @@ class CacheDataAPI:
589
579
  show_spinner=show_spinner,
590
580
  max_entries=max_entries,
591
581
  ttl=ttl,
592
- allow_widgets=experimental_allow_widgets,
593
582
  hash_funcs=hash_funcs,
594
583
  )
595
584
  )
@@ -611,7 +600,6 @@ class DataCache(Cache):
611
600
  max_entries: int | None,
612
601
  ttl_seconds: float | None,
613
602
  display_name: str,
614
- allow_widgets: bool = False,
615
603
  ):
616
604
  super().__init__()
617
605
  self.key = key
@@ -620,7 +608,6 @@ class DataCache(Cache):
620
608
  self.ttl_seconds = ttl_seconds
621
609
  self.max_entries = max_entries
622
610
  self.persist = persist
623
- self.allow_widgets = allow_widgets
624
611
 
625
612
  def get_stats(self) -> list[CacheStat]:
626
613
  if isinstance(self.storage, CacheStatsProvider):
@@ -641,21 +628,12 @@ class DataCache(Cache):
641
628
 
642
629
  try:
643
630
  entry = pickle.loads(pickled_entry)
644
- if not isinstance(entry, MultiCacheResults):
631
+ if not isinstance(entry, CachedResult):
645
632
  # Loaded an old cache file format, remove it and let the caller
646
633
  # rerun the function.
647
634
  self.storage.delete(key)
648
635
  raise CacheKeyNotFoundError()
649
-
650
- ctx = get_script_run_ctx()
651
- if not ctx:
652
- raise CacheKeyNotFoundError()
653
-
654
- widget_key = entry.get_current_widget_key(ctx, CacheType.DATA)
655
- if widget_key in entry.results:
656
- return entry.results[widget_key]
657
- else:
658
- raise CacheKeyNotFoundError()
636
+ return entry
659
637
  except pickle.UnpicklingError as exc:
660
638
  raise CacheError(f"Failed to unpickle {key}") from exc
661
639
 
@@ -664,43 +642,13 @@ class DataCache(Cache):
664
642
  """Write a value and associated messages to the cache.
665
643
  The value must be pickleable.
666
644
  """
667
- ctx = get_script_run_ctx()
668
- if ctx is None:
669
- return
670
-
671
- main_id = st._main.id
672
- sidebar_id = st.sidebar.id
673
-
674
- if self.allow_widgets:
675
- widgets = {
676
- msg.widget_metadata.widget_id
677
- for msg in messages
678
- if isinstance(msg, ElementMsgData) and msg.widget_metadata is not None
679
- }
680
- else:
681
- widgets = set()
682
-
683
- multi_cache_results: MultiCacheResults | None = None
684
-
685
- # Try to find in cache storage, then falling back to a new result instance
686
- try:
687
- multi_cache_results = self._read_multi_results_from_storage(key)
688
- except (CacheKeyNotFoundError, pickle.UnpicklingError):
689
- pass
690
-
691
- if multi_cache_results is None:
692
- multi_cache_results = MultiCacheResults(widget_ids=widgets, results={})
693
- multi_cache_results.widget_ids.update(widgets)
694
- widget_key = multi_cache_results.get_current_widget_key(ctx, CacheType.DATA)
695
-
696
- result = CachedResult(value, messages, main_id, sidebar_id)
697
- multi_cache_results.results[widget_key] = result
698
-
699
645
  try:
700
- pickled_entry = pickle.dumps(multi_cache_results)
646
+ main_id = st._main.id
647
+ sidebar_id = st.sidebar.id
648
+ entry = CachedResult(value, messages, main_id, sidebar_id)
649
+ pickled_entry = pickle.dumps(entry)
701
650
  except (pickle.PicklingError, TypeError) as exc:
702
651
  raise CacheError(f"Failed to pickle {key}") from exc
703
-
704
652
  self.storage.set(key, pickled_entry)
705
653
 
706
654
  def _clear(self, key: str | None = None) -> None:
@@ -708,22 +656,3 @@ class DataCache(Cache):
708
656
  self.storage.clear()
709
657
  else:
710
658
  self.storage.delete(key)
711
-
712
- def _read_multi_results_from_storage(self, key: str) -> MultiCacheResults:
713
- """Look up the results from storage and ensure it has the right type.
714
-
715
- Raises a `CacheKeyNotFoundError` if the key has no entry, or if the
716
- entry is malformed.
717
- """
718
- try:
719
- pickled = self.storage.get(key)
720
- except CacheStorageKeyNotFoundError as e:
721
- raise CacheKeyNotFoundError(str(e)) from e
722
-
723
- maybe_results = pickle.loads(pickled)
724
-
725
- if isinstance(maybe_results, MultiCacheResults):
726
- return maybe_results
727
- else:
728
- self.storage.delete(key)
729
- raise CacheKeyNotFoundError()
@@ -29,7 +29,7 @@ CACHE_DOCS_URL = "https://docs.streamlit.io/develop/concepts/architecture/cachin
29
29
  def get_cached_func_name_md(func: Any) -> str:
30
30
  """Get markdown representation of the function name."""
31
31
  if hasattr(func, "__name__"):
32
- return "`%s()`" % func.__name__
32
+ return f"`{func.__name__}()`"
33
33
  elif hasattr(type(func), "__name__"):
34
34
  return f"`{type(func).__name__}`"
35
35
  return f"`{type(func)}`"
@@ -105,9 +105,10 @@ class CacheReplayClosureError(StreamlitAPIException):
105
105
 
106
106
  msg = (
107
107
  f"""
108
- While running {func_name}, a streamlit element is called on some layout block created outside the function.
109
- This is incompatible with replaying the cached effect of that element, because the
110
- the referenced block might not exist when the replay happens.
108
+ While running {func_name}, a streamlit element is called on some layout block
109
+ created outside the function. This is incompatible with replaying the cached
110
+ effect of that element, because the the referenced block might not exist when
111
+ the replay happens.
111
112
 
112
113
  How to fix this:
113
114
  * Move the creation of $THING inside {func_name}.
@@ -124,11 +125,14 @@ class UnserializableReturnValueError(MarkdownFormattedException):
124
125
  MarkdownFormattedException.__init__(
125
126
  self,
126
127
  f"""
127
- Cannot serialize the return value (of type {get_return_value_type(return_value)}) in {get_cached_func_name_md(func)}.
128
- `st.cache_data` uses [pickle](https://docs.python.org/3/library/pickle.html) to
129
- serialize the function’s return value and safely store it in the cache without mutating the original object. Please convert the return value to a pickle-serializable type.
130
- If you want to cache unserializable objects such as database connections or Tensorflow
131
- sessions, use `st.cache_resource` instead (see [our docs]({CACHE_DOCS_URL}) for differences).""",
128
+ Cannot serialize the return value (of type {get_return_value_type(return_value)})
129
+ in {get_cached_func_name_md(func)}. `st.cache_data` uses
130
+ [pickle](https://docs.python.org/3/library/pickle.html) to serialize the
131
+ function's return value and safely store it in the cache
132
+ without mutating the original object. Please convert the return value to a
133
+ pickle-serializable type. If you want to cache unserializable objects such
134
+ as database connections or Tensorflow sessions, use `st.cache_resource`
135
+ instead (see [our docs]({CACHE_DOCS_URL}) for differences).""",
132
136
  )
133
137
 
134
138
 
@@ -37,13 +37,10 @@ from streamlit.runtime.caching.cache_utils import (
37
37
  from streamlit.runtime.caching.cached_message_replay import (
38
38
  CachedMessageReplayContext,
39
39
  CachedResult,
40
- ElementMsgData,
41
40
  MsgData,
42
- MultiCacheResults,
43
41
  show_widget_replay_deprecation,
44
42
  )
45
43
  from streamlit.runtime.metrics_util import gather_metrics
46
- from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
47
44
  from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
48
45
  from streamlit.time_util import time_to_seconds
49
46
 
@@ -83,7 +80,6 @@ class ResourceCaches(CacheStatsProvider):
83
80
  max_entries: int | float | None,
84
81
  ttl: float | timedelta | str | None,
85
82
  validate: ValidateFunc | None,
86
- allow_widgets: bool,
87
83
  ) -> ResourceCache:
88
84
  """Return the mem cache for the given key.
89
85
 
@@ -114,7 +110,6 @@ class ResourceCaches(CacheStatsProvider):
114
110
  max_entries=max_entries,
115
111
  ttl_seconds=ttl_seconds,
116
112
  validate=validate,
117
- allow_widgets=allow_widgets,
118
113
  )
119
114
  self._function_caches[key] = cache
120
115
  return cache
@@ -155,13 +150,11 @@ class CachedResourceFuncInfo(CachedFuncInfo):
155
150
  max_entries: int | None,
156
151
  ttl: float | timedelta | str | None,
157
152
  validate: ValidateFunc | None,
158
- allow_widgets: bool,
159
153
  hash_funcs: HashFuncsDict | None = None,
160
154
  ):
161
155
  super().__init__(
162
156
  func,
163
157
  show_spinner=show_spinner,
164
- allow_widgets=allow_widgets,
165
158
  hash_funcs=hash_funcs,
166
159
  )
167
160
  self.max_entries = max_entries
@@ -188,7 +181,6 @@ class CachedResourceFuncInfo(CachedFuncInfo):
188
181
  max_entries=self.max_entries,
189
182
  ttl=self.ttl,
190
183
  validate=self.validate,
191
- allow_widgets=self.allow_widgets,
192
184
  )
193
185
 
194
186
 
@@ -315,9 +307,6 @@ class CacheResourceAPI:
315
307
 
316
308
  experimental_allow_widgets : bool
317
309
  Allow widgets to be used in the cached function. Defaults to False.
318
- Support for widgets in cached functions is currently experimental.
319
- Setting this parameter to True may lead to excessive memory use since the
320
- widget value is treated as an additional input parameter to the cache.
321
310
 
322
311
  hash_funcs : dict or None
323
312
  Mapping of types or fully qualified names to hash functions.
@@ -328,8 +317,10 @@ class CacheResourceAPI:
328
317
  of how this can be used.
329
318
 
330
319
  .. deprecated::
331
- ``experimental_allow_widgets`` is deprecated and will be removed in
332
- a later version.
320
+ The cached widget replay functionality was removed in 1.38. Please
321
+ remove the ``experimental_allow_widgets`` parameter from your
322
+ caching decorators. This parameter will be removed in a future
323
+ version.
333
324
 
334
325
  Example
335
326
  -------
@@ -426,7 +417,6 @@ class CacheResourceAPI:
426
417
  max_entries=max_entries,
427
418
  ttl=ttl,
428
419
  validate=validate,
429
- allow_widgets=experimental_allow_widgets,
430
420
  hash_funcs=hash_funcs,
431
421
  )
432
422
  )
@@ -438,7 +428,6 @@ class CacheResourceAPI:
438
428
  max_entries=max_entries,
439
429
  ttl=ttl,
440
430
  validate=validate,
441
- allow_widgets=experimental_allow_widgets,
442
431
  hash_funcs=hash_funcs,
443
432
  )
444
433
  )
@@ -459,17 +448,15 @@ class ResourceCache(Cache):
459
448
  ttl_seconds: float,
460
449
  validate: ValidateFunc | None,
461
450
  display_name: str,
462
- allow_widgets: bool,
463
451
  ):
464
452
  super().__init__()
465
453
  self.key = key
466
454
  self.display_name = display_name
467
- self._mem_cache: TTLCache[str, MultiCacheResults] = TTLCache(
455
+ self._mem_cache: TTLCache[str, CachedResult] = TTLCache(
468
456
  maxsize=max_entries, ttl=ttl_seconds, timer=cache_utils.TTLCACHE_TIMER
469
457
  )
470
458
  self._mem_cache_lock = threading.Lock()
471
459
  self.validate = validate
472
- self.allow_widgets = allow_widgets
473
460
 
474
461
  @property
475
462
  def max_entries(self) -> float:
@@ -488,24 +475,11 @@ class ResourceCache(Cache):
488
475
  # key does not exist in cache.
489
476
  raise CacheKeyNotFoundError()
490
477
 
491
- multi_results: MultiCacheResults = self._mem_cache[key]
492
-
493
- ctx = get_script_run_ctx()
494
- if not ctx:
495
- # ScriptRunCtx does not exist (we're probably running in "raw" mode).
496
- raise CacheKeyNotFoundError()
497
-
498
- widget_key = multi_results.get_current_widget_key(ctx, CacheType.RESOURCE)
499
- if widget_key not in multi_results.results:
500
- # widget_key does not exist in cache (this combination of widgets hasn't been
501
- # seen for the value_key yet).
502
- raise CacheKeyNotFoundError()
503
-
504
- result = multi_results.results[widget_key]
478
+ result = self._mem_cache[key]
505
479
 
506
480
  if self.validate is not None and not self.validate(result.value):
507
481
  # Validate failed: delete the entry and raise an error.
508
- del multi_results.results[widget_key]
482
+ del self._mem_cache[key]
509
483
  raise CacheKeyNotFoundError()
510
484
 
511
485
  return result
@@ -513,33 +487,11 @@ class ResourceCache(Cache):
513
487
  @gather_metrics("_cache_resource_object")
514
488
  def write_result(self, key: str, value: Any, messages: list[MsgData]) -> None:
515
489
  """Write a value and associated messages to the cache."""
516
- ctx = get_script_run_ctx()
517
- if ctx is None:
518
- return
519
-
520
490
  main_id = st._main.id
521
491
  sidebar_id = st.sidebar.id
522
- if self.allow_widgets:
523
- widgets = {
524
- msg.widget_metadata.widget_id
525
- for msg in messages
526
- if isinstance(msg, ElementMsgData) and msg.widget_metadata is not None
527
- }
528
- else:
529
- widgets = set()
530
492
 
531
493
  with self._mem_cache_lock:
532
- try:
533
- multi_results = self._mem_cache[key]
534
- except KeyError:
535
- multi_results = MultiCacheResults(widget_ids=widgets, results={})
536
-
537
- multi_results.widget_ids.update(widgets)
538
- widget_key = multi_results.get_current_widget_key(ctx, CacheType.RESOURCE)
539
-
540
- result = CachedResult(value, messages, main_id, sidebar_id)
541
- multi_results.results[widget_key] = result
542
- self._mem_cache[key] = multi_results
494
+ self._mem_cache[key] = CachedResult(value, messages, main_id, sidebar_id)
543
495
 
544
496
  def _clear(self, key: str | None = None) -> None:
545
497
  with self._mem_cache_lock:
@@ -16,6 +16,7 @@
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
+ import contextlib
19
20
  import functools
20
21
  import hashlib
21
22
  import inspect
@@ -125,12 +126,10 @@ class CachedFuncInfo:
125
126
  self,
126
127
  func: FunctionType,
127
128
  show_spinner: bool | str,
128
- allow_widgets: bool,
129
129
  hash_funcs: HashFuncsDict | None,
130
130
  ):
131
131
  self.func = func
132
132
  self.show_spinner = show_spinner
133
- self.allow_widgets = allow_widgets
134
133
  self.hash_funcs = hash_funcs
135
134
 
136
135
  @property
@@ -230,11 +229,9 @@ class CachedFunc:
230
229
  hash_funcs=self._info.hash_funcs,
231
230
  )
232
231
 
233
- try:
232
+ with contextlib.suppress(CacheKeyNotFoundError):
234
233
  cached_result = cache.read_result(value_key)
235
234
  return self._handle_cache_hit(cached_result)
236
- except CacheKeyNotFoundError:
237
- pass
238
235
  return self._handle_cache_miss(cache, value_key, func_args, func_kwargs)
239
236
 
240
237
  def _handle_cache_hit(self, result: CachedResult) -> Any:
@@ -279,17 +276,14 @@ class CachedFunc:
279
276
  # We've acquired the lock - but another thread may have acquired it first
280
277
  # and already computed the value. So we need to test for a cache hit again,
281
278
  # before computing.
282
- try:
279
+ with contextlib.suppress(CacheKeyNotFoundError):
283
280
  cached_result = cache.read_result(value_key)
284
281
  # Another thread computed the value before us. Early exit!
285
282
  return self._handle_cache_hit(cached_result)
286
283
 
287
- except CacheKeyNotFoundError:
288
- pass
289
-
290
284
  # We acquired the lock before any other thread. Compute the value!
291
285
  with self._info.cached_message_replay_ctx.calling_cached_function(
292
- self._info.func, self._info.allow_widgets
286
+ self._info.func
293
287
  ):
294
288
  computed_value = self._info.func(*func_args, **func_kwargs)
295
289
 
@@ -329,8 +323,10 @@ class CachedFunc:
329
323
 
330
324
  Parameters
331
325
  ----------
326
+
332
327
  *args: Any
333
328
  Arguments of the cached functions.
329
+
334
330
  **kwargs: Any
335
331
  Keyword arguments of the cached function.
336
332
 
@@ -471,8 +467,7 @@ def _make_function_key(cache_type: CacheType, func: FunctionType) -> str:
471
467
  source_code, hasher=func_hasher, cache_type=cache_type, hash_source=func
472
468
  )
473
469
 
474
- cache_key = func_hasher.hexdigest()
475
- return cache_key
470
+ return func_hasher.hexdigest()
476
471
 
477
472
 
478
473
  def _get_positional_arg_name(func: FunctionType, arg_index: int) -> str | None: