streamlit-nightly 1.40.3.dev20241130__py2.py3-none-any.whl → 1.40.3.dev20241202__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.
@@ -16,18 +16,17 @@ from __future__ import annotations
16
16
 
17
17
  import os
18
18
  import traceback
19
- from typing import TYPE_CHECKING, Final, cast
19
+ from typing import TYPE_CHECKING, Callable, Final, TypeVar, cast
20
20
 
21
- import streamlit
22
21
  from streamlit.errors import (
23
22
  MarkdownFormattedException,
24
- StreamlitAPIException,
25
23
  StreamlitAPIWarning,
26
24
  UncaughtAppException,
27
25
  )
28
26
  from streamlit.logger import get_logger
29
27
  from streamlit.proto.Exception_pb2 import Exception as ExceptionProto
30
28
  from streamlit.runtime.metrics_util import gather_metrics
29
+ from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
31
30
 
32
31
  if TYPE_CHECKING:
33
32
  from streamlit.delta_generator import DeltaGenerator
@@ -38,12 +37,6 @@ _LOGGER: Final = get_logger(__name__)
38
37
  # frontend when we encounter an uncaught app exception.
39
38
  _GENERIC_UNCAUGHT_EXCEPTION_TEXT: Final = "This app has encountered an error. The original error message is redacted to prevent data leaks. Full error details have been recorded in the logs (if you're on Streamlit Cloud, click on 'Manage app' in the lower right of your app)."
40
39
 
41
- # Extract the streamlit package path. Make it absolute, resolve aliases, and
42
- # ensure there's a trailing path separator
43
- _STREAMLIT_DIR: Final = os.path.join(
44
- os.path.realpath(os.path.dirname(streamlit.__file__)), ""
45
- )
46
-
47
40
 
48
41
  class ExceptionMixin:
49
42
  @gather_metrics("exception")
@@ -84,16 +77,9 @@ def marshall(exception_proto: ExceptionProto, exception: BaseException) -> None:
84
77
  exception : BaseException
85
78
  The exception whose data we're extracting
86
79
  """
87
- # If this is a StreamlitAPIException, we prune all Streamlit entries
88
- # from the exception's stack trace.
89
- is_api_exception = isinstance(exception, StreamlitAPIException)
90
80
  is_markdown_exception = isinstance(exception, MarkdownFormattedException)
91
81
  is_uncaught_app_exception = isinstance(exception, UncaughtAppException)
92
82
 
93
- stack_trace = _get_stack_trace_str_list(
94
- exception, strip_streamlit_stack_entries=is_api_exception
95
- )
96
-
97
83
  # Some exceptions (like UserHashError) have an alternate_name attribute so
98
84
  # we can pretend to the user that the exception is called something else.
99
85
  if getattr(exception, "alternate_name", None) is not None:
@@ -101,6 +87,8 @@ def marshall(exception_proto: ExceptionProto, exception: BaseException) -> None:
101
87
  else:
102
88
  exception_proto.type = type(exception).__name__
103
89
 
90
+ stack_trace = _get_stack_trace_str_list(exception)
91
+
104
92
  exception_proto.stack_trace.extend(stack_trace)
105
93
  exception_proto.is_warning = isinstance(exception, Warning)
106
94
 
@@ -185,9 +173,7 @@ def _format_syntax_error_message(exception: SyntaxError) -> str:
185
173
  return str(exception)
186
174
 
187
175
 
188
- def _get_stack_trace_str_list(
189
- exception: BaseException, strip_streamlit_stack_entries: bool = False
190
- ) -> list[str]:
176
+ def _get_stack_trace_str_list(exception: BaseException) -> list[str]:
191
177
  """Get the stack trace for the given exception.
192
178
 
193
179
  Parameters
@@ -195,16 +181,13 @@ def _get_stack_trace_str_list(
195
181
  exception : BaseException
196
182
  The exception to extract the traceback from
197
183
 
198
- strip_streamlit_stack_entries : bool
199
- If True, all traceback entries that are in the Streamlit package
200
- will be removed from the list. We do this for exceptions that result
201
- from incorrect usage of Streamlit APIs, so that the user doesn't see
202
- a bunch of noise about ScriptRunner, DeltaGenerator, etc.
203
-
204
184
  Returns
205
185
  -------
206
- list
207
- The exception traceback as a list of strings
186
+ tuple of two string lists
187
+ The exception traceback as two lists of strings. The first represents the part
188
+ of the stack trace the users don't typically want to see, containing internal
189
+ Streamlit code. The second is whatever comes after the Streamlit stack trace,
190
+ which is usually what the user wants.
208
191
 
209
192
  """
210
193
  extracted_traceback: traceback.StackSummary | None = None
@@ -218,36 +201,93 @@ def _get_stack_trace_str_list(
218
201
 
219
202
  # Format the extracted traceback and add it to the protobuf element.
220
203
  if extracted_traceback is None:
221
- stack_trace_str_list = [
204
+ trace_str_list = [
222
205
  "Cannot extract the stack trace for this exception. "
223
206
  "Try calling exception() within the `catch` block."
224
207
  ]
225
208
  else:
226
- if strip_streamlit_stack_entries:
227
- extracted_frames = _get_nonstreamlit_traceback(extracted_traceback)
228
- stack_trace_str_list = traceback.format_list(extracted_frames)
209
+ internal_frames, external_frames = _split_internal_streamlit_frames(
210
+ extracted_traceback
211
+ )
212
+
213
+ if external_frames:
214
+ trace_str_list = traceback.format_list(external_frames)
229
215
  else:
230
- stack_trace_str_list = traceback.format_list(extracted_traceback)
216
+ trace_str_list = traceback.format_list(internal_frames)
231
217
 
232
- stack_trace_str_list = [item.strip() for item in stack_trace_str_list]
218
+ trace_str_list = [item.strip() for item in trace_str_list]
233
219
 
234
- return stack_trace_str_list
220
+ return trace_str_list
235
221
 
236
222
 
237
- def _is_in_streamlit_package(file: str) -> bool:
238
- """True if the given file is part of the streamlit package."""
223
+ def _is_in_package(file: str, package_path: str) -> bool:
224
+ """True if the given file is part of package_path."""
239
225
  try:
240
- common_prefix = os.path.commonprefix([os.path.realpath(file), _STREAMLIT_DIR])
226
+ common_prefix = os.path.commonprefix([os.path.realpath(file), package_path])
241
227
  except ValueError:
242
228
  # Raised if paths are on different drives.
243
229
  return False
244
230
 
245
- return common_prefix == _STREAMLIT_DIR
231
+ return common_prefix == package_path
246
232
 
247
233
 
248
- def _get_nonstreamlit_traceback(
234
+ def _split_internal_streamlit_frames(
249
235
  extracted_tb: traceback.StackSummary,
250
- ) -> list[traceback.FrameSummary]:
251
- return [
252
- entry for entry in extracted_tb if not _is_in_streamlit_package(entry.filename)
253
- ]
236
+ ) -> tuple[list[traceback.FrameSummary], list[traceback.FrameSummary]]:
237
+ """Split the traceback into a Streamlit-internal part and an external part.
238
+
239
+ The internal part is everything up to (but excluding) the first frame belonging to
240
+ the user's code. The external part is everything else.
241
+
242
+ So if the stack looks like this:
243
+
244
+ 1. Streamlit frame
245
+ 2. Pandas frame
246
+ 3. Altair frame
247
+ 4. Streamlit frame
248
+ 5. User frame
249
+ 6. User frame
250
+ 7. Streamlit frame
251
+ 8. Matplotlib frame
252
+
253
+ ...then this should return 1-4 as the internal traceback and 5-8 as the external.
254
+
255
+ (Note that something like the example above is extremely unlikely to happen since
256
+ it's not like Altair is calling Streamlit code, but you get the idea.)
257
+ """
258
+
259
+ ctx = get_script_run_ctx()
260
+
261
+ if not ctx:
262
+ return [], list(extracted_tb)
263
+
264
+ package_path = os.path.join(os.path.realpath(str(ctx.main_script_parent)), "")
265
+
266
+ return _split_list(
267
+ extracted_tb,
268
+ split_point=lambda tb: _is_in_package(tb.filename, package_path),
269
+ )
270
+
271
+
272
+ T = TypeVar("T")
273
+
274
+
275
+ def _split_list(
276
+ orig_list: list[T], split_point: Callable[[T], bool]
277
+ ) -> tuple[list[T], list[T]]:
278
+ before: list[T] = []
279
+ after: list[T] = []
280
+
281
+ saw_split_point = False
282
+
283
+ for item in orig_list:
284
+ if not saw_split_point:
285
+ if split_point(item):
286
+ saw_split_point = True
287
+
288
+ if saw_split_point:
289
+ after.append(item)
290
+ else:
291
+ before.append(item)
292
+
293
+ return before, after
@@ -178,7 +178,7 @@ class StreamlitPage:
178
178
  if not ctx:
179
179
  return
180
180
 
181
- main_path = Path(ctx.pages_manager.main_script_path).parent
181
+ main_path = ctx.pages_manager.main_script_parent
182
182
  if isinstance(page, str):
183
183
  page = Path(page)
184
184
  if isinstance(page, Path):
@@ -57,8 +57,7 @@ class PagesStrategyV1:
57
57
  def _handle_page_changed(_path: str) -> None:
58
58
  source_util.invalidate_pages_cache()
59
59
 
60
- main_script_path = Path(pages_manager.main_script_path)
61
- pages_dir = main_script_path.parent / "pages"
60
+ pages_dir = pages_manager.main_script_parent / "pages"
62
61
  watch_dir(
63
62
  str(pages_dir),
64
63
  _handle_page_changed,
@@ -243,6 +242,10 @@ class PagesManager:
243
242
  def main_script_path(self) -> ScriptPath:
244
243
  return self._main_script_path
245
244
 
245
+ @property
246
+ def main_script_parent(self) -> Path:
247
+ return Path(self._main_script_path).parent
248
+
246
249
  @property
247
250
  def main_script_hash(self) -> PageHash:
248
251
  return self._main_script_hash
@@ -295,7 +298,7 @@ class PagesManager:
295
298
  def set_pages(self, pages: dict[PageHash, PageInfo]) -> None:
296
299
  # Manually setting the pages indicates we are using MPA v2.
297
300
  if isinstance(self.pages_strategy, PagesStrategyV1):
298
- if os.path.exists(Path(self.main_script_path).parent / "pages"):
301
+ if os.path.exists(self.main_script_parent / "pages"):
299
302
  _LOGGER.warning(
300
303
  "st.navigation was called in an app with a pages/ directory. This may cause unusual app behavior. You may want to rename the pages/ directory."
301
304
  )
@@ -39,6 +39,8 @@ from streamlit.errors import (
39
39
  from streamlit.logger import get_logger
40
40
 
41
41
  if TYPE_CHECKING:
42
+ from pathlib import Path
43
+
42
44
  from streamlit.cursor import RunningCursor
43
45
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
44
46
  from streamlit.proto.PageProfile_pb2 import Command
@@ -114,6 +116,10 @@ class ScriptRunContext:
114
116
  def active_script_hash(self):
115
117
  return self._active_script_hash
116
118
 
119
+ @property
120
+ def main_script_parent(self) -> Path:
121
+ return self.pages_manager.main_script_parent
122
+
117
123
  @contextlib.contextmanager
118
124
  def run_with_active_hash(self, page_hash: str):
119
125
  original_page_hash = self._active_script_hash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: streamlit-nightly
3
- Version: 1.40.3.dev20241130
3
+ Version: 1.40.3.dev20241202
4
4
  Summary: A faster way to build and share data apps
5
5
  Home-page: https://streamlit.io
6
6
  Author: Snowflake Inc
@@ -65,7 +65,7 @@ streamlit/elements/deck_gl_json_chart.py,sha256=3j8oZjtMK4IxiVW_ISlXPfu56X3UfEQh
65
65
  streamlit/elements/dialog_decorator.py,sha256=12lIbNyinnfk_VvSWB8xauAMCT8PPfdn157aIMtudbg,10052
66
66
  streamlit/elements/doc_string.py,sha256=IuCqpXX0GqKIjCMcaOOHr-fmOixFlCdvCT8d8EIYEAE,16024
67
67
  streamlit/elements/empty.py,sha256=O0UGJsTsij2ZFk1bNP877vxdDkViXM04Q-lp9HMhs0U,4615
68
- streamlit/elements/exception.py,sha256=KcaQP2pvpkKzbXRYTb6lNetY8KDpD-74Aqh_1uP3SGM,8948
68
+ streamlit/elements/exception.py,sha256=WESsjo9PbIGpDvCLc3AEcdCeRMQhsviKgf34aOkrDO8,9841
69
69
  streamlit/elements/form.py,sha256=Nm2DfsypnBB5uFZ2aC_frEPcRCSjhlrxxkcA6_TbfNw,12681
70
70
  streamlit/elements/graphviz_chart.py,sha256=x2CwyP1lqDmIGObs3-Auk-6izCsdctuznKmdcUQqyoY,4937
71
71
  streamlit/elements/heading.py,sha256=xzsf5QFUhlNW1VXjxmsyUHsHDCDzvo4Q6bgVoEBkMec,9893
@@ -135,7 +135,7 @@ streamlit/hello/plotting_demo.py,sha256=VNTbJtjujCEW5_fz2LoElwmz7vGaOKTjlOF_E94P
135
135
  streamlit/hello/streamlit_app.py,sha256=CeLTbfeel07VDxckb4CYVi2U3C1bS-Q8sRU9VycobQA,1683
136
136
  streamlit/hello/utils.py,sha256=IZMM6MZ4tcrLuSN9RWmMEYlzTbbzA3trpq6Pa82NeRw,992
137
137
  streamlit/navigation/__init__.py,sha256=Vrf1yVMOcTyhUPnYvsfyeL96Vpd5z8KoSV5ZzTcTQgU,616
138
- streamlit/navigation/page.py,sha256=grrKbPLn69tD-7i-OXmUBsrOtbvj0CeqWm-2HZtL7vQ,11743
138
+ streamlit/navigation/page.py,sha256=PVdP1NJQ7jVABgawVkzd-ijAofVhUvq5cPJkTMIm8Nk,11732
139
139
  streamlit/proto/Alert_pb2.py,sha256=rGlkoiE7c-gmZbYpuhRdFmRkYLcR3AmdHH3lHw8q1-E,1565
140
140
  streamlit/proto/Alert_pb2.pyi,sha256=sf1JHN92JSQs2_15clCjEfBGPByTTG-FSSZ-qGjWLXk,3106
141
141
  streamlit/proto/AppPage_pb2.py,sha256=zc06HvAElRirQavLwn0TzwJFhB3kvYRxSRdCS1P9ozE,1443
@@ -309,7 +309,7 @@ streamlit/runtime/memory_media_file_storage.py,sha256=9jzWImu9qCUGbJ61c4UhkxRSAP
309
309
  streamlit/runtime/memory_session_storage.py,sha256=mTPuVAapuuUl0h4xZOZqviBHho9v9mDxY-XXSkqrgyQ,2936
310
310
  streamlit/runtime/memory_uploaded_file_manager.py,sha256=rCLvdZv2nPlWeCiHnwV8phcVV43mUCgW7BaWkmEXgpM,4422
311
311
  streamlit/runtime/metrics_util.py,sha256=khmoXNXtpRp7IIpbSVqrmTPB_sT8Oo4hyI9V6P1qthk,15001
312
- streamlit/runtime/pages_manager.py,sha256=cNL6GnBADwi6B5zGBe3IK-h7UP6DXCw12Skm_vFxWaY,12901
312
+ streamlit/runtime/pages_manager.py,sha256=wuqKcS9qX-h_XXw0EyiggUZ0WH9L7s5FmLiElZ_3oU8,12939
313
313
  streamlit/runtime/runtime.py,sha256=ek-bSvOSzwLaY06Sej44wPC5n7WDCMdx0VqYgUz2xWE,29337
314
314
  streamlit/runtime/runtime_util.py,sha256=pPgc524cnmjVffZp_QuH3Yql8TFxuSs23gjnv7gIhqk,4021
315
315
  streamlit/runtime/script_data.py,sha256=-sBITUF0U7DIDL5LE_nFpXAvjnEfiJ9J3HAnnqML9ds,1749
@@ -341,7 +341,7 @@ streamlit/runtime/scriptrunner/script_runner.py,sha256=rNhGoicfv_cg0yyHEFbcTdMYG
341
341
  streamlit/runtime/scriptrunner_utils/__init__.py,sha256=3ecJDi5VtnxRDoaDEdgQIJ-UeNg5VWPZiycE3l6nhf0,840
342
342
  streamlit/runtime/scriptrunner_utils/exceptions.py,sha256=FM09ZMEkAGqdNUPSp3SyFxp0O7g77fZtL_6JcqxNMB8,1554
343
343
  streamlit/runtime/scriptrunner_utils/script_requests.py,sha256=_CeahHuCUJL8CL2oEWkKLOPDAw5HssYgTzg9tdtdUWE,12078
344
- streamlit/runtime/scriptrunner_utils/script_run_context.py,sha256=uldS9qpOwOhSVTCIZfuVSW5Qcqc54-73loh5fq-mlU0,10295
344
+ streamlit/runtime/scriptrunner_utils/script_run_context.py,sha256=TSio56JoWKRCr4AngaWHCrjZjhjB5fmf7TslFdL9wKo,10435
345
345
  streamlit/runtime/state/__init__.py,sha256=rPkmN09FxLMWUDDBbs7Ig2d5MwAKu0GlXQwZSgBHbrY,1433
346
346
  streamlit/runtime/state/common.py,sha256=yYZc4NiFQp0lqMRYSS_Lin_WC3FJj-2irXcPvpjfBOc,6407
347
347
  streamlit/runtime/state/query_params.py,sha256=kCNQI99ctEGY7B2q49D9RM1vGGlZn9b4IqTxtMM9BJs,7507
@@ -617,9 +617,9 @@ streamlit/web/server/server_util.py,sha256=ioIHkXNlA_ujj2Q3isziM8r5glKxgK2JZRoCD
617
617
  streamlit/web/server/stats_request_handler.py,sha256=e144zIhzLTB1PN4CwTCxElCoWMuo9IsBEPex2exHCQ0,3641
618
618
  streamlit/web/server/upload_file_request_handler.py,sha256=ftyKpARrUjOpRcFETIXuoTyOG_mo-ToOw5NI0y_W4lE,5003
619
619
  streamlit/web/server/websocket_headers.py,sha256=uUxypj04ondEC4ocBiYCndX_N06Zwe1Mt690Vupe08Y,2232
620
- streamlit_nightly-1.40.3.dev20241130.data/scripts/streamlit.cmd,sha256=ZEYM3vBJSp-k7vwSJ3ba5NzEk9-qHdSeLvGYAAe1mMw,676
621
- streamlit_nightly-1.40.3.dev20241130.dist-info/METADATA,sha256=WK61eiCsdT5et1g18hZyMa1z-PBsW0Ru2-AuDRirMHU,8513
622
- streamlit_nightly-1.40.3.dev20241130.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
623
- streamlit_nightly-1.40.3.dev20241130.dist-info/entry_points.txt,sha256=uNJ4DwGNXEhOK0USwSNanjkYyR-Bk7eYQbJFDrWyOgY,53
624
- streamlit_nightly-1.40.3.dev20241130.dist-info/top_level.txt,sha256=V3FhKbm7G2LnR0s4SytavrjIPNIhvcsAGXfYHAwtQzw,10
625
- streamlit_nightly-1.40.3.dev20241130.dist-info/RECORD,,
620
+ streamlit_nightly-1.40.3.dev20241202.data/scripts/streamlit.cmd,sha256=ZEYM3vBJSp-k7vwSJ3ba5NzEk9-qHdSeLvGYAAe1mMw,676
621
+ streamlit_nightly-1.40.3.dev20241202.dist-info/METADATA,sha256=DXIeFUyhn9gZfSCvPUPm3-0JfBEMnER8zGzUkz0z4uI,8513
622
+ streamlit_nightly-1.40.3.dev20241202.dist-info/WHEEL,sha256=pxeNX5JdtCe58PUSYP9upmc7jdRPgvT0Gm9kb1SHlVw,109
623
+ streamlit_nightly-1.40.3.dev20241202.dist-info/entry_points.txt,sha256=uNJ4DwGNXEhOK0USwSNanjkYyR-Bk7eYQbJFDrWyOgY,53
624
+ streamlit_nightly-1.40.3.dev20241202.dist-info/top_level.txt,sha256=V3FhKbm7G2LnR0s4SytavrjIPNIhvcsAGXfYHAwtQzw,10
625
+ streamlit_nightly-1.40.3.dev20241202.dist-info/RECORD,,