From cf555aa565af1f956382a9ea8eeb956b1cbbb1fe Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:47:29 -0400 Subject: [PATCH 01/56] pycodestyle --- ruff.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index 86b99fc7f..7788915a7 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,7 +73,8 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -# extend-select = ["E", "I", "B", "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E"] +# , "I", "B", "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 8ac19b4a53570b159fbe7218655bae4e05f211b4 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:47:54 -0400 Subject: [PATCH 02/56] isort --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 7788915a7..bef5e7611 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,8 +73,8 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E"] -# , "I", "B", "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E", "I"] +# "B", "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 0fa0840c8e7dd7d82b149b78df598607fa21fd13 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:48:20 -0400 Subject: [PATCH 03/56] flake8-bugbear --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index bef5e7611..194e4afdc 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,8 +73,8 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I"] -# "B", "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E", "I", "B"] +# "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 750378ccac7b41c9f998fbe0f7fa9c5328797f9c Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:51:47 -0400 Subject: [PATCH 04/56] Fix bugbear lints --- examples/airmass/location.py | 2 +- shiny/_connection.py | 2 +- shiny/_docstring.py | 4 ++-- shiny/ui/_layout_columns.py | 3 ++- shiny/ui/_markdown.py | 2 +- shiny/ui/_progress.py | 9 +++++++-- tests/playwright/shiny/inputs/test_input_switch.py | 1 - 7 files changed, 14 insertions(+), 9 deletions(-) diff --git a/examples/airmass/location.py b/examples/airmass/location.py index b644c19a5..f9ca37838 100644 --- a/examples/airmass/location.py +++ b/examples/airmass/location.py @@ -130,6 +130,6 @@ def location(): long = (long + 180) % 360 - 180 return (input.lat(), long) except ValueError: - raise ValueError("Invalid latitude/longitude specification") + raise ValueError("Invalid latitude/longitude specification") from None return location diff --git a/shiny/_connection.py b/shiny/_connection.py index f2e0323fe..1f360d551 100644 --- a/shiny/_connection.py +++ b/shiny/_connection.py @@ -94,7 +94,7 @@ async def receive(self) -> str: try: return await self.conn.receive_text() except starlette.websockets.WebSocketDisconnect: - raise ConnectionClosed() + raise ConnectionClosed() from None except Exception: # From RFC6455: # 1008 indicates that an endpoint is terminating the connection because it diff --git a/shiny/_docstring.py b/shiny/_docstring.py index 8505f96b0..9c6578c30 100644 --- a/shiny/_docstring.py +++ b/shiny/_docstring.py @@ -321,9 +321,9 @@ def _(func: F) -> F: except ImportError: raise RuntimeError( "Please install the latest version of shinylive to build the docs." - ) + ) from None except ModuleNotFoundError: - raise RuntimeError("Please install shinylive to build the docs.") + raise RuntimeError("Please install shinylive to build the docs.") from None class ShinyliveExampleWriter(ExampleWriter): def write_example(self, app_files: list[str]) -> str: diff --git a/shiny/ui/_layout_columns.py b/shiny/ui/_layout_columns.py index d2de2d38e..30b89b673 100644 --- a/shiny/ui/_layout_columns.py +++ b/shiny/ui/_layout_columns.py @@ -201,7 +201,8 @@ def validate_col_width( if len(list(y)) > n_kids: warn( - f"More column widths than children at breakpoint '{break_name}', extra widths will be ignored." + f"More column widths than children at breakpoint '{break_name}', extra widths will be ignored.", + stacklevel=2, ) return y diff --git a/shiny/ui/_markdown.py b/shiny/ui/_markdown.py index 18ddca3f8..551efda28 100644 --- a/shiny/ui/_markdown.py +++ b/shiny/ui/_markdown.py @@ -60,7 +60,7 @@ def default_md_renderer( raise ModuleNotFoundError( "The default markdown parser requires the markdown-it-py package" " to be installed. Install it with `pip install markdown-it`." - ) + ) from None if preset == "commonmark": parser = MarkdownIt("commonmark") diff --git a/shiny/ui/_progress.py b/shiny/ui/_progress.py index 5f5ad764c..61425bad4 100644 --- a/shiny/ui/_progress.py +++ b/shiny/ui/_progress.py @@ -95,7 +95,9 @@ def set( """ if self._closed: - warn("Attempting to set progress, but progress already closed.") + warn( + "Attempting to set progress, but progress already closed.", stacklevel=2 + ) return None self.value = value @@ -164,7 +166,10 @@ def close(self) -> None: Removes the progress panel. Future calls to set and close will be ignored. """ if self._closed: - warn("Attempting to close progress, but progress already closed.") + warn( + "Attempting to close progress, but progress already closed.", + stacklevel=2, + ) return None self._session._send_progress("close", {"id": self._id, "style": self._style}) diff --git a/tests/playwright/shiny/inputs/test_input_switch.py b/tests/playwright/shiny/inputs/test_input_switch.py index 39034bf2f..0fc16a042 100644 --- a/tests/playwright/shiny/inputs/test_input_switch.py +++ b/tests/playwright/shiny/inputs/test_input_switch.py @@ -9,7 +9,6 @@ def test_input_switch_kitchen(page: Page, app: ShinyAppProc) -> None: page.goto(app.url) somevalue = InputSwitch(page, "somevalue") - somevalue.expect_label expect(somevalue.loc_label).to_have_text("Some value") somevalue.expect_label("Some value") From 9142772b92da7a6f4329bea5ddd0555a2c9cf371 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:52:12 -0400 Subject: [PATCH 05/56] flake8-quotes --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 194e4afdc..f7d2e2532 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,8 +73,8 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B"] -# "Q", "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E", "I", "B", "Q"] +# "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 26dec42ba9e18bfb51c29f6499faeb1ae343616c Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:53:26 -0400 Subject: [PATCH 06/56] commas --- ruff.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index f7d2e2532..bbc08e77a 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,8 +73,9 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q"] -# "C90", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E", "I", "B", "Q", "COM"] +# "C90", +# , "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 8de81b25936dbbe590cab0aa6b2e8b908202257d Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:53:59 -0400 Subject: [PATCH 07/56] flake8-comprehensions --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index bbc08e77a..3aa3cdd15 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,9 +73,9 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM"] +extend-select = ["E", "I", "B", "Q", "COM", "C4"] # "C90", -# , "C4", "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From fd4c9d331e647cbb96ae04a5ea084e007ccc7a34 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:59:20 -0400 Subject: [PATCH 08/56] When formatting, fix all lints --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fb9d3ad91..dbff968fc 100644 --- a/Makefile +++ b/Makefile @@ -227,7 +227,7 @@ format-ruff: $(RUFF) FORCE @# Reason for two commands: https://github.com/astral-sh/ruff/issues/8232 @# Fix imports . $(PYBIN)/activate && \ - ruff check --select I --fix . + ruff check --fix . @# Fix formatting . $(PYBIN)/activate && \ ruff format . From cdcb7fb417e8d5e281261f767ee74f4b6e4171d2 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 22:59:39 -0400 Subject: [PATCH 09/56] Add unsafe format target for ruff --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index dbff968fc..644884f93 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,10 @@ format-ruff: $(RUFF) FORCE . $(PYBIN)/activate && \ ruff format . +format-ruff-unsafe: $(RUFF) FORCE + @echo "-------- Formatting code with ruff (unsafe) --------" + . $(PYBIN)/activate && \ + ruff check --fix --unsafe-fixes . # ----------------- # Documentation # ----------------- From 6728a58441ce60198088f28cb58ff4b0775092ab Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:01:39 -0400 Subject: [PATCH 10/56] Auto fix flake8-comprehensions --- examples/brownian/brownian_motion.py | 14 +- examples/brownian/mediapipe.py | 14 +- examples/model-score/app.py | 17 +- shiny/_main.py | 8 +- shiny/_utils.py | 2 +- shiny/api-examples/output_table/app-core.py | 2 +- .../api-examples/output_table/app-express.py | 2 +- .../remove_accordion_panel/app-core.py | 2 +- .../remove_accordion_panel/app-express.py | 2 +- shiny/express/_recall_context.py | 2 +- shiny/express/ui/_cm_components.py | 166 +++++++++--------- shiny/express/ui/_hold.py | 2 +- shiny/reactive/_reactives.py | 4 +- shiny/render/_dataframe.py | 34 ++-- shiny/render/renderer/_renderer.py | 2 +- shiny/render/transformer/_transformer.py | 4 +- shiny/session/_session.py | 4 +- shiny/ui/_input_update.py | 2 +- shiny/ui/_output.py | 2 +- shiny/ui/_plot_output_opts.py | 2 +- tests/playwright/examples/example_apps.py | 8 +- .../shiny/bugs/0676-row-selection/app.py | 10 +- .../shiny/bugs/0696-resolve-id/app.py | 2 +- .../shiny/bugs/0696-resolve-id/check.py | 2 +- .../playwright/shiny/implicit-register/app.py | 12 +- tests/playwright/shiny/plot-sizing/app.py | 2 +- 26 files changed, 159 insertions(+), 164 deletions(-) diff --git a/examples/brownian/brownian_motion.py b/examples/brownian/brownian_motion.py index 92defcba5..408743f8a 100644 --- a/examples/brownian/brownian_motion.py +++ b/examples/brownian/brownian_motion.py @@ -24,7 +24,7 @@ def brownian_data(n=100, mu=(0.0, 0.00), sigma=(0.1, 0.1), S0=(1.0, 1.0)): "x": brownian_motion(T=1, N=n, mu=mu[0], sigma=sigma[0], S0=S0[0]), "y": brownian_motion(T=1, N=n, mu=mu[1], sigma=sigma[1], S0=S0[1]), # "y": [i for i in range(n)], - "z": [i for i in range(n)], + "z": list(range(n)), } @@ -35,12 +35,12 @@ def brownian_widget(width=600, height=600): x=[], y=[], z=[], - marker=dict( - size=4, - color=[], - colorscale="Viridis", - ), - line=dict(color="darkblue", width=2), + marker={ + "size": 4, + "color": [], + "colorscale": "Viridis", + }, + line={"color": "darkblue", "width": 2}, ) ], layout={"showlegend": False, "width": width, "height": height}, diff --git a/examples/brownian/mediapipe.py b/examples/brownian/mediapipe.py index 1a2b6bd98..91f482b60 100644 --- a/examples/brownian/mediapipe.py +++ b/examples/brownian/mediapipe.py @@ -60,8 +60,8 @@ def rel_hand(start_pos: int, end_pos: int): normal_unit_vec = normal_vec / np.linalg.norm(normal_vec) def list_to_xyz(x): - x = list(map(lambda y: round(y, 2), x)) - return dict(x=x[0], y=x[1], z=x[2]) + x = [round(y, 2) for y in x] + return {"x": x[0], "y": x[1], "z": x[2]} # Invert, for some reason normal_unit_vec = normal_unit_vec * -1.0 @@ -82,8 +82,8 @@ def list_to_xyz(x): def xyz_mean(points): - return dict( - x=mean([p["x"] for p in points]), - y=mean([p["y"] for p in points]), - z=mean([p["z"] for p in points]), - ) + return { + "x": mean([p["x"] for p in points]), + "y": mean([p["y"] for p in points]), + "z": mean([p["z"] for p in points]), + } diff --git a/examples/model-score/app.py b/examples/model-score/app.py index 8fe3fcb0b..6c332aca1 100644 --- a/examples/model-score/app.py +++ b/examples/model-score/app.py @@ -71,10 +71,7 @@ def read_time_period(from_time, to_time): model_names = ["model_1", "model_2", "model_3", "model_4"] -model_colors = { - name: color - for name, color in zip(model_names, px.colors.qualitative.D3[0 : len(model_names)]) -} +model_colors = dict(zip(model_names, px.colors.qualitative.D3[0 : len(model_names)])) def app_ui(req): @@ -220,7 +217,7 @@ def plot_timeseries(): filtered_df(), x="time", y="score", - labels=dict(score="accuracy"), + labels={"score": "accuracy"}, color="model", color_discrete_map=model_colors, # The default for render_mode is "auto", which switches between @@ -234,13 +231,13 @@ def plot_timeseries(): fig.add_hline( THRESHOLD_LOW, line_dash="dash", - line=dict(color=THRESHOLD_LOW_COLOR, width=2), + line={"color": THRESHOLD_LOW_COLOR, "width": 2}, opacity=0.3, ) fig.add_hline( THRESHOLD_MID, line_dash="dash", - line=dict(color=THRESHOLD_MID_COLOR, width=2), + line={"color": THRESHOLD_MID_COLOR, "width": 2}, opacity=0.3, ) @@ -256,7 +253,7 @@ def plot_dist(): facet_row="model", nbins=20, x="score", - labels=dict(score="accuracy"), + labels={"score": "accuracy"}, color="model", color_discrete_map=model_colors, template="simple_white", @@ -265,13 +262,13 @@ def plot_dist(): fig.add_vline( THRESHOLD_LOW, line_dash="dash", - line=dict(color=THRESHOLD_LOW_COLOR, width=2), + line={"color": THRESHOLD_LOW_COLOR, "width": 2}, opacity=0.3, ) fig.add_vline( THRESHOLD_MID, line_dash="dash", - line=dict(color=THRESHOLD_MID_COLOR, width=2), + line={"color": THRESHOLD_MID_COLOR, "width": 2}, opacity=0.3, ) diff --git a/shiny/_main.py b/shiny/_main.py index bf61f6899..1bdcf0f6f 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -561,10 +561,10 @@ def create( shinylive export APPDIR DESTDIR """, - context_settings=dict( - ignore_unknown_options=True, - allow_extra_args=True, - ), + context_settings={ + "ignore_unknown_options": True, + "allow_extra_args": True, + }, ) def static() -> None: print( diff --git a/shiny/_utils.py b/shiny/_utils.py index 74daf50e5..5b0f7fe20 100644 --- a/shiny/_utils.py +++ b/shiny/_utils.py @@ -182,7 +182,7 @@ def random_port( 10080, ] - unusable = set([x for x in unsafe_ports if x >= min and x <= max]) + unusable = {x for x in unsafe_ports if x >= min and x <= max} while n > 0: if (max - min + 1) <= len(unusable): break diff --git a/shiny/api-examples/output_table/app-core.py b/shiny/api-examples/output_table/app-core.py index 1dac0bab9..b23415044 100644 --- a/shiny/api-examples/output_table/app-core.py +++ b/shiny/api-examples/output_table/app-core.py @@ -53,7 +53,7 @@ def result(): } ) .set_table_styles( - [dict(selector="th", props=[("text-align", "right")])] + [{"selector": "th", "props": [("text-align", "right")]}] ) .highlight_min(color="silver") .highlight_max(color="yellow") diff --git a/shiny/api-examples/output_table/app-express.py b/shiny/api-examples/output_table/app-express.py index 12d8cb8aa..38cc6abd8 100644 --- a/shiny/api-examples/output_table/app-express.py +++ b/shiny/api-examples/output_table/app-express.py @@ -37,7 +37,7 @@ def result(): "qsec": "{0:0.2f}", } ) - .set_table_styles([dict(selector="th", props=[("text-align", "right")])]) + .set_table_styles([{"selector": "th", "props": [("text-align", "right")]}]) .highlight_min(color="silver") .highlight_max(color="yellow") ) diff --git a/shiny/api-examples/remove_accordion_panel/app-core.py b/shiny/api-examples/remove_accordion_panel/app-core.py index fa51fd56d..0c2caac02 100644 --- a/shiny/api-examples/remove_accordion_panel/app-core.py +++ b/shiny/api-examples/remove_accordion_panel/app-core.py @@ -27,7 +27,7 @@ def make_panel(letter: str) -> ui.AccordionPanel: def server(input: Inputs, output: Outputs, session: Session): # Copy the list for user - user_choices = [choice for choice in choices] + user_choices = list(choices) @reactive.effect @reactive.event(input.remove_panel) diff --git a/shiny/api-examples/remove_accordion_panel/app-express.py b/shiny/api-examples/remove_accordion_panel/app-express.py index d01f643e6..2c1042c57 100644 --- a/shiny/api-examples/remove_accordion_panel/app-express.py +++ b/shiny/api-examples/remove_accordion_panel/app-express.py @@ -20,7 +20,7 @@ f"Some narrative for section {letter}" -user_choices = [choice for choice in choices] +user_choices = list(choices) @reactive.effect diff --git a/shiny/express/_recall_context.py b/shiny/express/_recall_context.py index aad43bb37..3d81712b4 100644 --- a/shiny/express/_recall_context.py +++ b/shiny/express/_recall_context.py @@ -24,7 +24,7 @@ def __init__( ): self.fn = fn if args is None: - args = tuple() + args = () if kwargs is None: kwargs = {} self.args: list[object] = list(args) diff --git a/shiny/express/ui/_cm_components.py b/shiny/express/ui/_cm_components.py index f7ff8386c..e4378211b 100644 --- a/shiny/express/ui/_cm_components.py +++ b/shiny/express/ui/_cm_components.py @@ -656,12 +656,12 @@ def navset_tab( """ return RecallContextManager( ui.navset_tab, - kwargs=dict( - id=id, - selected=selected, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "header": header, + "footer": footer, + }, ) @@ -693,12 +693,12 @@ def navset_pill( """ return RecallContextManager( ui.navset_pill, - kwargs=dict( - id=id, - selected=selected, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "header": header, + "footer": footer, + }, ) @@ -731,12 +731,12 @@ def navset_underline( """ return RecallContextManager( ui.navset_underline, - kwargs=dict( - id=id, - selected=selected, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "header": header, + "footer": footer, + }, ) @@ -768,12 +768,12 @@ def navset_hidden( """ return RecallContextManager( ui.navset_hidden, - kwargs=dict( - id=id, - selected=selected, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "header": header, + "footer": footer, + }, ) @@ -809,14 +809,14 @@ def navset_card_tab( """ return RecallContextManager( ui.navset_card_tab, - kwargs=dict( - id=id, - selected=selected, - title=title, - sidebar=sidebar, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "title": title, + "sidebar": sidebar, + "header": header, + "footer": footer, + }, ) @@ -852,14 +852,14 @@ def navset_card_pill( """ return RecallContextManager( ui.navset_card_pill, - kwargs=dict( - id=id, - selected=selected, - title=title, - sidebar=sidebar, - header=header, - footer=footer, - ), + kwargs={ + "id": id, + "selected": selected, + "title": title, + "sidebar": sidebar, + "header": header, + "footer": footer, + }, ) @@ -898,15 +898,15 @@ def navset_card_underline( """ return RecallContextManager( ui.navset_card_underline, - kwargs=dict( - id=id, - selected=selected, - title=title, - sidebar=sidebar, - header=header, - footer=footer, - placement=placement, - ), + kwargs={ + "id": id, + "selected": selected, + "title": title, + "sidebar": sidebar, + "header": header, + "footer": footer, + "placement": placement, + }, ) @@ -944,14 +944,14 @@ def navset_pill_list( """ return RecallContextManager( ui.navset_pill_list, - kwargs=dict( - id=id, - selected=selected, - header=header, - footer=footer, - well=well, - widths=widths, - ), + kwargs={ + "id": id, + "selected": selected, + "header": header, + "footer": footer, + "well": well, + "widths": widths, + }, ) @@ -1034,23 +1034,23 @@ def navset_bar( """ return RecallContextManager( ui.navset_bar, - kwargs=dict( - title=title, - id=id, - selected=selected, - sidebar=sidebar, - fillable=fillable, - gap=gap, - padding=padding, - position=position, - header=header, - footer=footer, - bg=bg, - inverse=inverse, - underline=underline, - collapsible=collapsible, - fluid=fluid, - ), + kwargs={ + "title": title, + "id": id, + "selected": selected, + "sidebar": sidebar, + "fillable": fillable, + "gap": gap, + "padding": padding, + "position": position, + "header": header, + "footer": footer, + "bg": bg, + "inverse": inverse, + "underline": underline, + "collapsible": collapsible, + "fluid": fluid, + }, ) @@ -1082,10 +1082,10 @@ def nav_panel( return RecallContextManager( ui.nav_panel, args=(title,), - kwargs=dict( - value=value, - icon=icon, - ), + kwargs={ + "value": value, + "icon": icon, + }, ) @@ -1131,11 +1131,11 @@ def nav_menu( return RecallContextManager( ui.nav_menu, args=(title,), - kwargs=dict( - value=value, - icon=icon, - align=align, - ), + kwargs={ + "value": value, + "icon": icon, + "align": align, + }, ) diff --git a/shiny/express/ui/_hold.py b/shiny/express/ui/_hold.py index b6fe8d295..1f83a04d3 100644 --- a/shiny/express/ui/_hold.py +++ b/shiny/express/ui/_hold.py @@ -46,7 +46,7 @@ def hold() -> HoldContextManager: class HoldContextManager: def __init__(self): - self.content: list[object] = list() + self.content: list[object] = [] def __enter__(self) -> list[object]: self.prev_displayhook = sys.displayhook diff --git a/shiny/reactive/_reactives.py b/shiny/reactive/_reactives.py index f82658d09..eb4de0ffc 100644 --- a/shiny/reactive/_reactives.py +++ b/shiny/reactive/_reactives.py @@ -794,7 +794,7 @@ def event( ``@render.ui``, etc). """ - if any([not callable(arg) for arg in args]): + if any(not callable(arg) for arg in args): raise TypeError( "All objects passed to event decorator must be callable.\n" + "If you are calling `@reactive.event(f())`, try calling `@reactive.event(f)` instead." @@ -862,7 +862,7 @@ async def new_user_async_fn(): return new_user_async_fn # type: ignore - elif any([is_async_callable(arg) for arg in args]): + elif any(is_async_callable(arg) for arg in args): raise TypeError( "When decorating a synchronous function with @reactive.event(), all" + "arguments to @reactive.event() must be synchronous functions." diff --git a/shiny/render/_dataframe.py b/shiny/render/_dataframe.py index 16c0509f3..b3c3daa67 100644 --- a/shiny/render/_dataframe.py +++ b/shiny/render/_dataframe.py @@ -96,15 +96,15 @@ def __init__( def to_payload(self) -> Jsonifiable: res = serialize_pandas_df(self.data) - res["options"] = dict( - width=self.width, - height=self.height, - summary=self.summary, - filters=self.filters, - row_selection_mode=self.row_selection_mode, - style="grid", - fill=self.height is None, - ) + res["options"] = { + "width": self.width, + "height": self.height, + "summary": self.summary, + "filters": self.filters, + "row_selection_mode": self.row_selection_mode, + "style": "grid", + "fill": self.height is None, + } return res @@ -186,14 +186,14 @@ def __init__( def to_payload(self) -> Jsonifiable: res = serialize_pandas_df(self.data) - res["options"] = dict( - width=self.width, - height=self.height, - summary=self.summary, - filters=self.filters, - row_selection_mode=self.row_selection_mode, - style="table", - ) + res["options"] = { + "width": self.width, + "height": self.height, + "summary": self.summary, + "filters": self.filters, + "row_selection_mode": self.row_selection_mode, + "style": "table", + } return res diff --git a/shiny/render/renderer/_renderer.py b/shiny/render/renderer/_renderer.py index ba4b28d88..a1b8fe3b3 100644 --- a/shiny/render/renderer/_renderer.py +++ b/shiny/render/renderer/_renderer.py @@ -137,7 +137,7 @@ class Renderer(Generic[IT]): # Q: Could we do this with typing without putting `P` in the Generic? # A: No. Even if we had a `P` in the Generic, the calling decorator would not have access to it. # Idea: Possibly use a chained method of `.ui_kwargs()`? https://github.com/posit-dev/py-shiny/issues/971 - _auto_output_ui_kwargs: dict[str, Any] = dict() + _auto_output_ui_kwargs: dict[str, Any] = {} __name__: str """ diff --git a/shiny/render/transformer/_transformer.py b/shiny/render/transformer/_transformer.py index 1476e1679..5b49b5846 100644 --- a/shiny/render/transformer/_transformer.py +++ b/shiny/render/transformer/_transformer.py @@ -263,8 +263,8 @@ def __init__( self._default_ui = default_ui self._default_ui_passthrough_args = default_ui_passthrough_args - self._default_ui_args: tuple[object, ...] = tuple() - self._default_ui_kwargs: dict[str, object] = dict() + self._default_ui_args: tuple[object, ...] = () + self._default_ui_kwargs: dict[str, object] = {} # Allow for App authors to not require `@output` self._auto_register() diff --git a/shiny/session/_session.py b/shiny/session/_session.py index 1f401d5cc..1d6688be7 100644 --- a/shiny/session/_session.py +++ b/shiny/session/_session.py @@ -190,8 +190,8 @@ def __init__( # query information about the request, like headers, cookies, etc. self.http_conn: HTTPConnection = conn.get_http_conn() - self.input: Inputs = Inputs(dict()) - self.output: Outputs = Outputs(self, self.ns, dict(), dict()) + self.input: Inputs = Inputs({}) + self.output: Outputs = Outputs(self, self.ns, {}, {}) self.user: str | None = None self.groups: list[str] | None = None diff --git a/shiny/ui/_input_update.py b/shiny/ui/_input_update.py index e7c8a7760..d6aaed821 100644 --- a/shiny/ui/_input_update.py +++ b/shiny/ui/_input_update.py @@ -751,7 +751,7 @@ def selectize_choices_json(request: Request) -> Response: if isinstance(search_fields[0], list): search_fields = search_fields[0] - if set(search_fields).difference(set(["label", "value", "optgroup"])): + if set(search_fields).difference({"label", "value", "optgroup"}): raise ValueError( "The selectize.js searchFields option must contain some combination of: " + "'label', 'value', and 'optgroup'" diff --git a/shiny/ui/_output.py b/shiny/ui/_output.py index 2b21ae193..a509076dc 100644 --- a/shiny/ui/_output.py +++ b/shiny/ui/_output.py @@ -195,7 +195,7 @@ def output_image( height = f"{height}px" if isinstance(height, (float, int)) else height style = None if inline else css(width=width, height=height) - args: dict[str, str] = dict() + args: dict[str, str] = {} id_resolved = resolve_id(id) diff --git a/shiny/ui/_plot_output_opts.py b/shiny/ui/_plot_output_opts.py index d9c542b8b..c1e387d7d 100644 --- a/shiny/ui/_plot_output_opts.py +++ b/shiny/ui/_plot_output_opts.py @@ -44,7 +44,7 @@ def format_opt_names( opts: ClickOpts | DblClickOpts | HoverOpts | BrushOpts, prefix: str, ) -> dict[str, str]: - new_opts: dict[str, str] = dict() + new_opts: dict[str, str] = {} for key, value in opts.items(): new_key = f"data-{prefix}-" + re.sub("([A-Z])", "-\\1", key).lower() new_value = str(value) diff --git a/tests/playwright/examples/example_apps.py b/tests/playwright/examples/example_apps.py index 296c64f31..47d87cebb 100644 --- a/tests/playwright/examples/example_apps.py +++ b/tests/playwright/examples/example_apps.py @@ -193,7 +193,7 @@ def on_console_msg(msg: ConsoleMessage) -> None: error_lines = [ line for line in error_lines - if not any([error_txt in line for error_txt in app_allow_external_errors]) + if not any(error_txt in line for error_txt in app_allow_external_errors) ] # Remove any app specific errors that are allowed @@ -220,7 +220,7 @@ def on_console_msg(msg: ConsoleMessage) -> None: line for line in error_lines if len(line.strip()) > 0 - and not any([error_txt in line for error_txt in app_allowable_errors]) + and not any(error_txt in line for error_txt in app_allowable_errors) ] if len(error_lines) > 0: print("\nshort_app_path: " + short_app_path) @@ -237,10 +237,8 @@ def on_console_msg(msg: ConsoleMessage) -> None: line for line in console_errors if not any( - [ - error_txt in line + error_txt in line for error_txt in app_allow_js_errors[short_app_path] - ] ) ] assert len(console_errors) == 0, ( diff --git a/tests/playwright/shiny/bugs/0676-row-selection/app.py b/tests/playwright/shiny/bugs/0676-row-selection/app.py index 1c8fee0fd..cea93bd41 100644 --- a/tests/playwright/shiny/bugs/0676-row-selection/app.py +++ b/tests/playwright/shiny/bugs/0676-row-selection/app.py @@ -7,11 +7,11 @@ from shiny import App, Inputs, Outputs, Session, render, ui df = pd.DataFrame( - dict( - id=["one", "two", "three"], - fname=["Alice", "Bob", "Charlie"], - lname=["Smith", "Jones", "Brown"], - ) + { + "id": ["one", "two", "three"], + "fname": ["Alice", "Bob", "Charlie"], + "lname": ["Smith", "Jones", "Brown"], + } ).set_index( # type: ignore "id", drop=False, diff --git a/tests/playwright/shiny/bugs/0696-resolve-id/app.py b/tests/playwright/shiny/bugs/0696-resolve-id/app.py index 5e0af336e..c7e45667f 100644 --- a/tests/playwright/shiny/bugs/0696-resolve-id/app.py +++ b/tests/playwright/shiny/bugs/0696-resolve-id/app.py @@ -31,7 +31,7 @@ img_path = pathlib.Path(__file__).parent / "imgs" penguin_imgs = [str(img_path / img) for img in os.listdir(img_path)] assert len(penguin_imgs) > 0 -letters = [letter for letter in "abcdefghijklmnopqrstuvwxyz"][: len(penguin_imgs)] +letters = list("abcdefghijklmnopqrstuvwxyz")[: len(penguin_imgs)] input_keys = ( "input_action_button", diff --git a/tests/playwright/shiny/bugs/0696-resolve-id/check.py b/tests/playwright/shiny/bugs/0696-resolve-id/check.py index 60801f94e..0d2e7919e 100644 --- a/tests/playwright/shiny/bugs/0696-resolve-id/check.py +++ b/tests/playwright/shiny/bugs/0696-resolve-id/check.py @@ -48,7 +48,7 @@ class ModState(NamedTuple): navset_tab: str -blacklist = set(["awesome_component"]) +blacklist = {"awesome_component"} x_input_keys = ("x_" + key for key in x_input_keys) diff --git a/tests/playwright/shiny/implicit-register/app.py b/tests/playwright/shiny/implicit-register/app.py index eb88220a1..7bb6d7ecd 100644 --- a/tests/playwright/shiny/implicit-register/app.py +++ b/tests/playwright/shiny/implicit-register/app.py @@ -1,11 +1,11 @@ from shiny import App, Inputs, Outputs, Session, render, ui -scenarios = dict( - out1="The following output should be empty", - out2='The following output should have the word "One"', - out3='The following output should have the word "Two"', - out4='The following output should also have the word "Two"', -) +scenarios = { + "out1": "The following output should be empty", + "out2": 'The following output should have the word "One"', + "out3": 'The following output should have the word "Two"', + "out4": 'The following output should also have the word "Two"', +} app_ui = ui.page_fluid( [ diff --git a/tests/playwright/shiny/plot-sizing/app.py b/tests/playwright/shiny/plot-sizing/app.py index 646fe7fe4..83a0c0c93 100644 --- a/tests/playwright/shiny/plot-sizing/app.py +++ b/tests/playwright/shiny/plot-sizing/app.py @@ -111,7 +111,7 @@ def plot_with_mpl(fig_size: tuple[float, float] | None) -> object: return fig def plot_with_sns(fig_size: tuple[float, float] | None) -> object: - kwargs = dict() + kwargs = {} if fig_size: kwargs["height"] = fig_size[1] / dpi kwargs["aspect"] = fig_size[0] / fig_size[1] From e55f7f62cbd3bb676b648df4044466e31768492a Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:08:00 -0400 Subject: [PATCH 11/56] flake8-future-annotations --- ruff.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 3aa3cdd15..8bfaa433d 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,9 +73,9 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4"] -# "C90", -# "DTZ", "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA"] +# "C90", "DTZ" +# "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 33426a197a84e93cabe14cfee9226bcf6e813c13 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:16:03 -0400 Subject: [PATCH 12/56] Only use FA102 --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 8bfaa433d..58a98fae7 100644 --- a/ruff.toml +++ b/ruff.toml @@ -54,7 +54,7 @@ extend-ignore = [ # COM; Commas: https://docs.astral.sh/ruff/rules/#flake8-commas-com # C4; flake8-comprehensions: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 # DTZ; flake8-datetimez: https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz -# FA; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa +# FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa # ISC; flake8-s=implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn # G; flake8-logging-format: https://docs.astral.sh/ruff/rules/#flake8-logging-format-g @@ -73,7 +73,7 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA"] +extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102"] # "C90", "DTZ" # "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] From a6ba3229a280712b8743121ecf1819a9d2aad59b Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:16:29 -0400 Subject: [PATCH 13/56] Auto fix FA102 --- scripts/generate-imports.py | 1 + shiny/_typing_extensions.py | 1 + shiny/api-examples/input_file/app-core.py | 2 ++ shiny/api-examples/input_file/app-express.py | 2 ++ shiny/api-examples/notification_show/app-core.py | 2 ++ shiny/api-examples/notification_show/app-express.py | 2 ++ tests/playwright/examples/example_apps.py | 2 +- tests/playwright/shiny/inputs/input_file/app.py | 2 ++ tests/pytest/test_reactives.py | 2 ++ tests/pytest/test_utils_async.py | 2 ++ 10 files changed, 17 insertions(+), 1 deletion(-) diff --git a/scripts/generate-imports.py b/scripts/generate-imports.py index a3bfc7f15..a11d836dd 100755 --- a/scripts/generate-imports.py +++ b/scripts/generate-imports.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +from __future__ import annotations import importlib import sys diff --git a/shiny/_typing_extensions.py b/shiny/_typing_extensions.py index 39cc1ac29..28bcf8422 100644 --- a/shiny/_typing_extensions.py +++ b/shiny/_typing_extensions.py @@ -1,6 +1,7 @@ # # Within file flags to ignore unused imports # flake8: noqa: F401 # pyright: reportUnusedImport=false +from __future__ import annotations __all__ = ( "Concatenate", diff --git a/shiny/api-examples/input_file/app-core.py b/shiny/api-examples/input_file/app-core.py index 4cd0d99ee..937889f22 100644 --- a/shiny/api-examples/input_file/app-core.py +++ b/shiny/api-examples/input_file/app-core.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pandas as pd from shiny import App, Inputs, Outputs, Session, reactive, render, ui diff --git a/shiny/api-examples/input_file/app-express.py b/shiny/api-examples/input_file/app-express.py index 6a035a555..243c09f52 100644 --- a/shiny/api-examples/input_file/app-express.py +++ b/shiny/api-examples/input_file/app-express.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pandas as pd from shiny import reactive diff --git a/shiny/api-examples/notification_show/app-core.py b/shiny/api-examples/notification_show/app-core.py index 2f8e3a056..216bbe434 100644 --- a/shiny/api-examples/notification_show/app-core.py +++ b/shiny/api-examples/notification_show/app-core.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from shiny import App, Inputs, Outputs, Session, reactive, ui app_ui = ui.page_fluid( diff --git a/shiny/api-examples/notification_show/app-express.py b/shiny/api-examples/notification_show/app-express.py index d64a57431..e92050a85 100644 --- a/shiny/api-examples/notification_show/app-express.py +++ b/shiny/api-examples/notification_show/app-express.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from shiny import reactive from shiny.express import input, ui diff --git a/tests/playwright/examples/example_apps.py b/tests/playwright/examples/example_apps.py index 47d87cebb..1ce27a124 100644 --- a/tests/playwright/examples/example_apps.py +++ b/tests/playwright/examples/example_apps.py @@ -238,7 +238,7 @@ def on_console_msg(msg: ConsoleMessage) -> None: for line in console_errors if not any( error_txt in line - for error_txt in app_allow_js_errors[short_app_path] + for error_txt in app_allow_js_errors[short_app_path] ) ] assert len(console_errors) == 0, ( diff --git a/tests/playwright/shiny/inputs/input_file/app.py b/tests/playwright/shiny/inputs/input_file/app.py index af92f9c55..2706d23be 100644 --- a/tests/playwright/shiny/inputs/input_file/app.py +++ b/tests/playwright/shiny/inputs/input_file/app.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import typing import pandas as pd diff --git a/tests/pytest/test_reactives.py b/tests/pytest/test_reactives.py index 4edaa4841..d5744ef3e 100644 --- a/tests/pytest/test_reactives.py +++ b/tests/pytest/test_reactives.py @@ -1,5 +1,7 @@ """Tests for `shiny.reactive`.""" +from __future__ import annotations + import asyncio from typing import List diff --git a/tests/pytest/test_utils_async.py b/tests/pytest/test_utils_async.py index dd03f98d5..2ef3c7194 100644 --- a/tests/pytest/test_utils_async.py +++ b/tests/pytest/test_utils_async.py @@ -1,5 +1,7 @@ """Tests for `shiny.utils` async-related functions.""" +from __future__ import annotations + import asyncio import contextvars from typing import Iterator, List From acd766c1977745ba7f89d7916c4fa68fb8090fde Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:17:34 -0400 Subject: [PATCH 14/56] flake8-implicit-str-concat --- ruff.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 58a98fae7..c38341697 100644 --- a/ruff.toml +++ b/ruff.toml @@ -55,7 +55,7 @@ extend-ignore = [ # C4; flake8-comprehensions: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 # DTZ; flake8-datetimez: https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz # FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa -# ISC; flake8-s=implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc +# ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn # G; flake8-logging-format: https://docs.astral.sh/ruff/rules/#flake8-logging-format-g # PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie @@ -73,9 +73,9 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102"] +extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC"] # "C90", "DTZ" -# "FA", "ISC", "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From d2b3d256170cb22cb0edb9363042f27c2663fdf0 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:20:32 -0400 Subject: [PATCH 15/56] Manually fix flake8-implicit-str-concat errors --- shiny/_docstring.py | 2 +- shiny/reactive/_reactives.py | 16 ++++++++-------- shiny/render/_render.py | 4 ++-- shiny/render/_try_render_plot.py | 4 ++-- shiny/session/_session.py | 2 +- shiny/ui/_input_update.py | 2 +- shiny/ui/_sidebar.py | 8 ++++---- tests/playwright/controls.py | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/shiny/_docstring.py b/shiny/_docstring.py index 9c6578c30..1cd6b8f0d 100644 --- a/shiny/_docstring.py +++ b/shiny/_docstring.py @@ -238,7 +238,7 @@ def __str__(self): return ( f"Could not find {type} example file named " - + f"{' or '.join(self.file_names)} in {self.dir}." + f"{' or '.join(self.file_names)} in {self.dir}." ) diff --git a/shiny/reactive/_reactives.py b/shiny/reactive/_reactives.py index eb4de0ffc..5c7b1498c 100644 --- a/shiny/reactive/_reactives.py +++ b/shiny/reactive/_reactives.py @@ -483,7 +483,7 @@ def __init__( if isinstance(fn, Renderer): raise TypeError( "`@reactive.effect` can not be combined with `@render.xx`.\n" - + "Please remove your call of `@reactive.effect`." + "Please remove your call of `@reactive.effect`." ) # The EffectAsync subclass will pass in an async function, but it tells the @@ -797,7 +797,7 @@ def event( if any(not callable(arg) for arg in args): raise TypeError( "All objects passed to event decorator must be callable.\n" - + "If you are calling `@reactive.event(f())`, try calling `@reactive.event(f)` instead." + "If you are calling `@reactive.event(f())`, try calling `@reactive.event(f)` instead." ) if len(args) == 0: @@ -809,14 +809,14 @@ def decorator(user_fn: Callable[[], T]) -> Callable[[], T]: if not callable(user_fn): raise TypeError( "`@reactive.event()` must be applied to a function or Callable object.\n" - + "It should usually be applied before `@Calc`,` @Effect`, or `@render.xx` function.\n" - + "In other words, `@reactive.event()` goes below the other decorators." + "It should usually be applied before `@Calc`,` @Effect`, or `@render.xx` function.\n" + "In other words, `@reactive.event()` goes below the other decorators." ) if isinstance(user_fn, Calc_): raise TypeError( "`@reactive.event()` must be applied before `@reactive.calc`.\n" - + "In other words, `@reactive.calc` must be above `@reactive.event()`." + "In other words, `@reactive.calc` must be above `@reactive.event()`." ) # This is here instead of at the top of the .py file in order to avoid a @@ -828,7 +828,7 @@ def decorator(user_fn: Callable[[], T]) -> Callable[[], T]: # use case. For now we'll disallow it, for simplicity. raise TypeError( "`@reactive.event()` must be applied before `@render.xx` .\n" - + "In other words, `@render.xx` must be above `@reactive.event()`." + "In other words, `@render.xx` must be above `@reactive.event()`." ) initialized = False @@ -864,8 +864,8 @@ async def new_user_async_fn(): elif any(is_async_callable(arg) for arg in args): raise TypeError( - "When decorating a synchronous function with @reactive.event(), all" - + "arguments to @reactive.event() must be synchronous functions." + "When decorating a synchronous function with @reactive.event(), all " + "arguments to @reactive.event() must be synchronous functions." ) else: diff --git a/shiny/render/_render.py b/shiny/render/_render.py index af4c30c95..72447fcf4 100644 --- a/shiny/render/_render.py +++ b/shiny/render/_render.py @@ -384,8 +384,8 @@ def cast_result(result: ImgData | None) -> dict[str, Jsonifiable] | None: raise Exception( f"@render.plot doesn't know to render objects of type '{str(type(x))}'. " - + "Consider either requesting support for this type of plot object, and/or " - + " explictly saving the object to a (png) file and using @render.image." + "Consider either requesting support for this type of plot object, and/or " + " explictly saving the object to a (png) file and using @render.image." ) diff --git a/shiny/render/_try_render_plot.py b/shiny/render/_try_render_plot.py index c54789fc1..661204afd 100644 --- a/shiny/render/_try_render_plot.py +++ b/shiny/render/_try_render_plot.py @@ -258,8 +258,8 @@ def get_matplotlib_figure(x: object, allow_global: bool) -> Figure | None: # py if isinstance(x, Animation): raise RuntimeError( "Matplotlib's Animation class isn't supported by @render.plot. " - + "Consider explictly saving the animation to a file and " - + "then using @render.image instead to render it." + "Consider explictly saving the animation to a file and " + "then using @render.image instead to render it." ) # Libraries like pandas, xarray, etc have plot() methods that can return a wide diff --git a/shiny/session/_session.py b/shiny/session/_session.py index 1d6688be7..fb3911703 100644 --- a/shiny/session/_session.py +++ b/shiny/session/_session.py @@ -1064,7 +1064,7 @@ def set_renderer(renderer: RendererT) -> RendererT: if not isinstance(renderer, Renderer): raise TypeError( "`@output` must be applied to a `@render.xx` function.\n" - + "In other words, `@output` must be above `@render.xx`." + "In other words, `@output` must be above `@render.xx`." ) # Get the (possibly namespaced) output id diff --git a/shiny/ui/_input_update.py b/shiny/ui/_input_update.py index d6aaed821..c3c347546 100644 --- a/shiny/ui/_input_update.py +++ b/shiny/ui/_input_update.py @@ -754,7 +754,7 @@ def selectize_choices_json(request: Request) -> Response: if set(search_fields).difference({"label", "value", "optgroup"}): raise ValueError( "The selectize.js searchFields option must contain some combination of: " - + "'label', 'value', and 'optgroup'" + "'label', 'value', and 'optgroup'" ) # i.e. valueField (defaults to 'value') diff --git a/shiny/ui/_sidebar.py b/shiny/ui/_sidebar.py index bff18727e..2baec5b6a 100644 --- a/shiny/ui/_sidebar.py +++ b/shiny/ui/_sidebar.py @@ -138,7 +138,7 @@ def _as_open( raise ValueError( f"""`open` must be one of {SidebarOpen._values_str()}, """ - + "or a dictionary with keys `desktop` and `mobile` using these values." + "or a dictionary with keys `desktop` and `mobile` using these values." ) @@ -321,9 +321,9 @@ def max_height_mobile(self) -> Optional[str]: if max_height_mobile is not None and self.open().mobile != "always": warnings.warn( "The `shiny.ui.sidebar(max_height_mobile=)` argument only applies to " - + "the sidebar when `open` is `'always'` on mobile, but " - + f"`open` is `'{self.open().mobile}'`. " - + "The `max_height_mobile` argument will be ignored.", + "the sidebar when `open` is `'always'` on mobile, but " + f"`open` is `'{self.open().mobile}'`. " + "The `max_height_mobile` argument will be ignored.", # `stacklevel=2`: Refers to the caller of `.max_height_mobile` property method stacklevel=2, ) diff --git a/tests/playwright/controls.py b/tests/playwright/controls.py index 1d3e5490e..2e5200d5b 100644 --- a/tests/playwright/controls.py +++ b/tests/playwright/controls.py @@ -1685,7 +1685,7 @@ def slow_move(x: float, y: float, delay: float = sleep_time) -> None: values_found_txt = ", ".join([f'"{key}"' for key in key_arr]) raise ValueError( f"Could not find value '{value}' when moving slider from {error_msg_direction}\n" - + f"Values found:\n{values_found_txt}{trail_txt}" + f"Values found:\n{values_found_txt}{trail_txt}" ) def _grid_bb(self, *, timeout: Timeout = None) -> FloatRect: From eeb42c4ccd24ed10521a1b15be9fbea50943c4da Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:21:48 -0400 Subject: [PATCH 16/56] flake8-import-conventions --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index c38341697..a0550fa04 100644 --- a/ruff.toml +++ b/ruff.toml @@ -73,9 +73,9 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC"] +extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN"] # "C90", "DTZ" -# "ICN", "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 3bf439123ac016307ce834061234898d80860890 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:26:05 -0400 Subject: [PATCH 17/56] Fix flake8-import-conventions errors --- examples/cpuinfo/app.py | 4 ++-- shiny/api-examples/data_frame/app-core.py | 2 +- shiny/api-examples/data_frame/app-express.py | 2 +- shiny/render/_render.py | 4 ++-- shiny/render/_try_render_plot.py | 5 ++--- tests/playwright/deploys/plotly/app.py | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/cpuinfo/app.py b/examples/cpuinfo/app.py index 7cf934283..219fe1211 100644 --- a/examples/cpuinfo/app.py +++ b/examples/cpuinfo/app.py @@ -8,7 +8,7 @@ from math import ceil -import matplotlib +import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import pandas as pd @@ -17,7 +17,7 @@ # The agg matplotlib backend seems to be a little more efficient than the default when # running on macOS, and also gives more consistent results across operating systems -matplotlib.use("agg") +mpl.use("agg") # max number of samples to retain MAX_SAMPLES = 1000 diff --git a/shiny/api-examples/data_frame/app-core.py b/shiny/api-examples/data_frame/app-core.py index a592ef238..0f27aa96f 100644 --- a/shiny/api-examples/data_frame/app-core.py +++ b/shiny/api-examples/data_frame/app-core.py @@ -1,4 +1,4 @@ -import pandas # noqa: F401 (this line needed for Shinylive to load plotly.express) +import pandas as pd # noqa: F401 (this line needed for Shinylive to load plotly.express) import plotly.express as px from shinywidgets import output_widget, render_widget diff --git a/shiny/api-examples/data_frame/app-express.py b/shiny/api-examples/data_frame/app-express.py index 24a5b47ba..98644c0d9 100644 --- a/shiny/api-examples/data_frame/app-express.py +++ b/shiny/api-examples/data_frame/app-express.py @@ -1,4 +1,4 @@ -import pandas # noqa: F401 (this line needed for Shinylive to load plotly.express) +import pandas as pd # noqa: F401 (this line needed for Shinylive to load plotly.express) import plotly.express as px from shinywidgets import render_widget diff --git a/shiny/render/_render.py b/shiny/render/_render.py index 72447fcf4..e333074af 100644 --- a/shiny/render/_render.py +++ b/shiny/render/_render.py @@ -535,7 +535,7 @@ def __init__( # TODO: deal with kwargs collision with output_table async def transform(self, value: TableResult) -> dict[str, Jsonifiable]: - import pandas + import pandas as pd import pandas.io.formats.style html: str @@ -545,7 +545,7 @@ async def transform(self, value: TableResult) -> dict[str, Jsonifiable]: value.to_html(**self.kwargs), # pyright: ignore ) else: - if not isinstance(value, pandas.DataFrame): + if not isinstance(value, pd.DataFrame): if not isinstance(value, PandasCompatible): raise TypeError( "@render.table doesn't know how to render objects of type " diff --git a/shiny/render/_try_render_plot.py b/shiny/render/_try_render_plot.py index 661204afd..943087407 100644 --- a/shiny/render/_try_render_plot.py +++ b/shiny/render/_try_render_plot.py @@ -137,7 +137,6 @@ def try_render_matplotlib( return (False, None) try: - import matplotlib import matplotlib.pyplot as plt # pyright: ignore[reportUnusedImport] # noqa: F401 pixelratio = plot_size_info.pixelratio @@ -226,9 +225,9 @@ def try_render_matplotlib( return (True, res) finally: - import matplotlib.pyplot + import matplotlib.pyplot as plt - matplotlib.pyplot.close(fig) # pyright: ignore[reportUnknownMemberType] + plt.close(fig) # pyright: ignore[reportUnknownMemberType] def get_matplotlib_figure(x: object, allow_global: bool) -> Figure | None: # pyright: ignore diff --git a/tests/playwright/deploys/plotly/app.py b/tests/playwright/deploys/plotly/app.py index bf90aa3f7..d36e1429f 100644 --- a/tests/playwright/deploys/plotly/app.py +++ b/tests/playwright/deploys/plotly/app.py @@ -1,5 +1,5 @@ # App altered from: https://github.com/rstudio/py-shiny/blob/main/shiny/api-examples/data_frame/app.py -import pandas # noqa: F401 (this line needed for Shinylive to load plotly.express) +import pandas as pd # noqa: F401 (this line needed for Shinylive to load plotly.express) import plotly.express as px import plotly.graph_objs as go from shinywidgets import output_widget, render_widget From a8a1e65184d0ce42ab7110e22bcb256d360f983e Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:29:58 -0400 Subject: [PATCH 18/56] Do not use flake8-logging-format --- ruff.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index a0550fa04..752ce927d 100644 --- a/ruff.toml +++ b/ruff.toml @@ -57,7 +57,6 @@ extend-ignore = [ # FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa # ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn -# G; flake8-logging-format: https://docs.astral.sh/ruff/rules/#flake8-logging-format-g # PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie # T20; flake8-print: https://docs.astral.sh/ruff/rules/#flake8-print-t20 # PYI013; flake8-pyi Non-empty class body must not contain `...`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi @@ -74,8 +73,9 @@ extend-ignore = [ # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN"] -# "C90", "DTZ" -# "G", "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "C90" - Many false positives +# "DTZ" - dates with timezones are different from dates without timezones +# "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From e02c851709864ca01bb8ac9f4f3f65ce257f0cea Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:31:18 -0400 Subject: [PATCH 19/56] flake8-pie --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 752ce927d..a390496f1 100644 --- a/ruff.toml +++ b/ruff.toml @@ -72,10 +72,10 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN"] +extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN", "PIE"] # "C90" - Many false positives # "DTZ" - dates with timezones are different from dates without timezones -# "PIE", "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From c789b63fc45eac1bb8981fa315c42b5ef817fdd7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:31:23 -0400 Subject: [PATCH 20/56] Fix flake8-pie --- examples/cpuinfo/app.py | 2 +- shiny/_connection.py | 1 - shiny/_custom_component_template_questions.py | 5 +---- shiny/experimental/ui/_deprecated.py | 1 - shiny/session/_session.py | 1 - shiny/types.py | 3 --- shiny/ui/_valuebox.py | 2 +- tests/playwright/controls.py | 1 - 8 files changed, 3 insertions(+), 13 deletions(-) diff --git a/examples/cpuinfo/app.py b/examples/cpuinfo/app.py index 219fe1211..37d788b43 100644 --- a/examples/cpuinfo/app.py +++ b/examples/cpuinfo/app.py @@ -166,7 +166,7 @@ def plot(): ncols=ncols, squeeze=False, ) - for i in range(0, ncols * nrows): + for i in range(ncols * nrows): row = i // ncols col = i % ncols axes = axeses[row, col] diff --git a/shiny/_connection.py b/shiny/_connection.py index 1f360d551..430e70ff8 100644 --- a/shiny/_connection.py +++ b/shiny/_connection.py @@ -138,4 +138,3 @@ def get_http_conn(self) -> HTTPConnection: class ConnectionClosed(Exception): """Raised when a Connection is closed from the other side.""" - pass diff --git a/shiny/_custom_component_template_questions.py b/shiny/_custom_component_template_questions.py index 00e64e4b0..9670de68e 100644 --- a/shiny/_custom_component_template_questions.py +++ b/shiny/_custom_component_template_questions.py @@ -62,10 +62,7 @@ def validate(self, document: Document): # Check for quotations if ( - name.startswith('"') - or name.endswith('"') - or name.startswith("'") - or name.endswith("'") + name.startswith(('"', "'")) or name.endswith(('"', "'")) ): raise ValidationError( message="The name should be unquoted.", diff --git a/shiny/experimental/ui/_deprecated.py b/shiny/experimental/ui/_deprecated.py index e35a0dcbd..782656efc 100644 --- a/shiny/experimental/ui/_deprecated.py +++ b/shiny/experimental/ui/_deprecated.py @@ -727,7 +727,6 @@ class AccordionPanel(MainAccordionPanel): Deprecated. Please use `shiny.ui.AccordionPanel` instead. """ - ... # Deprecated 2023-09-12 diff --git a/shiny/session/_session.py b/shiny/session/_session.py index fb3911703..fa0d954b9 100644 --- a/shiny/session/_session.py +++ b/shiny/session/_session.py @@ -677,7 +677,6 @@ def _send_message_sync(self, message: dict[str, object]) -> None: def _send_error_response(self, message_str: str) -> None: print("_send_error_response: " + message_str) - pass # ========================================================================== # Flush diff --git a/shiny/types.py b/shiny/types.py index 89a22ac68..14a07bcd9 100644 --- a/shiny/types.py +++ b/shiny/types.py @@ -90,7 +90,6 @@ class SafeException(Exception): generate an error that is OK to be displayed to the user. """ - pass @add_example() @@ -113,7 +112,6 @@ class SilentException(Exception): * :class:`~shiny.types.SilentCancelOutputException` """ - pass @add_example() @@ -129,7 +127,6 @@ class SilentCancelOutputException(Exception): * :class:`~shiny.types.SilentException` """ - pass class SilentOperationInProgressException(SilentException): diff --git a/shiny/ui/_valuebox.py b/shiny/ui/_valuebox.py index f374554a4..90d07c0a1 100644 --- a/shiny/ui/_valuebox.py +++ b/shiny/ui/_valuebox.py @@ -290,7 +290,7 @@ def value_box_theme( """e.g. `"primary"`, `"danger"`, `"purple"`, etc.""" ) - if not (name.startswith("bg-") or name.startswith("text-")): + if not (name.startswith(("bg-", "text-"))): name = "bg-" + name return ValueBoxTheme(class_=name, bg=bg, fg=fg) diff --git a/tests/playwright/controls.py b/tests/playwright/controls.py index 2e5200d5b..fb4db85f1 100644 --- a/tests/playwright/controls.py +++ b/tests/playwright/controls.py @@ -497,7 +497,6 @@ class InputPassword( # *, # width: Optional[str] = None, # placeholder: Optional[str] = None, - ... def __init__(self, page: Page, id: str) -> None: super().__init__( From 1e2b9472d5b7ccb1e5d1a220b9f1fcc6343ff14c Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:37:09 -0400 Subject: [PATCH 21/56] Drop flake8-print --- ruff.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index a390496f1..e731b62e1 100644 --- a/ruff.toml +++ b/ruff.toml @@ -58,7 +58,6 @@ extend-ignore = [ # ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn # PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie -# T20; flake8-print: https://docs.astral.sh/ruff/rules/#flake8-print-t20 # PYI013; flake8-pyi Non-empty class body must not contain `...`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi # PYI030; flake8-pyi Multiple literal members in a union: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi # PYI034; flake8-pyi `__new__` methods usually reutrn `Self`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi @@ -75,7 +74,7 @@ extend-ignore = [ extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN", "PIE"] # "C90" - Many false positives # "DTZ" - dates with timezones are different from dates without timezones -# "T20", "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From a4c0d9cff71a71b781be6720f8d3ac4e4145f82b Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:40:19 -0400 Subject: [PATCH 22/56] flake8-pyi --- ruff.toml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index e731b62e1..808922e71 100644 --- a/ruff.toml +++ b/ruff.toml @@ -71,10 +71,24 @@ extend-ignore = [ # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -extend-select = ["E", "I", "B", "Q", "COM", "C4", "FA102", "ISC", "ICN", "PIE"] +extend-select = [ + "E", + "I", + "B", + "Q", + "COM", + "C4", + "FA102", + "ISC", + "ICN", + "PIE", + "PYI013", + "PYI030", + "PYI034", +] # "C90" - Many false positives # "DTZ" - dates with timezones are different from dates without timezones -# "PYI013", "PYI030", "PYI034", "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] +# "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 07c1729d7a8a0360b3b7097ad1414ce3d9f7dca4 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:40:31 -0400 Subject: [PATCH 23/56] Auto fix flake8-pyi --- shiny/_connection.py | 1 - shiny/_custom_component_template_questions.py | 4 +--- shiny/experimental/ui/_deprecated.py | 1 - shiny/render/_dataframe.py | 4 +--- shiny/types.py | 3 --- 5 files changed, 2 insertions(+), 11 deletions(-) diff --git a/shiny/_connection.py b/shiny/_connection.py index 430e70ff8..846805089 100644 --- a/shiny/_connection.py +++ b/shiny/_connection.py @@ -137,4 +137,3 @@ def get_http_conn(self) -> HTTPConnection: class ConnectionClosed(Exception): """Raised when a Connection is closed from the other side.""" - diff --git a/shiny/_custom_component_template_questions.py b/shiny/_custom_component_template_questions.py index 9670de68e..a44743917 100644 --- a/shiny/_custom_component_template_questions.py +++ b/shiny/_custom_component_template_questions.py @@ -61,9 +61,7 @@ def validate(self, document: Document): # Check for quotations - if ( - name.startswith(('"', "'")) or name.endswith(('"', "'")) - ): + if name.startswith(('"', "'")) or name.endswith(('"', "'")): raise ValidationError( message="The name should be unquoted.", cursor_position=len(name), diff --git a/shiny/experimental/ui/_deprecated.py b/shiny/experimental/ui/_deprecated.py index 782656efc..de7b601d6 100644 --- a/shiny/experimental/ui/_deprecated.py +++ b/shiny/experimental/ui/_deprecated.py @@ -728,7 +728,6 @@ class AccordionPanel(MainAccordionPanel): """ - # Deprecated 2023-09-12 def accordion( *args: AccordionPanel | TagAttrs, diff --git a/shiny/render/_dataframe.py b/shiny/render/_dataframe.py index b3c3daa67..eb0a6a1fc 100644 --- a/shiny/render/_dataframe.py +++ b/shiny/render/_dataframe.py @@ -164,9 +164,7 @@ def __init__( height: Union[str, float, None] = "500px", summary: Union[bool, str] = True, filters: bool = False, - row_selection_mode: Union[ - Literal["none"], Literal["single"], Literal["multiple"] - ] = "none", + row_selection_mode: Literal["none", "single", "multiple"] = "none", ): import pandas as pd diff --git a/shiny/types.py b/shiny/types.py index 14a07bcd9..76cfe19cc 100644 --- a/shiny/types.py +++ b/shiny/types.py @@ -91,7 +91,6 @@ class SafeException(Exception): """ - @add_example() class SilentException(Exception): """ @@ -113,7 +112,6 @@ class SilentException(Exception): """ - @add_example() class SilentCancelOutputException(Exception): """ @@ -128,7 +126,6 @@ class SilentCancelOutputException(Exception): """ - class SilentOperationInProgressException(SilentException): # Throw a silent exception to indicate that an operation is in progress From 62e101d6ff340dd7944cf4fb3e86ec77849872b8 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:40:45 -0400 Subject: [PATCH 24/56] Manually fix flake8-pyi return Self --- tests/playwright/conftest.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py index 6707dd25e..5f9b0d14f 100644 --- a/tests/playwright/conftest.py +++ b/tests/playwright/conftest.py @@ -27,6 +27,7 @@ import pytest import shiny._utils +from shiny._typing_extensions import Self __all__ = ( "ShinyAppProc", @@ -149,7 +150,7 @@ def close(self) -> None: sleep(0.5) self.proc.terminate() - def __enter__(self) -> ShinyAppProc: + def __enter__(self) -> Self: return self def __exit__( From 35a536850e1888e0560edc74985cb59b6d20ab07 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:42:26 -0400 Subject: [PATCH 25/56] flake8-pytest-style --- ruff.toml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 808922e71..d8fb97612 100644 --- a/ruff.toml +++ b/ruff.toml @@ -72,6 +72,9 @@ extend-ignore = [ # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf extend-select = [ + # "C90", # Many false positives + # "DTZ", # Dates with timezones are different from dates without timezones + "E", "I", "B", @@ -85,10 +88,17 @@ extend-select = [ "PYI013", "PYI030", "PYI034", + "PT", + # "SIM118", + # "TCH", + # "FIX", + # "PD", + # "PGH", + # "FLY", + # "NPY", + # "RUF100", + # "RUF005", ] -# "C90" - Many false positives -# "DTZ" - dates with timezones are different from dates without timezones -# "PT", "SIM118", "TCH", "FIX", "PD", "PGH", "FLY", "NPY", "RUF100", "RUF005"] [lint.extend-per-file-ignores] # F403: 'from module import *' used; unable to detect undefined names From 56fb78cd9e8cda3ff9a7500681c0f5f4456604ca Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:42:58 -0400 Subject: [PATCH 26/56] Auto fix flake8-pytest-style --- tests/playwright/conftest.py | 6 +- .../components/data_frame/test_data_frame.py | 8 +-- tests/pytest/test_modules.py | 2 +- tests/pytest/test_output_transformer.py | 2 +- tests/pytest/test_poll.py | 8 +-- tests/pytest/test_reactives.py | 64 +++++++++---------- tests/pytest/test_renderer.py | 4 +- tests/pytest/test_shinysession.py | 2 +- tests/pytest/test_utils.py | 2 +- tests/pytest/test_utils_async.py | 14 ++-- 10 files changed, 56 insertions(+), 56 deletions(-) diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py index 5f9b0d14f..29610b1f6 100644 --- a/tests/playwright/conftest.py +++ b/tests/playwright/conftest.py @@ -229,7 +229,7 @@ def fixture_func(): # Pass through `yield` via `next(...)` call # (`yield` must be on same line as `next`!) app_gen = local_app_fixture_gen(app) - yield next(app_gen) + return next(app_gen) return fixture_func @@ -280,9 +280,9 @@ def x_create_doc_example_fixture(example_name: str, scope: ScopeName = "module") @pytest.fixture(scope="module") -def local_app(request: pytest.FixtureRequest) -> Generator[ShinyAppProc, None, None]: +def local_app(request: pytest.FixtureRequest) -> ShinyAppProc: app_gen = local_app_fixture_gen(PurePath(request.path).parent / "app.py") - yield next(app_gen) + return next(app_gen) @contextmanager diff --git a/tests/playwright/shiny/components/data_frame/test_data_frame.py b/tests/playwright/shiny/components/data_frame/test_data_frame.py index bddcc3059..6f710e73a 100644 --- a/tests/playwright/shiny/components/data_frame/test_data_frame.py +++ b/tests/playwright/shiny/components/data_frame/test_data_frame.py @@ -14,22 +14,22 @@ data_frame_app = create_example_fixture("dataframe") -@pytest.fixture +@pytest.fixture() def grid(page: Page) -> Locator: return page.locator("#grid") -@pytest.fixture +@pytest.fixture() def grid_container(page: Page, grid: Locator) -> Locator: return grid.locator("> div > div.shiny-data-grid") -@pytest.fixture +@pytest.fixture() def summary(page: Page, grid: Locator) -> Locator: return grid.locator("div.shiny-data-grid-summary") -@pytest.fixture +@pytest.fixture() def scroll_to_end(page: Page, grid_container: Locator) -> Callable[[], None]: def do(): grid_container.locator("tbody tr:first-child td:first-child").click() diff --git a/tests/pytest/test_modules.py b/tests/pytest/test_modules.py index 1b91fc7d7..a1522e35f 100644 --- a/tests/pytest/test_modules.py +++ b/tests/pytest/test_modules.py @@ -39,7 +39,7 @@ def test_module_ui(): assert get_id(y, 2) == "outer-out2" -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_session_scoping(): sessions: Dict[str, Union[Session, None, str]] = {} diff --git a/tests/pytest/test_output_transformer.py b/tests/pytest/test_output_transformer.py index 0ae494b0c..be4a0ecc7 100644 --- a/tests/pytest/test_output_transformer.py +++ b/tests/pytest/test_output_transformer.py @@ -197,7 +197,7 @@ def render_fn_sync(*args: str): assert "Expected `params` to be of type `TransformerParams`" in str(e) -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_renderer_handler_or_transform_fn_can_be_async(): @output_transformer async def AsyncTransformer( diff --git a/tests/pytest/test_poll.py b/tests/pytest/test_poll.py index 46b5b298c..60a79fb4a 100644 --- a/tests/pytest/test_poll.py +++ b/tests/pytest/test_poll.py @@ -52,7 +52,7 @@ async def __aexit__( self._on_ended_callbacks.invoke() -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_poll(): async with OnEndedSessionCallbacks(): poll_invocations = 0 @@ -126,7 +126,7 @@ def _(): assert (poll_invocations, value_invocations) == (6, 4) -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_poll_errors(): async with OnEndedSessionCallbacks(): @@ -194,7 +194,7 @@ def _(): assert invocations == 3 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_file_reader(): tmpfile = tempfile.NamedTemporaryFile(delete=False) try: @@ -240,7 +240,7 @@ def read_file(): os.unlink(tmpfile.name) -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_file_reader_error(): async with OnEndedSessionCallbacks(): tmpfile1 = tempfile.NamedTemporaryFile(delete=False) diff --git a/tests/pytest/test_reactives.py b/tests/pytest/test_reactives.py index d5744ef3e..d2dd3d3aa 100644 --- a/tests/pytest/test_reactives.py +++ b/tests/pytest/test_reactives.py @@ -16,7 +16,7 @@ from .mocktime import MockTime -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_flush_runs_newly_invalidated(): """ Make sure that a flush will also run any calcs that were invalidated during the @@ -45,7 +45,7 @@ def o1(): assert o1._exec_count == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_flush_runs_newly_invalidated_async(): """ Make sure that a flush will also run any calcs that were invalidated during the @@ -77,7 +77,7 @@ async def o1(): # ====================================================================== # Setting Value to same value doesn't invalidate downstream # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_reactive_value_same_no_invalidate(): v = Value(1) @@ -96,7 +96,7 @@ def o(): # ====================================================================== # Intializing reactive.Value to MISSING, and unsetting # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_reactive_value_unset(): v = Value[int]() @@ -136,7 +136,7 @@ def o(): # ====================================================================== # reactive.Value.is_set() invalidates dependents only when set state changes # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_reactive_value_is_set(): v = Value[int]() v_is_set: bool = False @@ -179,7 +179,7 @@ def o(): # ====================================================================== # Recursive calls to calcs # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_recursive_calc(): v = Value(5) @@ -201,7 +201,7 @@ def o(): assert v() == 0 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_recursive_async_calc(): v = Value(5) @@ -228,7 +228,7 @@ async def o(): # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_async_sequential(): x: Value[int] = Value(1) results: list[int] = [] @@ -276,7 +276,7 @@ async def _(): # ====================================================================== # isolate() # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_isolate_basic_without_context(): # isolate() works with calc and Value; allows executing without a reactive context. v = Value(1) @@ -296,7 +296,7 @@ def get_r(): assert get_r() == 11 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_isolate_prevents_dependency(): v = Value(1) @@ -333,7 +333,7 @@ def o(): # ====================================================================== # async isolate # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_isolate_async_basic_value(): async def f(): return 123 @@ -342,7 +342,7 @@ async def f(): assert await f() == 123 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_isolate_async_basic_without_context(): # async isolate works with calc and Value; allows executing without a reactive # context. @@ -360,7 +360,7 @@ async def get_r(): assert await get_r() == 11 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_isolate_async_prevents_dependency(): v = Value(1) @@ -397,7 +397,7 @@ async def o(): # ====================================================================== # Priority for effects # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_effect_priority(): v = Value(1) results: list[int] = [] @@ -448,7 +448,7 @@ def o4(): # Same as previous, but with async -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_async_effect_priority(): v = Value(1) results: list[int] = [] @@ -501,7 +501,7 @@ async def o4(): # ====================================================================== # Destroying effects # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_effect_destroy(): v = Value(1) results: list[int] = [] @@ -538,7 +538,7 @@ def o2(): # ====================================================================== # Error handling # ====================================================================== -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_error_handling(): vals: List[str] = [] @@ -585,7 +585,7 @@ def _(): assert vals == ["o1-1", "r", "o2"] -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_calc_error_rethrow(): # Make sure calcs re-throw errors. vals: List[str] = [] @@ -624,7 +624,7 @@ def _(): # Invalidating dependents # ====================================================================== # For https://github.com/posit-dev/py-shiny/issues/26 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_dependent_invalidation(): trigger = Value(0) v = Value(0) @@ -665,7 +665,7 @@ def r(): # ------------------------------------------------------------ # req() pauses execution in @effect() and @calc() # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_req(): n_times = 0 @@ -716,7 +716,7 @@ def _(): assert val == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_invalidate_later(): mock_time = MockTime() with mock_time(): @@ -747,7 +747,7 @@ def obs1(): assert obs1._exec_count == 12 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_invalidate_later_invalidation(): mock_time = MockTime() with mock_time(): @@ -775,7 +775,7 @@ def obs1(): assert obs1._exec_count == 2 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_mock_time(): mock_time = MockTime() @@ -800,7 +800,7 @@ async def add_result_later(delay: float, msg: str): # ------------------------------------------------------------ # @reactive.event() works as expected # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_event_decorator(): n_times = 0 @@ -911,7 +911,7 @@ def _(): # ------------------------------------------------------------ # @event() works as expected with async # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_event_async_decorator(): n_times = 0 @@ -1029,7 +1029,7 @@ async def _(): # ------------------------------------------------------------ # @event() handles silent exceptions in event function # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_event_silent_exception(): n_times = 0 x = Value[bool]() @@ -1059,7 +1059,7 @@ def _(): # ------------------------------------------------------------ # @event() handles silent exceptions in event function, async # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_event_silent_exception_async(): n_times = 0 x = Value[bool]() @@ -1095,7 +1095,7 @@ async def _(): # ------------------------------------------------------------ # @event() throws runtime errors if passed wrong type # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_event_type_check(): with pytest.raises(TypeError): # Should complain about missing argument to @event(). @@ -1148,7 +1148,7 @@ async def _(): ... # ------------------------------------------------------------ # @output() throws runtime errors if passed wrong type # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_output_type_check(): conn = MockConnection() session = App(ui.TagList(), None)._create_session(conn) @@ -1196,7 +1196,7 @@ def _(): ... # ------------------------------------------------------------ # @effect()'s .suspend()/.resume() works as expected # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_effect_pausing(): a = Value(float(1)) @@ -1278,7 +1278,7 @@ def _(): # ------------------------------------------------------------ # @effect()'s .suspend()/.resume() works as expected (with async) # ------------------------------------------------------------ -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_effect_async_pausing(): a = Value(float(1)) @@ -1357,7 +1357,7 @@ def _(): assert obsB._exec_count == 3 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_observer_async_suspended_resumed_observers_run_at_most_once(): a = Value(1) diff --git a/tests/pytest/test_renderer.py b/tests/pytest/test_renderer.py index 652461c7b..ab6ff9e7f 100644 --- a/tests/pytest/test_renderer.py +++ b/tests/pytest/test_renderer.py @@ -8,7 +8,7 @@ from shiny.render.renderer import Renderer, ValueFn -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_renderer_works(): # No args works class test_renderer(Renderer[str]): @@ -30,7 +30,7 @@ def txt_no_paren() -> str: assert val == "Hello World! Hello World!" -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_renderer_works_with_args(): # No args works class test_renderer_with_args(Renderer[str]): diff --git a/tests/pytest/test_shinysession.py b/tests/pytest/test_shinysession.py index 18017ba44..de3580f81 100644 --- a/tests/pytest/test_shinysession.py +++ b/tests/pytest/test_shinysession.py @@ -49,7 +49,7 @@ def test_input_nonexistent(): assert "y" not in input -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_input_nonexistent_deps(): # Make sure that `"x" in input` causes a reactive dependency to be created. input = Inputs({}) diff --git a/tests/pytest/test_utils.py b/tests/pytest/test_utils.py index ac99d4ab6..36a07ca01 100644 --- a/tests/pytest/test_utils.py +++ b/tests/pytest/test_utils.py @@ -93,7 +93,7 @@ def mutate_registrations(): assert cb4.exec_count == 1 # Registered during previous invoke(), was called -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_async_callbacks(): class AsyncMockCallback: def __init__(self): diff --git a/tests/pytest/test_utils_async.py b/tests/pytest/test_utils_async.py index 2ef3c7194..f91f7e5b2 100644 --- a/tests/pytest/test_utils_async.py +++ b/tests/pytest/test_utils_async.py @@ -144,7 +144,7 @@ async def inner(): asyncio.run(create_task_wrapper2()) -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid(): state = 0 @@ -167,7 +167,7 @@ async def test_task() -> int: assert await fut == 100 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_throw(): async def test_task_throw(): raise ValueError("boom") @@ -177,7 +177,7 @@ async def test_task_throw(): await fut -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_throw_later(): state = 0 @@ -193,7 +193,7 @@ async def test_task_throw_later(): await fut -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_cancel(): state = 0 @@ -210,7 +210,7 @@ async def test_task_cancel(): assert state == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_self_cancel(): state = 0 @@ -233,7 +233,7 @@ async def test_task_cancel(): assert state == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_self_cancel2(): state = 0 @@ -252,7 +252,7 @@ async def test_task_cancel(): assert state == 1 -@pytest.mark.asyncio +@pytest.mark.asyncio() async def test_coro_hybrid_context(): test = contextvars.ContextVar("test", default=False) From ca4b7d8b7178b89ef61e39dd10755321bcc2db4e Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Mon, 11 Mar 2024 23:43:43 -0400 Subject: [PATCH 27/56] More auto fix flake8-pytest-style --- tests/playwright/conftest.py | 2 +- tests/pytest/test_sidebar.py | 2 +- tests/pytest/test_utils.py | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py index 29610b1f6..f7d1df855 100644 --- a/tests/playwright/conftest.py +++ b/tests/playwright/conftest.py @@ -50,7 +50,7 @@ def session_page(browser: BrowserContext) -> Page: return browser.new_page() -@pytest.fixture(scope="function") +@pytest.fixture() # By going to `about:blank`, we _reset_ the page to a known state before each test. # It is not perfect, but it is faster than making a new page for each test. # This must be done before each test diff --git a/tests/pytest/test_sidebar.py b/tests/pytest/test_sidebar.py index f2f11605d..b8408859f 100644 --- a/tests/pytest/test_sidebar.py +++ b/tests/pytest/test_sidebar.py @@ -56,7 +56,7 @@ def test_panel_main_and_panel_sidebar(): @pytest.mark.parametrize( - "open_value, expected", + ("open_value", "expected"), [ ("closed", {"desktop": "closed", "mobile": "closed"}), ("open", {"desktop": "open", "mobile": "open"}), diff --git a/tests/pytest/test_utils.py b/tests/pytest/test_utils.py index 36a07ca01..31a0d8a58 100644 --- a/tests/pytest/test_utils.py +++ b/tests/pytest/test_utils.py @@ -19,7 +19,9 @@ def test_randomness(): pub2 = random.randint(0, 100000000) with private_seed(): priv2 = random.randint(0, 100000000) - assert pub != priv and priv != pub2 and pub2 != priv2 + assert pub != priv + assert priv != pub2 + assert pub2 != priv2 # By setting the same seed, we should get the same randomness random.seed(0) From 6506d7f59e4859a840dd9e5bafc9cb7b6601b800 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:06:26 -0400 Subject: [PATCH 28/56] Manually fix remaining PT lints --- ruff.toml | 48 +++++++--------- .../test_input_radio_checkbox_group_app.py | 56 +++++++++---------- .../input_slider/test_input_slider_app.py | 6 +- .../shiny/inputs/test_input_slider.py | 12 ++-- tests/pytest/test_output_transformer.py | 33 +++-------- tests/pytest/test_sidebar.py | 27 +++------ 6 files changed, 67 insertions(+), 115 deletions(-) diff --git a/ruff.toml b/ruff.toml index d8fb97612..a0e30cbf3 100644 --- a/ruff.toml +++ b/ruff.toml @@ -10,36 +10,24 @@ extend-exclude = [ ] [lint] -# E501: Line too long -# Conflicting lint rules: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules -# * indentation-with-invalid-multiple (E111) -# * indentation-with-invalid-multiple-comment (E114) -# * over-indented (E117) -# * indent-with-spaces (D206) -# * triple-single-quotes (D300) -# * bad-quotes-inline-string (Q000) -# * bad-quotes-multiline-string (Q001) -# * bad-quotes-docstring (Q002) -# * avoidable-escaped-quote (Q003) -# * missing-trailing-comma (COM812) -# * prohibited-trailing-comma (COM819) -# * single-line-implicit-string-concatenation (ISC001) -# * multi-line-implicit-string-concatenation (ISC002) + extend-ignore = [ - "E501", - "E111", - "E114", - "E117", - "D206", - "D300", - "Q000", - "Q001", - "Q002", - "Q003", - "COM812", - "COM819", - "ISC001", - "ISC002", + "E501", # E501: Line too long + "PT011", # PT011 `pytest.raises(ValueError)` is too broad + # Conflicting lint rules: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "E111", # * indentation-with-invalid-multiple (E111) + "E114", # * indentation-with-invalid-multiple-comment (E114) + "E117", # * over-indented (E117) + "D206", # * indent-with-spaces (D206) + "D300", # * triple-single-quotes (D300) + "Q000", # * bad-quotes-inline-string (Q000) + "Q001", # * bad-quotes-multiline-string (Q001) + "Q002", # * bad-quotes-docstring (Q002) + "Q003", # * avoidable-escaped-quote (Q003) + "COM812", # * missing-trailing-comma (COM812) + "COM819", # * prohibited-trailing-comma (COM819) + "ISC001", # * single-line-implicit-string-concatenation (ISC001) + "ISC002", # * multi-line-implicit-string-concatenation (ISC002) ] @@ -117,6 +105,8 @@ extend-select = [ "tests/**" = ["T20"] # I: isort "shiny/experimental/ui/__init__.py" = ["I"] +# PT019: pytest +"tests/pytest/test_output_transformer.py" = ["PT019"] [format] diff --git a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py index 24f5b265b..84974564a 100644 --- a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py +++ b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py @@ -1,5 +1,6 @@ from __future__ import annotations +import pytest from conftest import ShinyAppProc from controls import InputCheckboxGroup, InputRadioButtons, PatternOrStr from playwright.sync_api import Page, expect @@ -87,35 +88,32 @@ def test_locator_debugging(page: Page, local_app: ShinyAppProc) -> None: timeout = 100 # Non-existent div - try: - not_exist = InputRadioButtons(page, "does-not-exist") + not_exist = InputRadioButtons(page, "does-not-exist") + with pytest.raises(AssertionError) as e: not_exist.expect_choices(["a", "b", "c"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + + assert "expected to have count '1'" in str(e) + assert "Actual value: 0" in str(e) check1 = InputCheckboxGroup(page, "check1") # Make sure it works check1.expect_choices(["red", "green", "blue"]) # Too many - try: + with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green", "blue", "test_value"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '4'" in str(e) - assert "Actual value: 3" in str(e) + assert "expected to have count '4'" in str(e) + assert "Actual value: 3" in str(e) # Not enough - try: + with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '2'" in str(e) - assert "Actual value: 3" in str(e) + assert "expected to have count '2'" in str(e) + assert "Actual value: 3" in str(e) # Wrong value - try: + with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green", "test_value"], timeout=timeout) - except AssertionError as e: - assert "attribute 'test_value'" in str(e) - assert "Actual value: blue" in str(e) + assert "attribute 'test_value'" in str(e) + assert "Actual value: blue" in str(e) def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: @@ -124,12 +122,11 @@ def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: timeout = 100 # Non-existent div - try: - not_exist = InputCheckboxGroup(page, "does-not-exist") + not_exist = InputCheckboxGroup(page, "does-not-exist") + with pytest.raises(AssertionError) as e: not_exist.set(["green"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + assert "expected to have count '1'" in str(e) + assert "Actual value: 0" in str(e) check1 = InputCheckboxGroup(page, "check1") @@ -140,17 +137,16 @@ def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: check1.expect_selected(["green"]) # Different value - try: + with pytest.raises(AssertionError) as e: check1.set(["test_value"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + assert "expected to have count '1'" in str(e) + assert "Actual value: 0" in str(e) # Extra value - try: + with pytest.raises(AssertionError) as e: check1.set(["blue", "test_value"], timeout=timeout) - except AssertionError as e: - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + + assert "expected to have count '1'" in str(e) + assert "Actual value: 0" in str(e) check1.expect_selected(["green"]) diff --git a/tests/playwright/shiny/inputs/input_slider/test_input_slider_app.py b/tests/playwright/shiny/inputs/input_slider/test_input_slider_app.py index bb109e7f1..58968f982 100644 --- a/tests/playwright/shiny/inputs/input_slider/test_input_slider_app.py +++ b/tests/playwright/shiny/inputs/input_slider/test_input_slider_app.py @@ -1,6 +1,6 @@ -import re import time +import pytest from conftest import ShinyAppProc from controls import InputSlider, InputSliderRange, OutputTextVerbatim from playwright.sync_api import Page @@ -54,10 +54,8 @@ def test_slider_range(page: Page, local_app: ShinyAppProc) -> None: new_val = ("605", "840") s1.set(new_val, max_err_values=1000) - try: + with pytest.raises(ValueError, match="tuple entries cannot"): s1.expect_value((MISSING, MISSING)) # type: ignore - except ValueError as e: - assert re.search("tuple entries cannot", str(e)) s1.expect_value((new_val[0], MISSING)) s1.expect_value((MISSING, new_val[1])) s1.expect_value(new_val) diff --git a/tests/playwright/shiny/inputs/test_input_slider.py b/tests/playwright/shiny/inputs/test_input_slider.py index 5da4cfaac..3bd655de6 100644 --- a/tests/playwright/shiny/inputs/test_input_slider.py +++ b/tests/playwright/shiny/inputs/test_input_slider.py @@ -1,3 +1,4 @@ +import pytest from conftest import ShinyAppProc, create_doc_example_core_fixture from controls import InputSlider, OutputTextVerbatim from playwright.sync_api import Page, expect @@ -49,13 +50,12 @@ def test_input_slider_kitchen(page: Page, slider_app: ShinyAppProc) -> None: # e # ), "Error message should contain the list of first 15 valid values" - try: + with pytest.raises(ValueError) as e: obs.set("not-a-number", timeout=800, max_err_values=4) - except ValueError as e: - values_found = '"10", "11", "12", "13", ...' - assert values_found in str( - e - ), "Error message should contain the list of first 4 valid values" + values_found = '"10", "11", "12", "13", ...' + assert values_found in str( + e + ), "Error message should contain the list of first 4 valid values" def test_input_slider_output(page: Page, template_app: ShinyAppProc) -> None: diff --git a/tests/pytest/test_output_transformer.py b/tests/pytest/test_output_transformer.py index be4a0ecc7..31915423b 100644 --- a/tests/pytest/test_output_transformer.py +++ b/tests/pytest/test_output_transformer.py @@ -116,20 +116,16 @@ def test_renderer( def test_output_transformer_pos_args(): - try: + with pytest.raises(TypeError, match="must have 2 positional arguments"): @output_transformer # pyright: ignore[reportArgumentType] async def TestTransformer( _meta: TransformerMetadata, ): ... - raise RuntimeError() - except TypeError as e: - assert "must have 2 positional parameters" in str(e) - def test_output_transformer_limits_positional_arg_count(): - try: + with pytest.raises(TypeError, match="more than 2 positional"): @output_transformer async def TestTransformer( @@ -138,13 +134,9 @@ async def TestTransformer( y: str, ): ... - raise RuntimeError() - except TypeError as e: - assert "more than 2 positional" in str(e) - def test_output_transformer_does_not_allow_args(): - try: + with pytest.raises(TypeError, match="No variadic positional parameters"): @output_transformer async def TestTransformer( @@ -153,14 +145,9 @@ async def TestTransformer( *args: str, ): ... - raise RuntimeError() - - except TypeError as e: - assert "No variadic positional parameters" in str(e) - def test_output_transformer_kwargs_have_defaults(): - try: + with pytest.raises(TypeError, match="did not have a default value"): @output_transformer async def TestTransformer( @@ -170,11 +157,6 @@ async def TestTransformer( y: str, ): ... - raise RuntimeError() - - except TypeError as e: - assert "did not have a default value" in str(e) - def test_output_transformer_result_does_not_allow_args(): @output_transformer @@ -187,14 +169,13 @@ async def TestTransformer( def render_fn_sync(*args: str): return " ".join(args) - try: + with pytest.raises( + TypeError, match="Expected `params` to be of type `TransformerParams`" + ): TestTransformer( render_fn_sync, "X", # pyright: ignore[reportArgumentType] ) - raise RuntimeError() - except TypeError as e: - assert "Expected `params` to be of type `TransformerParams`" in str(e) @pytest.mark.asyncio() diff --git a/tests/pytest/test_sidebar.py b/tests/pytest/test_sidebar.py index b8408859f..6394ebc33 100644 --- a/tests/pytest/test_sidebar.py +++ b/tests/pytest/test_sidebar.py @@ -25,34 +25,21 @@ def test_panel_main_and_panel_sidebar(): ui.layout_sidebar(_s) ui.layout_sidebar(_s, None) - try: + with pytest.raises(ValueError, match="multiple `sidebar()` objects"): ui.layout_sidebar(_s, _s) - raise AssertionError("Should have raised ValueError") - except ValueError as e: - assert "multiple `sidebar()` objects" in str(e) - try: + with pytest.raises( + ValueError, match="not being supplied with a `sidebar()` object" + ): ui.layout_sidebar(None, _ps) # pyright: ignore[reportArgumentType] - raise AssertionError("Should have raised ValueError") - except ValueError as e: - assert "not being supplied with a `sidebar()` object." in str(e) - try: + with pytest.raises(ValueError, match="is not being used with `panel_sidebar()`"): ui.layout_sidebar(_s, _pm) - raise AssertionError("Should have raised ValueError") - except ValueError as e: - assert "is not being used with `panel_sidebar()`" in str(e) - try: + with pytest.raises(ValueError, match="not being supplied as the second argument"): ui.layout_sidebar(_ps, None, _pm) - raise AssertionError("Should have raised ValueError") - except ValueError as e: - assert "not being supplied as the second argument" in str(e) - try: + with pytest.raises(ValueError, match="Unexpected extra legacy `*args`"): ui.layout_sidebar(_ps, _pm, None, "42") - raise AssertionError("Should have raised ValueError") - except ValueError as e: - assert "Unexpected extra legacy `*args`" in str(e) @pytest.mark.parametrize( From 23e618bc12db127132581af0915626a000f9b6eb Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:07:47 -0400 Subject: [PATCH 29/56] flake8-simplify Use `key {operator} dict` --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index a0e30cbf3..f9305793c 100644 --- a/ruff.toml +++ b/ruff.toml @@ -77,7 +77,7 @@ extend-select = [ "PYI030", "PYI034", "PT", - # "SIM118", + "SIM118", # "TCH", # "FIX", # "PD", From fd287b0c3833359d6bd1d39a9e7da351e28d12db Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:07:53 -0400 Subject: [PATCH 30/56] Auto fix flake8-simplify Use `key {operator} dict` --- shiny/ui/_layout_columns.py | 4 +--- tests/playwright/examples/example_apps.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/shiny/ui/_layout_columns.py b/shiny/ui/_layout_columns.py index 30b89b673..e63de30bb 100644 --- a/shiny/ui/_layout_columns.py +++ b/shiny/ui/_layout_columns.py @@ -263,9 +263,7 @@ def row_heights_attrs( # We use classes to activate CSS variables at the right breakpoints. Note: Mobile # row height is derived from xs or defaults to auto in the CSS, so we don't need the # class to activate it - classes = [ - f"bslib-grid--row-heights--{brk}" for brk in x_complete.keys() if brk != "xs" - ] + classes = [f"bslib-grid--row-heights--{brk}" for brk in x_complete if brk != "xs"] # Create CSS variables, treating numeric values as fractional units, passing strings css_vars: Dict[str, str] = {} diff --git a/tests/playwright/examples/example_apps.py b/tests/playwright/examples/example_apps.py index 1ce27a124..2c954106a 100644 --- a/tests/playwright/examples/example_apps.py +++ b/tests/playwright/examples/example_apps.py @@ -174,7 +174,7 @@ def on_console_msg(msg: ConsoleMessage) -> None: app_name = os.path.basename(os.path.dirname(ex_app_path)) short_app_path = f"{os.path.basename(os.path.dirname(os.path.dirname(ex_app_path)))}/{app_name}" - if short_app_path in app_hard_wait.keys(): + if short_app_path in app_hard_wait: # Apps are constantly invalidating and will not stabilize # Instead, wait for specific amount of time page.wait_for_timeout(app_hard_wait[short_app_path]) From 0d8755be7a62553f4c3f079c15a3038ae7a5bd8b Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:08:38 -0400 Subject: [PATCH 31/56] flake8-type-checking --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index f9305793c..8ecdaf59c 100644 --- a/ruff.toml +++ b/ruff.toml @@ -78,7 +78,7 @@ extend-select = [ "PYI034", "PT", "SIM118", - # "TCH", + "TCH", # "FIX", # "PD", # "PGH", From 85627751a02e62a8c511cd77007747a3c4e463ad Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:14:11 -0400 Subject: [PATCH 32/56] Fix broken tests --- tests/pytest/test_output_transformer.py | 2 +- tests/pytest/test_sidebar.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/pytest/test_output_transformer.py b/tests/pytest/test_output_transformer.py index 31915423b..a50dbe002 100644 --- a/tests/pytest/test_output_transformer.py +++ b/tests/pytest/test_output_transformer.py @@ -116,7 +116,7 @@ def test_renderer( def test_output_transformer_pos_args(): - with pytest.raises(TypeError, match="must have 2 positional arguments"): + with pytest.raises(TypeError, match="must have 2 positional parameters"): @output_transformer # pyright: ignore[reportArgumentType] async def TestTransformer( diff --git a/tests/pytest/test_sidebar.py b/tests/pytest/test_sidebar.py index 6394ebc33..7709bb226 100644 --- a/tests/pytest/test_sidebar.py +++ b/tests/pytest/test_sidebar.py @@ -25,21 +25,23 @@ def test_panel_main_and_panel_sidebar(): ui.layout_sidebar(_s) ui.layout_sidebar(_s, None) - with pytest.raises(ValueError, match="multiple `sidebar()` objects"): + with pytest.raises(ValueError) as e: ui.layout_sidebar(_s, _s) + assert "multiple `sidebar()` objects" in str(e) - with pytest.raises( - ValueError, match="not being supplied with a `sidebar()` object" - ): + with pytest.raises(ValueError) as e: ui.layout_sidebar(None, _ps) # pyright: ignore[reportArgumentType] + assert "not being supplied with a `sidebar()` object" in str(e) - with pytest.raises(ValueError, match="is not being used with `panel_sidebar()`"): + with pytest.raises(ValueError) as e: ui.layout_sidebar(_s, _pm) + assert "is not being used with `panel_sidebar()`" in str(e) with pytest.raises(ValueError, match="not being supplied as the second argument"): ui.layout_sidebar(_ps, None, _pm) - with pytest.raises(ValueError, match="Unexpected extra legacy `*args`"): + with pytest.raises(ValueError) as e: ui.layout_sidebar(_ps, _pm, None, "42") + assert "Unexpected extra legacy `*args`" in str(e) @pytest.mark.parametrize( From 354dbaa3e015447d69df747ee48f3396e0204bf7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:14:57 -0400 Subject: [PATCH 33/56] Auto fix type checking lint --- examples/dataframe/app.py | 6 ++++- shiny/_error.py | 6 +++-- shiny/_hostenv.py | 4 +++- shiny/_main.py | 6 +++-- shiny/_utils.py | 17 +++++++++++--- shiny/api-examples/input_file/app-core.py | 6 ++++- shiny/api-examples/input_file/app-express.py | 6 ++++- shiny/api-examples/output_image/app-core.py | 6 ++++- shiny/api-examples/render_image/app-core.py | 6 ++++- shiny/experimental/ui/_deprecated.py | 12 +++++----- shiny/express/_output.py | 9 +++++--- shiny/express/_recall_context.py | 6 +++-- shiny/express/_run.py | 6 +++-- shiny/express/app.py | 5 ++++- .../_node_transformers.py | 6 +++-- shiny/express/ui/_cm_components.py | 20 +++++++++-------- shiny/express/ui/_hold.py | 6 +++-- shiny/express/ui/_page.py | 7 +++--- shiny/http_staticfiles.py | 6 +++-- shiny/plotutils.py | 3 ++- shiny/render/_coordmap.py | 22 +++++++++---------- shiny/render/_dataframe.py | 3 +-- shiny/render/_express.py | 6 +++-- shiny/render/_render.py | 2 +- shiny/render/renderer/_renderer.py | 5 ++++- shiny/render/renderer/_utils.py | 10 +++++---- shiny/render/transformer/_transformer.py | 2 +- shiny/types.py | 3 +-- shiny/ui/_input_task_button.py | 6 +++-- shiny/ui/_input_update.py | 6 +++-- shiny/ui/_modal.py | 6 +++-- shiny/ui/_notification.py | 4 ++-- shiny/ui/_progress.py | 5 +++-- shiny/ui/_utils.py | 6 +++-- tests/playwright/conftest.py | 11 +++++++--- tests/playwright/controls.py | 4 +++- tests/playwright/shiny/TODO/navbar/app.py | 6 ++++- .../test_update_slider_datetime_value.py | 6 +++-- .../bugs/0666-sidebar/test_sidebar_colors.py | 6 ++++- .../test_0676_row_selection.py | 6 ++++- .../shiny/bugs/0696-resolve-id/app.py | 4 +++- .../shiny/bugs/0696-resolve-id/mod_state.py | 5 ++++- .../0696-resolve-id/test_0696_resolve_id.py | 7 ++++-- .../layout_columns/test_layout_columns.py | 6 +++-- tests/playwright/shiny/components/nav/app.py | 12 +++++----- .../shiny/components/nav/test_nav.py | 7 ++++-- .../playwright/shiny/inputs/input_file/app.py | 4 +++- .../inputs/input_file/test_input_file.py | 6 ++++- .../test_input_radio_checkbox_group_app.py | 6 ++++- .../test_input_task_button.py | 7 ++++-- .../test_input_task_button2.py | 8 +++++-- .../shiny/inputs/test_input_dark_mode.py | 6 ++++- tests/pytest/test_sidebar.py | 6 +++-- 53 files changed, 245 insertions(+), 113 deletions(-) diff --git a/examples/dataframe/app.py b/examples/dataframe/app.py index 99374627e..3568bbcb6 100644 --- a/examples/dataframe/app.py +++ b/examples/dataframe/app.py @@ -1,9 +1,13 @@ -import pandas as pd +from typing import TYPE_CHECKING + import seaborn as sns from shinyswatch.theme import darkly from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui +if TYPE_CHECKING: + import pandas as pd + def app_ui(req): dark = True if "dark" in req.query_params else None diff --git a/shiny/_error.py b/shiny/_error.py index 33f807dbc..bee5f6964 100644 --- a/shiny/_error.py +++ b/shiny/_error.py @@ -1,10 +1,12 @@ from __future__ import annotations -from typing import cast +from typing import TYPE_CHECKING, cast import starlette.exceptions as exceptions import starlette.responses as responses -from starlette.types import ASGIApp, Receive, Scope, Send + +if TYPE_CHECKING: + from starlette.types import ASGIApp, Receive, Scope, Send class ErrorMiddleware: diff --git a/shiny/_hostenv.py b/shiny/_hostenv.py index 89f1e0273..74876b770 100644 --- a/shiny/_hostenv.py +++ b/shiny/_hostenv.py @@ -1,6 +1,5 @@ from __future__ import annotations -import logging import os import re import typing @@ -9,6 +8,9 @@ from typing import Pattern from urllib.parse import ParseResult, urlparse +if typing.TYPE_CHECKING: + import logging + def is_workbench() -> bool: return bool(os.getenv("RS_SERVER_URL") and os.getenv("RS_SESSION_URL")) diff --git a/shiny/_main.py b/shiny/_main.py index 1bdcf0f6f..10f4653ba 100644 --- a/shiny/_main.py +++ b/shiny/_main.py @@ -8,9 +8,8 @@ import platform import re import sys -import types from pathlib import Path -from typing import Any, Optional +from typing import TYPE_CHECKING, Any, Optional import click import uvicorn @@ -24,6 +23,9 @@ from .express import is_express_app from .express._utils import escape_to_var_name +if TYPE_CHECKING: + import types + @click.group("main") def main() -> None: diff --git a/shiny/_utils.py b/shiny/_utils.py index 5b0f7fe20..cea322919 100644 --- a/shiny/_utils.py +++ b/shiny/_utils.py @@ -13,12 +13,23 @@ import sys import tempfile import warnings -from pathlib import Path -from types import ModuleType -from typing import Any, Awaitable, Callable, Generator, Optional, TypeVar, cast +from typing import ( + TYPE_CHECKING, + Any, + Awaitable, + Callable, + Generator, + Optional, + TypeVar, + cast, +) from ._typing_extensions import ParamSpec, TypeGuard +if TYPE_CHECKING: + from pathlib import Path + from types import ModuleType + CancelledError = asyncio.CancelledError T = TypeVar("T") diff --git a/shiny/api-examples/input_file/app-core.py b/shiny/api-examples/input_file/app-core.py index 937889f22..9331d5ba7 100644 --- a/shiny/api-examples/input_file/app-core.py +++ b/shiny/api-examples/input_file/app-core.py @@ -1,9 +1,13 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pandas as pd from shiny import App, Inputs, Outputs, Session, reactive, render, ui -from shiny.types import FileInfo + +if TYPE_CHECKING: + from shiny.types import FileInfo app_ui = ui.page_fluid( ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False), diff --git a/shiny/api-examples/input_file/app-express.py b/shiny/api-examples/input_file/app-express.py index 243c09f52..b930ad284 100644 --- a/shiny/api-examples/input_file/app-express.py +++ b/shiny/api-examples/input_file/app-express.py @@ -1,10 +1,14 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pandas as pd from shiny import reactive from shiny.express import input, render, ui -from shiny.types import FileInfo + +if TYPE_CHECKING: + from shiny.types import FileInfo ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False) ui.input_checkbox_group( diff --git a/shiny/api-examples/output_image/app-core.py b/shiny/api-examples/output_image/app-core.py index 09452566a..b530f29be 100644 --- a/shiny/api-examples/output_image/app-core.py +++ b/shiny/api-examples/output_image/app-core.py @@ -1,5 +1,9 @@ +from typing import TYPE_CHECKING + from shiny import App, Inputs, Outputs, Session, render, ui -from shiny.types import ImgData + +if TYPE_CHECKING: + from shiny.types import ImgData app_ui = ui.page_fluid(ui.output_image("image")) diff --git a/shiny/api-examples/render_image/app-core.py b/shiny/api-examples/render_image/app-core.py index 60d35d90a..a3c7d6732 100644 --- a/shiny/api-examples/render_image/app-core.py +++ b/shiny/api-examples/render_image/app-core.py @@ -1,5 +1,9 @@ +from typing import TYPE_CHECKING + from shiny import App, Inputs, Outputs, Session, render, ui -from shiny.types import ImgData + +if TYPE_CHECKING: + from shiny.types import ImgData app_ui = ui.page_fluid(ui.output_image("image")) diff --git a/shiny/experimental/ui/_deprecated.py b/shiny/experimental/ui/_deprecated.py index de7b601d6..4a1b74e33 100644 --- a/shiny/experimental/ui/_deprecated.py +++ b/shiny/experimental/ui/_deprecated.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Literal, Optional, Sequence, TypeVar, overload +from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, TypeVar, overload from htmltools import ( MetadataNode, @@ -46,10 +46,6 @@ from ...ui._page import page_fillable as main_page_fillable from ...ui._page import page_navbar as main_page_navbar from ...ui._page import page_sidebar as main_page_sidebar -from ...ui._plot_output_opts import BrushOpts as MainBrushOpts -from ...ui._plot_output_opts import ClickOpts as MainClickOpts -from ...ui._plot_output_opts import DblClickOpts as MainDblClickOpts -from ...ui._plot_output_opts import HoverOpts as MainHoverOpts from ...ui._sidebar import DeprecatedPanelMain, DeprecatedPanelSidebar from ...ui._sidebar import Sidebar as MainSidebar from ...ui._sidebar import SidebarOpenSpec as MainSidebarOpenSpec @@ -72,6 +68,12 @@ from ...ui.fill._fill import is_fill_item as main_is_fill_item from ...ui.fill._fill import is_fillable_container as main_is_fillable_container +if TYPE_CHECKING: + from ...ui._plot_output_opts import BrushOpts as MainBrushOpts + from ...ui._plot_output_opts import ClickOpts as MainClickOpts + from ...ui._plot_output_opts import DblClickOpts as MainDblClickOpts + from ...ui._plot_output_opts import HoverOpts as MainHoverOpts + __all__ = ( # Input Switch "toggle_switch", diff --git a/shiny/express/_output.py b/shiny/express/_output.py index a09484c52..6d89b1eb5 100644 --- a/shiny/express/_output.py +++ b/shiny/express/_output.py @@ -1,13 +1,16 @@ from __future__ import annotations -from contextlib import AbstractContextManager -from typing import Callable, TypeVar +from typing import TYPE_CHECKING, Callable, TypeVar from .._deprecated import warn_deprecated from .._typing_extensions import ParamSpec -from ..render.renderer import RendererT from .ui import hold +if TYPE_CHECKING: + from contextlib import AbstractContextManager + + from ..render.renderer import RendererT + __all__ = ("suspend_display",) P = ParamSpec("P") diff --git a/shiny/express/_recall_context.py b/shiny/express/_recall_context.py index 3d81712b4..337b0bb7e 100644 --- a/shiny/express/_recall_context.py +++ b/shiny/express/_recall_context.py @@ -2,13 +2,15 @@ import functools import sys -from types import TracebackType -from typing import Callable, Generic, Mapping, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Callable, Generic, Mapping, Optional, Type, TypeVar from htmltools import MetadataNode, Tag, TagList, wrap_displayhook_handler from .._typing_extensions import ParamSpec +if TYPE_CHECKING: + from types import TracebackType + P = ParamSpec("P") R = TypeVar("R") U = TypeVar("U") diff --git a/shiny/express/_run.py b/shiny/express/_run.py index cdfc9a9d0..2373c8613 100644 --- a/shiny/express/_run.py +++ b/shiny/express/_run.py @@ -4,7 +4,7 @@ import os import sys from pathlib import Path -from typing import cast +from typing import TYPE_CHECKING, cast from htmltools import Tag, TagList @@ -15,13 +15,15 @@ from ..session import Inputs, Outputs, Session, get_current_session, session_context from ..types import MISSING, MISSING_TYPE from ._mock_session import ExpressMockSession -from ._recall_context import RecallContextManager from .expressify_decorator._func_displayhook import _expressify_decorator_function_def from .expressify_decorator._node_transformers import ( DisplayFuncsTransformer, expressify_decorator_func_name, ) +if TYPE_CHECKING: + from ._recall_context import RecallContextManager + __all__ = ( "app_opts", "wrap_express_app", diff --git a/shiny/express/app.py b/shiny/express/app.py index 9612d0892..5e7bcea38 100644 --- a/shiny/express/app.py +++ b/shiny/express/app.py @@ -1,11 +1,14 @@ from __future__ import annotations from pathlib import Path +from typing import TYPE_CHECKING -from .._app import App from ._run import wrap_express_app from ._utils import unescape_from_var_name +if TYPE_CHECKING: + from .._app import App + # If someone requests shiny.express.app:_2f_path_2f_to_2f_app_2e_py, then we will call # wrap_express_app(Path("/path/to/app.py")) and return the result. diff --git a/shiny/express/expressify_decorator/_node_transformers.py b/shiny/express/expressify_decorator/_node_transformers.py index b80333f7e..478235d4e 100644 --- a/shiny/express/expressify_decorator/_node_transformers.py +++ b/shiny/express/expressify_decorator/_node_transformers.py @@ -1,11 +1,13 @@ from __future__ import annotations import ast -import types -from typing import Any, Callable, cast +from typing import TYPE_CHECKING, Any, Callable, cast from ._helpers import ast_matches_func +if TYPE_CHECKING: + import types + sys_alias = "__auto_displayhook_sys__" expressify_decorator_func_name = "_expressify_decorator_function_def" diff --git a/shiny/express/ui/_cm_components.py b/shiny/express/ui/_cm_components.py index e4378211b..7d2002750 100644 --- a/shiny/express/ui/_cm_components.py +++ b/shiny/express/ui/_cm_components.py @@ -2,21 +2,23 @@ from __future__ import annotations -from typing import Literal, Optional - -from htmltools import Tag, TagAttrs, TagAttrValue, TagChild, TagFunction, TagList +from typing import TYPE_CHECKING, Literal, Optional from ... import ui from ..._docstring import add_example, no_example from ...types import MISSING, MISSING_TYPE -from ...ui._accordion import AccordionPanel -from ...ui._card import CardItem -from ...ui._layout_columns import BreakpointsUser -from ...ui._navs import NavMenu, NavPanel, NavSet, NavSetBar, NavSetCard -from ...ui._sidebar import SidebarOpenSpec, SidebarOpenValue -from ...ui.css import CssUnit from .._recall_context import RecallContextManager +if TYPE_CHECKING: + from htmltools import Tag, TagAttrs, TagAttrValue, TagChild, TagFunction, TagList + + from ...ui._accordion import AccordionPanel + from ...ui._card import CardItem + from ...ui._layout_columns import BreakpointsUser + from ...ui._navs import NavMenu, NavPanel, NavSet, NavSetBar, NavSetCard + from ...ui._sidebar import SidebarOpenSpec, SidebarOpenValue + from ...ui.css import CssUnit + __all__ = ( "sidebar", "layout_sidebar", diff --git a/shiny/express/ui/_hold.py b/shiny/express/ui/_hold.py index 1f83a04d3..be5c820dd 100644 --- a/shiny/express/ui/_hold.py +++ b/shiny/express/ui/_hold.py @@ -1,14 +1,16 @@ from __future__ import annotations import sys -from types import TracebackType -from typing import Callable, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Callable, Optional, Type, TypeVar from htmltools import wrap_displayhook_handler from ..._docstring import no_example from ..._typing_extensions import ParamSpec +if TYPE_CHECKING: + from types import TracebackType + __all__ = ("hold",) P = ParamSpec("P") diff --git a/shiny/express/ui/_page.py b/shiny/express/ui/_page.py index d005540e9..9ff00060d 100644 --- a/shiny/express/ui/_page.py +++ b/shiny/express/ui/_page.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import Callable - -from htmltools import Tag +from typing import TYPE_CHECKING, Callable from ... import ui from ..._docstring import no_example @@ -10,6 +8,9 @@ from .._recall_context import RecallContextManager from .._run import get_top_level_recall_context_manager +if TYPE_CHECKING: + from htmltools import Tag + __all__ = ("page_opts",) diff --git a/shiny/http_staticfiles.py b/shiny/http_staticfiles.py index db38f543c..257131050 100644 --- a/shiny/http_staticfiles.py +++ b/shiny/http_staticfiles.py @@ -17,8 +17,11 @@ ) import sys +from typing import TYPE_CHECKING -from starlette.background import BackgroundTask +if TYPE_CHECKING: + from starlette.background import BackgroundTask + from starlette.types import Receive, Scope, Send if "pyodide" not in sys.modules: # Running in native mode; use starlette StaticFiles @@ -39,7 +42,6 @@ from typing import Iterable, MutableMapping, Optional from starlette.responses import PlainTextResponse - from starlette.types import Receive, Scope, Send from . import _utils diff --git a/shiny/plotutils.py b/shiny/plotutils.py index 9d513a248..8787d78ad 100644 --- a/shiny/plotutils.py +++ b/shiny/plotutils.py @@ -10,12 +10,13 @@ from typing import TYPE_CHECKING, Literal, Optional, Union, cast from ._typing_extensions import TypedDict -from .types import BrushInfo, CoordInfo, CoordXY if TYPE_CHECKING: import numpy.typing as npt import pandas as pd + from .types import BrushInfo, CoordInfo, CoordXY + DataFrameColumn = Union[ "pd.Series[int]", "pd.Series[float]", diff --git a/shiny/render/_coordmap.py b/shiny/render/_coordmap.py index e82fcb903..18baa25a2 100644 --- a/shiny/render/_coordmap.py +++ b/shiny/render/_coordmap.py @@ -5,17 +5,6 @@ from copy import deepcopy from typing import TYPE_CHECKING, Any, cast -from ..types import ( - Coordmap, - CoordmapDims, - CoordmapPanel, - CoordmapPanelDomain, - CoordmapPanelLog, - CoordmapPanelMapping, - CoordmapPanelRange, - PlotnineFigure, -) - if TYPE_CHECKING: import numpy as np import numpy.typing as npt @@ -23,6 +12,17 @@ from matplotlib.figure import Figure from matplotlib.gridspec import SubplotSpec + from ..types import ( + Coordmap, + CoordmapDims, + CoordmapPanel, + CoordmapPanelDomain, + CoordmapPanelLog, + CoordmapPanelMapping, + CoordmapPanelRange, + PlotnineFigure, + ) + def get_coordmap(fig: Figure) -> Coordmap | None: dims_ar = fig.get_size_inches() * fig.get_dpi() diff --git a/shiny/render/_dataframe.py b/shiny/render/_dataframe.py index eb0a6a1fc..1d770d138 100644 --- a/shiny/render/_dataframe.py +++ b/shiny/render/_dataframe.py @@ -4,8 +4,6 @@ import json from typing import TYPE_CHECKING, Any, Literal, Protocol, Union, cast, runtime_checkable -from htmltools import Tag - from .. import ui from .._docstring import add_example, no_example from ._dataframe_unsafe import serialize_numpy_dtypes @@ -13,6 +11,7 @@ if TYPE_CHECKING: import pandas as pd + from htmltools import Tag class AbstractTabularData(abc.ABC): diff --git a/shiny/render/_express.py b/shiny/render/_express.py index cc7d65b60..a37fb2fd2 100644 --- a/shiny/render/_express.py +++ b/shiny/render/_express.py @@ -1,12 +1,11 @@ from __future__ import annotations import sys -from typing import Optional +from typing import TYPE_CHECKING, Optional from htmltools import Tag, TagAttrValue, TagFunction, TagList, wrap_displayhook_handler from .. import ui as _ui -from .._typing_extensions import Self from ..session._utils import require_active_session from ..types import MISSING, MISSING_TYPE from .renderer import AsyncValueFn, Renderer, ValueFn @@ -16,6 +15,9 @@ set_kwargs_value, ) +if TYPE_CHECKING: + from .._typing_extensions import Self + class express(Renderer[None]): """ diff --git a/shiny/render/_render.py b/shiny/render/_render.py index e333074af..23cace29a 100644 --- a/shiny/render/_render.py +++ b/shiny/render/_render.py @@ -24,13 +24,13 @@ if TYPE_CHECKING: import pandas as pd + from .._typing_extensions import Self from ..session._utils import RenderedDeps from .. import _utils from .. import ui as _ui from .._docstring import add_example, no_example from .._namespaces import ResolvedId -from .._typing_extensions import Self from ..express._mock_session import ExpressMockSession from ..session import get_current_session, require_active_session from ..session._session import DownloadHandler, DownloadInfo diff --git a/shiny/render/renderer/_renderer.py b/shiny/render/renderer/_renderer.py index a1b8fe3b3..022107c16 100644 --- a/shiny/render/renderer/_renderer.py +++ b/shiny/render/renderer/_renderer.py @@ -1,6 +1,7 @@ from __future__ import annotations from typing import ( + TYPE_CHECKING, Any, Awaitable, Callable, @@ -17,9 +18,11 @@ from htmltools import MetadataNode, Tag, TagList from ..._docstring import add_example -from ..._typing_extensions import Self from ..._utils import is_async_callable, wrap_async +if TYPE_CHECKING: + from ..._typing_extensions import Self + # TODO-barret-future: Double check docs are rendererd # Missing first paragraph from some classes: Example: TransformerMetadata. # No init method for TransformerParams. This is because the `DocClass` object does not diff --git a/shiny/render/renderer/_utils.py b/shiny/render/renderer/_utils.py index 8bed1c415..74eedfe20 100644 --- a/shiny/render/renderer/_utils.py +++ b/shiny/render/renderer/_utils.py @@ -1,13 +1,15 @@ from __future__ import annotations -from typing import Any, Dict, cast +from typing import TYPE_CHECKING, Any, Dict, cast -from htmltools import TagFunction - -from ...session._utils import RenderedDeps from ...types import MISSING_TYPE, ImgData from ._renderer import Jsonifiable +if TYPE_CHECKING: + from htmltools import TagFunction + + from ...session._utils import RenderedDeps + JsonifiableDict = Dict[str, Jsonifiable] diff --git a/shiny/render/transformer/_transformer.py b/shiny/render/transformer/_transformer.py index 5b49b5846..5a2a01e3f 100644 --- a/shiny/render/transformer/_transformer.py +++ b/shiny/render/transformer/_transformer.py @@ -33,10 +33,10 @@ ) from ..renderer import Jsonifiable, Renderer -from ..renderer._renderer import DefaultUIFn, DefaultUIFnResultOrNone if TYPE_CHECKING: from ...session import Session + from ..renderer._renderer import DefaultUIFn, DefaultUIFnResultOrNone from ..._deprecated import warn_deprecated from ..._docstring import add_example diff --git a/shiny/types.py b/shiny/types.py index 76cfe19cc..61551833e 100644 --- a/shiny/types.py +++ b/shiny/types.py @@ -14,12 +14,11 @@ from typing import TYPE_CHECKING, Any, BinaryIO, Literal, NamedTuple, Optional, Protocol -from htmltools import TagChild - from ._docstring import add_example from ._typing_extensions import NotRequired, TypedDict if TYPE_CHECKING: + from htmltools import TagChild from matplotlib.figure import Figure diff --git a/shiny/ui/_input_task_button.py b/shiny/ui/_input_task_button.py index 76229e915..bc1d60a0e 100644 --- a/shiny/ui/_input_task_button.py +++ b/shiny/ui/_input_task_button.py @@ -3,7 +3,7 @@ __all__ = ("input_task_button",) from functools import partial -from typing import Callable, Optional, TypeVar, cast, overload +from typing import TYPE_CHECKING, Callable, Optional, TypeVar, cast, overload from htmltools import HTML, Tag, TagAttrValue, TagChild, css, tags @@ -12,11 +12,13 @@ from .._docstring import add_example from .._namespaces import resolve_id from .._typing_extensions import ParamSpec -from ..reactive._extended_task import ExtendedTask from ..reactive._reactives import effect from ._html_deps_py_shiny import spin_dependency from ._html_deps_shinyverse import components_dependencies +if TYPE_CHECKING: + from ..reactive._extended_task import ExtendedTask + P = ParamSpec("P") R = TypeVar("R") diff --git a/shiny/ui/_input_update.py b/shiny/ui/_input_update.py index c3c347546..332a11a81 100644 --- a/shiny/ui/_input_update.py +++ b/shiny/ui/_input_update.py @@ -20,11 +20,9 @@ import json import re -from datetime import date from typing import TYPE_CHECKING, Literal, Mapping, Optional, cast, overload from htmltools import TagChild, TagList, tags -from starlette.requests import Request from starlette.responses import JSONResponse, Response from .._docstring import add_example, doc_format, no_example @@ -41,6 +39,10 @@ from ._utils import JSEval, _session_on_flush_send_msg, extract_js_keys if TYPE_CHECKING: + from datetime import date + + from starlette.requests import Request + from .. import Session diff --git a/shiny/ui/_modal.py b/shiny/ui/_modal.py index c24d164ab..efdd3c65b 100644 --- a/shiny/ui/_modal.py +++ b/shiny/ui/_modal.py @@ -7,15 +7,17 @@ "modal_remove", ) -from typing import Literal, Optional +from typing import TYPE_CHECKING, Literal, Optional from htmltools import HTML, Tag, TagAttrs, TagAttrValue, TagChild, div, tags from .._docstring import add_example from ..session import require_active_session -from ..session._session import Session from ..types import MISSING, MISSING_TYPE +if TYPE_CHECKING: + from ..session._session import Session + @add_example(ex_dir="../api-examples/modal") def modal_button(label: TagChild, icon: TagChild = None, **kwargs: TagAttrValue) -> Tag: diff --git a/shiny/ui/_notification.py b/shiny/ui/_notification.py index 33593dce2..00804a1a1 100644 --- a/shiny/ui/_notification.py +++ b/shiny/ui/_notification.py @@ -4,13 +4,13 @@ from typing import TYPE_CHECKING, Any, Literal, Optional -from htmltools import TagChild - from .._docstring import add_example, no_example from .._utils import rand_hex from ..session import require_active_session if TYPE_CHECKING: + from htmltools import TagChild + from .. import Session diff --git a/shiny/ui/_progress.py b/shiny/ui/_progress.py index 61425bad4..f18a682da 100644 --- a/shiny/ui/_progress.py +++ b/shiny/ui/_progress.py @@ -2,17 +2,18 @@ __all__ = ("Progress",) -from types import TracebackType from typing import TYPE_CHECKING, Optional, Type from warnings import warn from .._docstring import add_example from .._utils import rand_hex from ..session import require_active_session -from ..session._session import UpdateProgressMessage if TYPE_CHECKING: + from types import TracebackType + from .. import Session + from ..session._session import UpdateProgressMessage @add_example() diff --git a/shiny/ui/_utils.py b/shiny/ui/_utils.py index aa9d80a95..d526ad3ff 100644 --- a/shiny/ui/_utils.py +++ b/shiny/ui/_utils.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Dict, List, Optional, cast, overload +from typing import TYPE_CHECKING, Any, Dict, List, Optional, cast, overload from htmltools import ( HTMLDependency, @@ -12,10 +12,12 @@ tags, ) -from .._typing_extensions import TypeGuard from ..session import Session, require_active_session from ..types import MISSING, MISSING_TYPE +if TYPE_CHECKING: + from .._typing_extensions import TypeGuard + def shiny_input_label(id: str, label: TagChild = None) -> Tag: cls = "control-label" + ("" if label else " shiny-label-null") diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py index f7d1df855..204167cf5 100644 --- a/tests/playwright/conftest.py +++ b/tests/playwright/conftest.py @@ -10,9 +10,9 @@ from contextlib import contextmanager from pathlib import PurePath from time import sleep -from types import TracebackType from typing import ( IO, + TYPE_CHECKING, Any, Callable, Generator, @@ -27,7 +27,6 @@ import pytest import shiny._utils -from shiny._typing_extensions import Self __all__ = ( "ShinyAppProc", @@ -40,7 +39,13 @@ "retry_with_timeout", ) -from playwright.sync_api import BrowserContext, Page + +if TYPE_CHECKING: + from types import TracebackType + + from playwright.sync_api import BrowserContext, Page + + from shiny._typing_extensions import Self # Make a single page fixture that can be used by all tests diff --git a/tests/playwright/controls.py b/tests/playwright/controls.py index fb4db85f1..fde8d762d 100644 --- a/tests/playwright/controls.py +++ b/tests/playwright/controls.py @@ -3,7 +3,6 @@ from __future__ import annotations import json -import pathlib import re import sys import time @@ -22,6 +21,9 @@ ) from shiny.types import MISSING, MISSING_TYPE +if typing.TYPE_CHECKING: + import pathlib + """ Questions: * `_DateBase` is signaled as private, but `InputDateRange` will have two fields of `date_start` and `date_end`. Due to how the init selectors are created, they are not `InputDate` instances. Should we make `_DateBase` public? diff --git a/tests/playwright/shiny/TODO/navbar/app.py b/tests/playwright/shiny/TODO/navbar/app.py index d1a750dbc..eca2ba3f5 100644 --- a/tests/playwright/shiny/TODO/navbar/app.py +++ b/tests/playwright/shiny/TODO/navbar/app.py @@ -1,7 +1,11 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from shiny import App, ui -from shiny.types import NavSetArg + +if TYPE_CHECKING: + from shiny.types import NavSetArg my_sidebar = ui.sidebar("Sidebar content", open="open", title="Sidebar title") diff --git a/tests/playwright/shiny/bugs/0648-update-slider-datetime-value/test_update_slider_datetime_value.py b/tests/playwright/shiny/bugs/0648-update-slider-datetime-value/test_update_slider_datetime_value.py index b569d0de7..d8e398386 100644 --- a/tests/playwright/shiny/bugs/0648-update-slider-datetime-value/test_update_slider_datetime_value.py +++ b/tests/playwright/shiny/bugs/0648-update-slider-datetime-value/test_update_slider_datetime_value.py @@ -1,11 +1,13 @@ from __future__ import annotations -from typing import Optional +from typing import TYPE_CHECKING, Optional -from conftest import ShinyAppProc from controls import InputActionButton, InputSlider, OutputTextVerbatim from playwright.sync_api import Page, expect +if TYPE_CHECKING: + from conftest import ShinyAppProc + def test_slider_app(page: Page, local_app: ShinyAppProc) -> None: def check_case( diff --git a/tests/playwright/shiny/bugs/0666-sidebar/test_sidebar_colors.py b/tests/playwright/shiny/bugs/0666-sidebar/test_sidebar_colors.py index e376d16ed..0a72b89d0 100644 --- a/tests/playwright/shiny/bugs/0666-sidebar/test_sidebar_colors.py +++ b/tests/playwright/shiny/bugs/0666-sidebar/test_sidebar_colors.py @@ -1,10 +1,14 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from colors import bg_color, fg_color -from conftest import ShinyAppProc from controls import Sidebar, _expect_class_value from playwright.sync_api import Page, expect +if TYPE_CHECKING: + from conftest import ShinyAppProc + def test_colors_are_rgb() -> None: assert bg_color.startswith("rgb(") diff --git a/tests/playwright/shiny/bugs/0676-row-selection/test_0676_row_selection.py b/tests/playwright/shiny/bugs/0676-row-selection/test_0676_row_selection.py index 9f83665ec..8362f3937 100644 --- a/tests/playwright/shiny/bugs/0676-row-selection/test_0676_row_selection.py +++ b/tests/playwright/shiny/bugs/0676-row-selection/test_0676_row_selection.py @@ -1,8 +1,12 @@ from __future__ import annotations -from conftest import ShinyAppProc +from typing import TYPE_CHECKING + from playwright.sync_api import Page, expect +if TYPE_CHECKING: + from conftest import ShinyAppProc + def test_row_selection(page: Page, local_app: ShinyAppProc) -> None: page.goto(local_app.url) diff --git a/tests/playwright/shiny/bugs/0696-resolve-id/app.py b/tests/playwright/shiny/bugs/0696-resolve-id/app.py index c7e45667f..8dd4c7b3e 100644 --- a/tests/playwright/shiny/bugs/0696-resolve-id/app.py +++ b/tests/playwright/shiny/bugs/0696-resolve-id/app.py @@ -17,7 +17,9 @@ from shiny import App, Inputs, Outputs, Session, module, reactive, render, ui from shiny.session import session_context -from shiny.types import ImgData + +if typing.TYPE_CHECKING: + from shiny.types import ImgData pandas_df = pd.DataFrame( { diff --git a/tests/playwright/shiny/bugs/0696-resolve-id/mod_state.py b/tests/playwright/shiny/bugs/0696-resolve-id/mod_state.py index 4a0ad4210..94fe831be 100644 --- a/tests/playwright/shiny/bugs/0696-resolve-id/mod_state.py +++ b/tests/playwright/shiny/bugs/0696-resolve-id/mod_state.py @@ -1,9 +1,12 @@ from __future__ import annotations import datetime +from typing import TYPE_CHECKING from controls import OutputTextVerbatim -from playwright.sync_api import Page + +if TYPE_CHECKING: + from playwright.sync_api import Page def expect_state( diff --git a/tests/playwright/shiny/bugs/0696-resolve-id/test_0696_resolve_id.py b/tests/playwright/shiny/bugs/0696-resolve-id/test_0696_resolve_id.py index 299bbb264..f5cc68c66 100644 --- a/tests/playwright/shiny/bugs/0696-resolve-id/test_0696_resolve_id.py +++ b/tests/playwright/shiny/bugs/0696-resolve-id/test_0696_resolve_id.py @@ -4,9 +4,9 @@ import datetime import os from pathlib import Path +from typing import TYPE_CHECKING import pytest -from conftest import ShinyAppProc from controls import ( DownloadButton, DownloadLink, @@ -33,11 +33,14 @@ OutputUi, ) from mod_state import expect_default_mod_state, expect_mod_state -from playwright.sync_api import Page from examples.example_apps import reruns, reruns_delay from shiny._utils import guess_mime_type +if TYPE_CHECKING: + from conftest import ShinyAppProc + from playwright.sync_api import Page + img_path = Path(__file__).parent / "imgs" penguin_imgs = [str(img_path / img) for img in os.listdir(img_path)] diff --git a/tests/playwright/shiny/components/layout_columns/test_layout_columns.py b/tests/playwright/shiny/components/layout_columns/test_layout_columns.py index 38f421c22..c3b0dd429 100644 --- a/tests/playwright/shiny/components/layout_columns/test_layout_columns.py +++ b/tests/playwright/shiny/components/layout_columns/test_layout_columns.py @@ -1,9 +1,11 @@ from __future__ import annotations -from typing import TypeVar +from typing import TYPE_CHECKING, TypeVar from conftest import ShinyAppProc, create_doc_example_core_fixture -from playwright.sync_api import Page + +if TYPE_CHECKING: + from playwright.sync_api import Page T = TypeVar("T") diff --git a/tests/playwright/shiny/components/nav/app.py b/tests/playwright/shiny/components/nav/app.py index ffe36f163..6b49b1dda 100644 --- a/tests/playwright/shiny/components/nav/app.py +++ b/tests/playwright/shiny/components/nav/app.py @@ -1,12 +1,14 @@ from __future__ import annotations -from typing import Any, Callable, List - -from htmltools import Tag +from typing import TYPE_CHECKING, Any, Callable, List from shiny import App, ui -from shiny.types import NavSetArg -from shiny.ui import Sidebar + +if TYPE_CHECKING: + from htmltools import Tag + + from shiny.types import NavSetArg + from shiny.ui import Sidebar # TODO-karan; Make test that uses sidebar / no sidebar (where possible) # TODO-karan; Make test that has/does not have a header & footer (where possible) diff --git a/tests/playwright/shiny/components/nav/test_nav.py b/tests/playwright/shiny/components/nav/test_nav.py index 546f81090..d6a80859d 100644 --- a/tests/playwright/shiny/components/nav/test_nav.py +++ b/tests/playwright/shiny/components/nav/test_nav.py @@ -1,9 +1,9 @@ from __future__ import annotations from dataclasses import dataclass +from typing import TYPE_CHECKING import pytest -from conftest import ShinyAppProc from controls import ( LayoutNavSetBar, LayoutNavSetCardPill, @@ -14,7 +14,10 @@ LayoutNavsetTab, LayoutNavSetUnderline, ) -from playwright.sync_api import Page + +if TYPE_CHECKING: + from conftest import ShinyAppProc + from playwright.sync_api import Page @pytest.mark.skip_browser("webkit") diff --git a/tests/playwright/shiny/inputs/input_file/app.py b/tests/playwright/shiny/inputs/input_file/app.py index 2706d23be..d825a0b75 100644 --- a/tests/playwright/shiny/inputs/input_file/app.py +++ b/tests/playwright/shiny/inputs/input_file/app.py @@ -5,7 +5,9 @@ import pandas as pd from shiny import App, Inputs, Outputs, Session, reactive, render, req, ui -from shiny.types import FileInfo + +if typing.TYPE_CHECKING: + from shiny.types import FileInfo app_ui = ui.page_fluid( ui.input_file("file1", "Choose CSV File", accept=[".csv"], multiple=False), diff --git a/tests/playwright/shiny/inputs/input_file/test_input_file.py b/tests/playwright/shiny/inputs/input_file/test_input_file.py index 953c1ea35..be11c3120 100644 --- a/tests/playwright/shiny/inputs/input_file/test_input_file.py +++ b/tests/playwright/shiny/inputs/input_file/test_input_file.py @@ -1,9 +1,13 @@ from __future__ import annotations -from conftest import ShinyAppProc +from typing import TYPE_CHECKING + from controls import InputFile, OutputTable, OutputTextVerbatim from playwright.sync_api import FilePayload, Page, expect +if TYPE_CHECKING: + from conftest import ShinyAppProc + def test_input_file_kitchen(page: Page, local_app: ShinyAppProc) -> None: page.goto(local_app.url) diff --git a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py index 84974564a..360a63434 100644 --- a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py +++ b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py @@ -1,10 +1,14 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pytest -from conftest import ShinyAppProc from controls import InputCheckboxGroup, InputRadioButtons, PatternOrStr from playwright.sync_api import Page, expect +if TYPE_CHECKING: + from conftest import ShinyAppProc + def test_input_checkbox_group_kitchen(page: Page, local_app: ShinyAppProc) -> None: page.goto(local_app.url) diff --git a/tests/playwright/shiny/inputs/input_task_button/test_input_task_button.py b/tests/playwright/shiny/inputs/input_task_button/test_input_task_button.py index f90ce3d5b..767f1c5a2 100644 --- a/tests/playwright/shiny/inputs/input_task_button/test_input_task_button.py +++ b/tests/playwright/shiny/inputs/input_task_button/test_input_task_button.py @@ -1,10 +1,13 @@ from __future__ import annotations import time +from typing import TYPE_CHECKING -from conftest import ShinyAppProc from controls import InputNumeric, InputTaskButton, OutputText -from playwright.sync_api import Page + +if TYPE_CHECKING: + from conftest import ShinyAppProc + from playwright.sync_api import Page def click_extended_task_button( diff --git a/tests/playwright/shiny/inputs/input_task_button2/test_input_task_button2.py b/tests/playwright/shiny/inputs/input_task_button2/test_input_task_button2.py index 85da00177..77a6cc825 100644 --- a/tests/playwright/shiny/inputs/input_task_button2/test_input_task_button2.py +++ b/tests/playwright/shiny/inputs/input_task_button2/test_input_task_button2.py @@ -1,8 +1,12 @@ from __future__ import annotations -from conftest import ShinyAppProc +from typing import TYPE_CHECKING + from controls import InputTaskButton, OutputText -from playwright.sync_api import Page + +if TYPE_CHECKING: + from conftest import ShinyAppProc + from playwright.sync_api import Page def click_extended_task_button( diff --git a/tests/playwright/shiny/inputs/test_input_dark_mode.py b/tests/playwright/shiny/inputs/test_input_dark_mode.py index d5c793566..607e59c8e 100644 --- a/tests/playwright/shiny/inputs/test_input_dark_mode.py +++ b/tests/playwright/shiny/inputs/test_input_dark_mode.py @@ -1,8 +1,12 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from conftest import ShinyAppProc, create_doc_example_core_fixture from controls import InputActionButton, InputDarkMode, LayoutNavSetBar -from playwright.sync_api import Page + +if TYPE_CHECKING: + from playwright.sync_api import Page app = create_doc_example_core_fixture("input_dark_mode") diff --git a/tests/pytest/test_sidebar.py b/tests/pytest/test_sidebar.py index 7709bb226..812e9a9b9 100644 --- a/tests/pytest/test_sidebar.py +++ b/tests/pytest/test_sidebar.py @@ -1,12 +1,14 @@ from __future__ import annotations -from typing import Literal +from typing import TYPE_CHECKING, Literal import pytest from htmltools import Tag, TagAttrValue from shiny import ui -from shiny.ui._sidebar import SidebarOpenSpec, SidebarOpenValue + +if TYPE_CHECKING: + from shiny.ui._sidebar import SidebarOpenSpec, SidebarOpenValue _s = ui.sidebar("Sidebar!") _m = "Body" From c32368ff1653f2a491ae210b41d43d625cdb5191 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:21:48 -0400 Subject: [PATCH 34/56] Drop pandas-vet --- ruff.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 8ecdaf59c..556c5b555 100644 --- a/ruff.toml +++ b/ruff.toml @@ -53,7 +53,6 @@ extend-ignore = [ # SIM118; flake8-simplify Use `key {operator} dict`: https://docs.astral.sh/ruff/rules/#flake8-simplify-sim # TCH; flake8-type-checking: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch # FIX; flake8-fixme: https://docs.astral.sh/ruff/rules/#flake8-fixme-fix -# PD; pandas-vet: https://docs.astral.sh/ruff/rules/#pandas-vet-pd # PGH; pygrep-hooks: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh # FLY; flynt: https://docs.astral.sh/ruff/rules/#flynt-fly # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy @@ -80,7 +79,6 @@ extend-select = [ "SIM118", "TCH", # "FIX", - # "PD", # "PGH", # "FLY", # "NPY", From 9b35e7c1302027a2f260458ed19cbe8383e1079a Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:23:13 -0400 Subject: [PATCH 35/56] flynt --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index 556c5b555..383b532db 100644 --- a/ruff.toml +++ b/ruff.toml @@ -80,7 +80,7 @@ extend-select = [ "TCH", # "FIX", # "PGH", - # "FLY", + "FLY", # "NPY", # "RUF100", # "RUF005", From d7da495cf8c248bd3ea87548e57806eba431ad0d Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:23:21 -0400 Subject: [PATCH 36/56] Auto fix flynt --- shiny/ui/_modal.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/shiny/ui/_modal.py b/shiny/ui/_modal.py index efdd3c65b..18fb736ec 100644 --- a/shiny/ui/_modal.py +++ b/shiny/ui/_modal.py @@ -131,16 +131,7 @@ def modal( ) # jQuery plugin doesn't work in Bootstrap 5, but vanilla JS doesn't work in Bootstrap 4 :sob: - js = "\n".join( - [ - "if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\. /)) {", - " var modal=new bootstrap.Modal(document.getElementById('shiny-modal'))", - " modal.show()", - "} else {", - " $('#shiny-modal').modal().focus()", - "}", - ] - ) + js = "if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\. /)) {\n var modal=new bootstrap.Modal(document.getElementById('shiny-modal'))\n modal.show()\n} else {\n $('#shiny-modal').modal().focus()\n}" backdrop = None if easy_close else "static" keyboard = None if easy_close else "false" From 2c298a556681a75725c59283ee478ad8d7bfcc4f Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:23:49 -0400 Subject: [PATCH 37/56] NumPy-specific rules --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index 383b532db..0783f9665 100644 --- a/ruff.toml +++ b/ruff.toml @@ -81,7 +81,7 @@ extend-select = [ # "FIX", # "PGH", "FLY", - # "NPY", + "NPY", # "RUF100", # "RUF005", ] From 7864da103c488a6b172a1e91a344412b200c32ba Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:24:15 -0400 Subject: [PATCH 38/56] Autofix NumPy-specific rule --- shiny/plotutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shiny/plotutils.py b/shiny/plotutils.py index 8787d78ad..4d7eef4d0 100644 --- a/shiny/plotutils.py +++ b/shiny/plotutils.py @@ -228,7 +228,7 @@ def near_points( # For no current coordinfo if coordinfo is None: if add_dist: - new_df["dist"] = np.NaN + new_df["dist"] = np.nan if all_rows: new_df["selected_"] = False From dcbab568cb206f58d5f0254c41dd8be64d3c4fe7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:36:47 -0400 Subject: [PATCH 39/56] Manually fix many random state lints --- examples/cpuinfo/fakepsutil.py | 5 +++-- examples/express/accordion_app.py | 3 +-- examples/express/column_wrap_app.py | 6 ++---- examples/express/nav_app.py | 6 ++---- examples/express/plot_app.py | 3 +-- examples/express/shared_app.py | 3 +-- examples/express/sidebar_app.py | 3 +-- examples/static_plots/app.py | 5 ++++- shiny/api-examples/download/app-core.py | 8 +++++--- shiny/api-examples/download/app-express.py | 8 +++++--- shiny/api-examples/input_action_button/app-core.py | 3 +-- shiny/api-examples/input_action_button/app-express.py | 3 +-- shiny/api-examples/input_action_link/app-core.py | 3 +-- shiny/api-examples/input_action_link/app-express.py | 3 +-- shiny/api-examples/input_dark_mode/app-core.py | 3 +-- shiny/api-examples/input_dark_mode/app-express.py | 3 +-- shiny/api-examples/input_slider/app-core.py | 3 +-- shiny/api-examples/input_slider/app-express.py | 3 +-- shiny/api-examples/isolate/app-core.py | 3 +-- shiny/api-examples/isolate/app-express.py | 3 +-- shiny/api-examples/layout_columns/model_plots.py | 8 +++++--- shiny/api-examples/layout_sidebar/app-core.py | 3 +-- shiny/api-examples/layout_sidebar/app-express.py | 3 +-- shiny/api-examples/output_plot/app-core.py | 3 +-- shiny/api-examples/output_plot/app-express.py | 3 +-- shiny/api-examples/page_fixed/app-core.py | 3 +-- shiny/api-examples/page_fixed/app-express.py | 3 +-- shiny/api-examples/page_fluid/app-core.py | 3 +-- shiny/api-examples/page_fluid/app-express.py | 3 +-- shiny/api-examples/page_sidebar/app-core.py | 3 +-- shiny/api-examples/page_sidebar/app-express.py | 3 +-- shiny/api-examples/row/app-core.py | 3 +-- 32 files changed, 51 insertions(+), 70 deletions(-) diff --git a/examples/cpuinfo/fakepsutil.py b/examples/cpuinfo/fakepsutil.py index de42c8189..ea3773934 100644 --- a/examples/cpuinfo/fakepsutil.py +++ b/examples/cpuinfo/fakepsutil.py @@ -7,12 +7,13 @@ def cpu_count(logical: bool = True): return 8 if logical else 4 -last_sample = np.random.uniform(0, 100, size=cpu_count(True)) +rnd = np.random.RandomState() +last_sample = rnd.uniform(0, 100, size=cpu_count(True)) def cpu_percent(percpu: bool = False): global last_sample - delta = np.random.normal(scale=10, size=len(last_sample)) + delta = rnd.normal(scale=10, size=len(last_sample)) last_sample = (last_sample + delta).clip(0, 100) if percpu: return last_sample.tolist() diff --git a/examples/express/accordion_app.py b/examples/express/accordion_app.py index fdd722c34..4cb552e4f 100644 --- a/examples/express/accordion_app.py +++ b/examples/express/accordion_app.py @@ -17,6 +17,5 @@ def txt(): @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/column_wrap_app.py b/examples/express/column_wrap_app.py index 5e5c44f06..0dd7666c8 100644 --- a/examples/express/column_wrap_app.py +++ b/examples/express/column_wrap_app.py @@ -12,14 +12,12 @@ @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) with ui.card(): @render.plot def histogram2(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True, color="red") diff --git a/examples/express/nav_app.py b/examples/express/nav_app.py index 0a72627ff..1bbe08040 100644 --- a/examples/express/nav_app.py +++ b/examples/express/nav_app.py @@ -13,8 +13,7 @@ @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) with ui.navset_card_underline(): @@ -25,6 +24,5 @@ def histogram(): @render.plot def histogram2(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n2(), density=True) diff --git a/examples/express/plot_app.py b/examples/express/plot_app.py index 605fe6e62..300f376ea 100644 --- a/examples/express/plot_app.py +++ b/examples/express/plot_app.py @@ -9,6 +9,5 @@ @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/shared_app.py b/examples/express/shared_app.py index 89c587a1c..d7ff51009 100644 --- a/examples/express/shared_app.py +++ b/examples/express/shared_app.py @@ -12,8 +12,7 @@ @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, shared.rv(), density=True) diff --git a/examples/express/sidebar_app.py b/examples/express/sidebar_app.py index ac1e97844..1d72de82a 100644 --- a/examples/express/sidebar_app.py +++ b/examples/express/sidebar_app.py @@ -10,6 +10,5 @@ @render.plot def histogram(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/static_plots/app.py b/examples/static_plots/app.py index b5c928169..ab329bec9 100644 --- a/examples/static_plots/app.py +++ b/examples/static_plots/app.py @@ -54,6 +54,8 @@ def server(input: Inputs, output: Outputs, session: Session): + rnd = np.random.RandomState() + @reactive.calc def fake_data(): n = 5000 @@ -98,7 +100,8 @@ def plotnine(): @render.plot def pandas(): ts = pd.Series( - np.random.randn(1000), index=pd.date_range("1/1/2000", periods=1000) + rnd.randn(1000), + index=pd.date_range("1/1/2000", periods=1000), ) ts = ts.cumsum() return ts.plot() diff --git a/shiny/api-examples/download/app-core.py b/shiny/api-examples/download/app-core.py index 74edfa82d..2b28e0ce9 100644 --- a/shiny/api-examples/download/app-core.py +++ b/shiny/api-examples/download/app-core.py @@ -77,6 +77,8 @@ def make_example(id: str, label: str, title: str, desc: str, extra: Any = None): def server(input: Inputs, output: Outputs, session: Session): + rnd = np.random.RandomState() + @render.download() def download1(): """ @@ -98,8 +100,8 @@ def download2(): """ print(input.num_points()) - x = np.random.uniform(size=input.num_points()) - y = np.random.uniform(size=input.num_points()) + x = rnd.uniform(size=input.num_points()) + y = rnd.uniform(size=input.num_points()) plt.figure() plt.scatter(x, y) plt.title(input.title()) @@ -108,7 +110,7 @@ def download2(): yield buf.getvalue() @render.download( - filename=lambda: f"新型-{date.today().isoformat()}-{np.random.randint(100, 999)}.csv" + filename=lambda: f"新型-{date.today().isoformat()}-{rnd.randint(100, 999)}.csv" ) async def download3(): await asyncio.sleep(0.25) diff --git a/shiny/api-examples/download/app-express.py b/shiny/api-examples/download/app-express.py index 9eaa60647..2edfcecd6 100644 --- a/shiny/api-examples/download/app-express.py +++ b/shiny/api-examples/download/app-express.py @@ -8,6 +8,8 @@ from shiny.express import render, ui +rnd = np.random.RandomState() + ui.page_opts(title="Various download examples") with ui.accordion(open=True): @@ -41,8 +43,8 @@ def download2(): """ print(input.num_points()) - x = np.random.uniform(size=input.num_points()) - y = np.random.uniform(size=input.num_points()) + x = rnd.uniform(size=input.num_points()) + y = rnd.uniform(size=input.num_points()) plt.figure() plt.scatter(x, y) plt.title(input.title()) @@ -57,7 +59,7 @@ def download2(): @render.download( label="Download filename", - filename=lambda: f"新型-{date.today().isoformat()}-{np.random.randint(100, 999)}.csv", + filename=lambda: f"新型-{date.today().isoformat()}-{rnd.randint(100, 999)}.csv", ) async def download3(): await asyncio.sleep(0.25) diff --git a/shiny/api-examples/input_action_button/app-core.py b/shiny/api-examples/input_action_button/app-core.py index 66f6abe13..cefe4bad5 100644 --- a/shiny/api-examples/input_action_button/app-core.py +++ b/shiny/api-examples/input_action_button/app-core.py @@ -16,8 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_button/app-express.py b/shiny/api-examples/input_action_button/app-express.py index 925ebc4d6..ec832e8d6 100644 --- a/shiny/api-examples/input_action_button/app-express.py +++ b/shiny/api-examples/input_action_button/app-express.py @@ -13,8 +13,7 @@ # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-core.py b/shiny/api-examples/input_action_link/app-core.py index 054ebacaa..08e2adf5e 100644 --- a/shiny/api-examples/input_action_link/app-core.py +++ b/shiny/api-examples/input_action_link/app-core.py @@ -16,8 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-express.py b/shiny/api-examples/input_action_link/app-express.py index 39939d756..30484e3ca 100644 --- a/shiny/api-examples/input_action_link/app-express.py +++ b/shiny/api-examples/input_action_link/app-express.py @@ -13,8 +13,7 @@ # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_dark_mode/app-core.py b/shiny/api-examples/input_dark_mode/app-core.py index 30539ac30..de3beae05 100644 --- a/shiny/api-examples/input_dark_mode/app-core.py +++ b/shiny/api-examples/input_dark_mode/app-core.py @@ -45,8 +45,7 @@ def _(): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_dark_mode/app-express.py b/shiny/api-examples/input_dark_mode/app-express.py index 063f215d8..c3169d4ef 100644 --- a/shiny/api-examples/input_dark_mode/app-express.py +++ b/shiny/api-examples/input_dark_mode/app-express.py @@ -13,8 +13,7 @@ @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_slider/app-core.py b/shiny/api-examples/input_slider/app-core.py index c8a238506..1cc773799 100644 --- a/shiny/api-examples/input_slider/app-core.py +++ b/shiny/api-examples/input_slider/app-core.py @@ -12,8 +12,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def distPlot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/input_slider/app-express.py b/shiny/api-examples/input_slider/app-express.py index e6e701594..9394d3ec9 100644 --- a/shiny/api-examples/input_slider/app-express.py +++ b/shiny/api-examples/input_slider/app-express.py @@ -8,8 +8,7 @@ @render.plot def distPlot(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/isolate/app-core.py b/shiny/api-examples/isolate/app-core.py index f6a12559d..db9585d87 100644 --- a/shiny/api-examples/isolate/app-core.py +++ b/shiny/api-examples/isolate/app-core.py @@ -18,8 +18,7 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/isolate/app-express.py b/shiny/api-examples/isolate/app-express.py index 52f8b9c38..35abfc9d4 100644 --- a/shiny/api-examples/isolate/app-express.py +++ b/shiny/api-examples/isolate/app-express.py @@ -15,8 +15,7 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(input.n()) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/layout_columns/model_plots.py b/shiny/api-examples/layout_columns/model_plots.py index 951204df9..6446fdb9e 100644 --- a/shiny/api-examples/layout_columns/model_plots.py +++ b/shiny/api-examples/layout_columns/model_plots.py @@ -3,10 +3,12 @@ from shiny import ui +rnd = np.random.RandomState() + def plot_loss_over_time(): epochs = np.arange(1, 101) - loss = 1000 / np.sqrt(epochs) + np.random.rand(100) * 25 + loss = 1000 / np.sqrt(epochs) + rnd.rand(100) * 25 fig = plt.figure(figsize=(10, 6)) plt.plot(epochs, loss) @@ -17,7 +19,7 @@ def plot_loss_over_time(): def plot_accuracy_over_time(): epochs = np.arange(1, 101) - accuracy = np.sqrt(epochs) / 12 + np.random.rand(100) * 0.15 + accuracy = np.sqrt(epochs) / 12 + rnd.rand(100) * 0.15 accuracy = [np.min([np.max(accuracy[:i]), 1]) for i in range(1, 101)] fig = plt.figure(figsize=(10, 6)) @@ -29,7 +31,7 @@ def plot_accuracy_over_time(): def plot_feature_importance(): features = ["Product Category", "Price", "Brand", "Rating", "Number of Reviews"] - importance = np.random.rand(5) + importance = rnd.rand(5) fig = plt.figure(figsize=(10, 6)) plt.barh(features, importance) diff --git a/shiny/api-examples/layout_sidebar/app-core.py b/shiny/api-examples/layout_sidebar/app-core.py index 78e36e744..913e76ca0 100644 --- a/shiny/api-examples/layout_sidebar/app-core.py +++ b/shiny/api-examples/layout_sidebar/app-core.py @@ -16,8 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/layout_sidebar/app-express.py b/shiny/api-examples/layout_sidebar/app-express.py index 10482a396..782cab3c5 100644 --- a/shiny/api-examples/layout_sidebar/app-express.py +++ b/shiny/api-examples/layout_sidebar/app-express.py @@ -9,8 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/output_plot/app-core.py b/shiny/api-examples/output_plot/app-core.py index 339a1a6b7..48b3ea76e 100644 --- a/shiny/api-examples/output_plot/app-core.py +++ b/shiny/api-examples/output_plot/app-core.py @@ -14,8 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def p(): - np.random.seed(19680801) - x_rand = 100 + 15 * np.random.randn(437) + x_rand = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/output_plot/app-express.py b/shiny/api-examples/output_plot/app-express.py index f328cb6eb..5227eef60 100644 --- a/shiny/api-examples/output_plot/app-express.py +++ b/shiny/api-examples/output_plot/app-express.py @@ -8,8 +8,7 @@ @render.plot def p(): - np.random.seed(19680801) - x_rand = 100 + 15 * np.random.randn(437) + x_rand = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/page_fixed/app-core.py b/shiny/api-examples/page_fixed/app-core.py index 80521e92c..2036d5b30 100644 --- a/shiny/api-examples/page_fixed/app-core.py +++ b/shiny/api-examples/page_fixed/app-core.py @@ -18,8 +18,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fixed/app-express.py b/shiny/api-examples/page_fixed/app-express.py index 91f751edd..aad365661 100644 --- a/shiny/api-examples/page_fixed/app-express.py +++ b/shiny/api-examples/page_fixed/app-express.py @@ -12,8 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-core.py b/shiny/api-examples/page_fluid/app-core.py index a05d3618a..29e2fae5c 100644 --- a/shiny/api-examples/page_fluid/app-core.py +++ b/shiny/api-examples/page_fluid/app-core.py @@ -16,8 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-express.py b/shiny/api-examples/page_fluid/app-express.py index 587ec743a..70c91e22c 100644 --- a/shiny/api-examples/page_fluid/app-express.py +++ b/shiny/api-examples/page_fluid/app-express.py @@ -12,8 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-core.py b/shiny/api-examples/page_sidebar/app-core.py index 8ce58f8b8..d6e5fbeb1 100644 --- a/shiny/api-examples/page_sidebar/app-core.py +++ b/shiny/api-examples/page_sidebar/app-core.py @@ -16,8 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-express.py b/shiny/api-examples/page_sidebar/app-express.py index 4781f851c..815c58e89 100644 --- a/shiny/api-examples/page_sidebar/app-express.py +++ b/shiny/api-examples/page_sidebar/app-express.py @@ -9,8 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/row/app-core.py b/shiny/api-examples/row/app-core.py index be69085a7..54563a7e6 100644 --- a/shiny/api-examples/row/app-core.py +++ b/shiny/api-examples/row/app-core.py @@ -14,8 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - np.random.seed(19680801) - x = 100 + 15 * np.random.randn(437) + x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) From 698e83fe0d909c77ba3fca671bb598169b965ada Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:38:02 -0400 Subject: [PATCH 40/56] Ruff specific rules; Consider {expression} instead of concatenation & Unused `noqa` directive --- ruff.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index 0783f9665..7728f9701 100644 --- a/ruff.toml +++ b/ruff.toml @@ -82,8 +82,8 @@ extend-select = [ # "PGH", "FLY", "NPY", - # "RUF100", - # "RUF005", + "RUF005", + "RUF100", ] [lint.extend-per-file-ignores] From 0a00cb0a5077d679ec91efeaf8cd83b390b3b9b4 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:40:56 -0400 Subject: [PATCH 41/56] Autofix ruff specific rules --- shiny/_docstring.py | 2 +- shiny/_utils.py | 4 ++-- shiny/api-examples/poll/app-core.py | 2 +- shiny/api-examples/poll/app-express.py | 2 +- shiny/render/_try_render_plot.py | 2 +- shiny/render/renderer/__init__.py | 2 +- shiny/session/__init__.py | 2 +- tests/playwright/shiny/session/flush/app.py | 16 ++++++++-------- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/shiny/_docstring.py b/shiny/_docstring.py index 1cd6b8f0d..7b48480eb 100644 --- a/shiny/_docstring.py +++ b/shiny/_docstring.py @@ -45,7 +45,7 @@ def decorator(func: F) -> F: current.extend(["express", "core"]) else: current.append(mode) - setattr(func, "__no_example", current) # noqa: B010 + setattr(func, "__no_example", current) return func return decorator diff --git a/shiny/_utils.py b/shiny/_utils.py index cea322919..89489050e 100644 --- a/shiny/_utils.py +++ b/shiny/_utils.py @@ -424,7 +424,7 @@ def _step(fut: Optional["asyncio.Future[None]"] = None): assert fut.done() try: fut.result() - except BaseException as e: # noqa: B036 + except BaseException as e: exc = e if result_future.cancelled(): @@ -450,7 +450,7 @@ def _step(fut: Optional["asyncio.Future[None]"] = None): except (KeyboardInterrupt, SystemExit) as e: result_future.set_exception(e) raise - except BaseException as e: # noqa: B036 + except BaseException as e: result_future.set_exception(e) else: # If we get here, the coro didn't finish. Schedule it for completion. diff --git a/shiny/api-examples/poll/app-core.py b/shiny/api-examples/poll/app-core.py index 6079a0be4..37ab86486 100644 --- a/shiny/api-examples/poll/app-core.py +++ b/shiny/api-examples/poll/app-core.py @@ -99,7 +99,7 @@ def stock_quotes() -> pd.DataFrame: """ ), ui.input_selectize( - "symbols", "Filter by symbol", [""] + SYMBOLS, multiple=True + "symbols", "Filter by symbol", ["", *SYMBOLS], multiple=True ), ui.output_data_frame("table"), fill=False, diff --git a/shiny/api-examples/poll/app-express.py b/shiny/api-examples/poll/app-express.py index df1f9c2cd..bba5b78ce 100644 --- a/shiny/api-examples/poll/app-express.py +++ b/shiny/api-examples/poll/app-express.py @@ -96,7 +96,7 @@ def stock_quotes() -> pd.DataFrame: case, an in-memory sqlite3) with the help of `shiny.reactive.poll`. """ ) - ui.input_selectize("symbols", "Filter by symbol", [""] + SYMBOLS, multiple=True) + ui.input_selectize("symbols", "Filter by symbol", ["", *SYMBOLS], multiple=True) @render.data_frame def table(): diff --git a/shiny/render/_try_render_plot.py b/shiny/render/_try_render_plot.py index 943087407..dff6e6d47 100644 --- a/shiny/render/_try_render_plot.py +++ b/shiny/render/_try_render_plot.py @@ -137,7 +137,7 @@ def try_render_matplotlib( return (False, None) try: - import matplotlib.pyplot as plt # pyright: ignore[reportUnusedImport] # noqa: F401 + import matplotlib.pyplot as plt # pyright: ignore[reportUnusedImport] pixelratio = plot_size_info.pixelratio diff --git a/shiny/render/renderer/__init__.py b/shiny/render/renderer/__init__.py index b27c921ae..0c5597d35 100644 --- a/shiny/render/renderer/__init__.py +++ b/shiny/render/renderer/__init__.py @@ -1,4 +1,4 @@ -from ._renderer import ( # noqa: F401 +from ._renderer import ( AsyncValueFn, Jsonifiable, Renderer, diff --git a/shiny/session/__init__.py b/shiny/session/__init__.py index 027365ff0..02d6e0be7 100644 --- a/shiny/session/__init__.py +++ b/shiny/session/__init__.py @@ -3,7 +3,7 @@ """ from ._session import Inputs, Outputs, Session -from ._utils import ( # noqa: F401 +from ._utils import ( get_current_session, require_active_session, ) diff --git a/tests/playwright/shiny/session/flush/app.py b/tests/playwright/shiny/session/flush/app.py index a6591e31d..d4aef1026 100644 --- a/tests/playwright/shiny/session/flush/app.py +++ b/tests/playwright/shiny/session/flush/app.py @@ -91,8 +91,8 @@ def call_a( ): def _(): with reactive.isolate(): - all_vals.set(all_vals.get() + (f"a-{suffix}",)) - vals.set(vals.get() + (f"a-{suffix}",)) + all_vals.set((*all_vals.get(), f"a-{suffix}")) + vals.set((*vals.get(), f"a-{suffix}")) return _ @@ -102,12 +102,12 @@ def call_b( ): async def _(): with reactive.isolate(): - all_vals.set(all_vals.get() + (f"bx-{suffix}",)) - vals.set(vals.get() + (f"bx-{suffix}",)) + all_vals.set((*all_vals.get(), f"bx-{suffix}")) + vals.set((*vals.get(), f"bx-{suffix}")) await asyncio.sleep(0) with reactive.isolate(): - all_vals.set(all_vals.get() + (f"by-{suffix}",)) - vals.set(vals.get() + (f"by-{suffix}",)) + all_vals.set((*all_vals.get(), f"by-{suffix}")) + vals.set((*vals.get(), f"by-{suffix}")) return _ @@ -117,8 +117,8 @@ def call_c( ): def _(): with reactive.isolate(): - all_vals.set(all_vals.get() + (f"c-{suffix}",)) - vals.set(vals.get() + (f"c-{suffix}",)) + all_vals.set((*all_vals.get(), f"c-{suffix}")) + vals.set((*vals.get(), f"c-{suffix}")) return _ From 6a3827306e1a563d762e67e044e3cd79e4237dfb Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:41:05 -0400 Subject: [PATCH 42/56] Manually fix ruff specific rules --- tests/playwright/examples/example_apps.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright/examples/example_apps.py b/tests/playwright/examples/example_apps.py index 2c954106a..8b3ebc0a4 100644 --- a/tests/playwright/examples/example_apps.py +++ b/tests/playwright/examples/example_apps.py @@ -208,11 +208,11 @@ def on_console_msg(msg: ConsoleMessage) -> None: app_allowable_errors = [app_allowable_errors] app_allowable_errors = ( # Remove ^INFO lines - ["INFO:"] + *["INFO:"], # Remove any known errors caused by external packages - + app_allow_external_errors + *app_allow_external_errors, # Remove any known errors allowed by the app - + app_allowable_errors + *app_allowable_errors, ) # If there is an array of allowable errors, remove them from errors. Ex: `PlotnineWarning` From 4b0bbd3006cb4c686b7c166b8b2ff865d0e87dcf Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:44:56 -0400 Subject: [PATCH 43/56] Update Makefile --- Makefile | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 644884f93..09e94fa63 100644 --- a/Makefile +++ b/Makefile @@ -187,14 +187,11 @@ clean-test: FORCE ## remove test and coverage artifacts # ----------------- check: check-lint check-types check-tests ## check code, style, types, and test (basic CI) check-fix: format check-lint check-types check-tests ## check and format code, style, types, and test -check-lint: check-ruff ## check code formatting and style +check-lint: check-ruff ## check code lints and format check-ruff: $(RUFF) FORCE - @echo "-------- Running ruff lint and formatting checks --------" + @echo "-------- Running ruff lint and format checks --------" @# Check imports in addition to code - @# Reason for two commands: https://github.com/astral-sh/ruff/issues/8232 - # . $(PYBIN)/activate && \ - # ruff check --select I --fix . # Check lints . $(PYBIN)/activate && \ ruff check . @@ -225,7 +222,7 @@ format: format-ruff ## format code format-ruff: $(RUFF) FORCE @echo "-------- Formatting code with ruff --------" @# Reason for two commands: https://github.com/astral-sh/ruff/issues/8232 - @# Fix imports + @# Fix lints . $(PYBIN)/activate && \ ruff check --fix . @# Fix formatting From 7f4eb86cc5a9c5190d54fdd9f76f89f6fabacdc7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 00:54:43 -0400 Subject: [PATCH 44/56] Remove duplicate work --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 09e94fa63..79826e1eb 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ clean-test: FORCE ## remove test and coverage artifacts # Check lint, test, and format of code # ----------------- check: check-lint check-types check-tests ## check code, style, types, and test (basic CI) -check-fix: format check-lint check-types check-tests ## check and format code, style, types, and test +check-fix: format check-types check-tests ## check and format code, style, types, and test check-lint: check-ruff ## check code lints and format check-ruff: $(RUFF) FORCE From d57d8f3af88dcac5ab71e5b174fdba17935942b7 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 01:30:20 -0400 Subject: [PATCH 45/56] Do not auto update fixtures from return to yield statements --- ruff.toml | 1 + tests/playwright/conftest.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 7728f9701..4a7896166 100644 --- a/ruff.toml +++ b/ruff.toml @@ -14,6 +14,7 @@ extend-exclude = [ extend-ignore = [ "E501", # E501: Line too long "PT011", # PT011 `pytest.raises(ValueError)` is too broad + "PT022", # PT022 [*] No teardown in fixture # Conflicting lint rules: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "E111", # * indentation-with-invalid-multiple (E111) "E114", # * indentation-with-invalid-multiple-comment (E114) diff --git a/tests/playwright/conftest.py b/tests/playwright/conftest.py index 204167cf5..95d5a3b92 100644 --- a/tests/playwright/conftest.py +++ b/tests/playwright/conftest.py @@ -234,7 +234,7 @@ def fixture_func(): # Pass through `yield` via `next(...)` call # (`yield` must be on same line as `next`!) app_gen = local_app_fixture_gen(app) - return next(app_gen) + yield next(app_gen) return fixture_func @@ -285,9 +285,9 @@ def x_create_doc_example_fixture(example_name: str, scope: ScopeName = "module") @pytest.fixture(scope="module") -def local_app(request: pytest.FixtureRequest) -> ShinyAppProc: +def local_app(request: pytest.FixtureRequest) -> Generator[ShinyAppProc, None, None]: app_gen = local_app_fixture_gen(PurePath(request.path).parent / "app.py") - return next(app_gen) + yield next(app_gen) @contextmanager From 356394af2c2dad855bda209dea42b022dd96864f Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 01:30:37 -0400 Subject: [PATCH 46/56] fix some assertions by checking the value --- .../test_input_radio_checkbox_group_app.py | 30 ++++++++++--------- tests/pytest/test_sidebar.py | 8 ++--- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py index 360a63434..cafadac14 100644 --- a/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py +++ b/tests/playwright/shiny/inputs/input_radio_checkbox_group/test_input_radio_checkbox_group_app.py @@ -96,8 +96,8 @@ def test_locator_debugging(page: Page, local_app: ShinyAppProc) -> None: with pytest.raises(AssertionError) as e: not_exist.expect_choices(["a", "b", "c"], timeout=timeout) - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + assert "expected to have count '1'" in str(e.value) + assert "Actual value: 0" in str(e.value) check1 = InputCheckboxGroup(page, "check1") @@ -106,18 +106,18 @@ def test_locator_debugging(page: Page, local_app: ShinyAppProc) -> None: # Too many with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green", "blue", "test_value"], timeout=timeout) - assert "expected to have count '4'" in str(e) - assert "Actual value: 3" in str(e) + assert "expected to have count '4'" in str(e.value) + assert "Actual value: 3" in str(e.value) # Not enough with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green"], timeout=timeout) - assert "expected to have count '2'" in str(e) - assert "Actual value: 3" in str(e) + assert "expected to have count '2'" in str(e.value) + assert "Actual value: 3" in str(e.value) # Wrong value with pytest.raises(AssertionError) as e: check1.expect_choices(["red", "green", "test_value"], timeout=timeout) - assert "attribute 'test_value'" in str(e) - assert "Actual value: blue" in str(e) + assert "attribute 'test_value'" in str(e.value) + assert "Actual value: blue" in str(e.value) def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: @@ -129,8 +129,10 @@ def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: not_exist = InputCheckboxGroup(page, "does-not-exist") with pytest.raises(AssertionError) as e: not_exist.set(["green"], timeout=timeout) - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + + print(str(e.value)) + assert "expected to have count '1'" in str(e.value) + assert "Actual value: 0" in str(e.value) check1 = InputCheckboxGroup(page, "check1") @@ -143,14 +145,14 @@ def test_locator_existance(page: Page, local_app: ShinyAppProc) -> None: # Different value with pytest.raises(AssertionError) as e: check1.set(["test_value"], timeout=timeout) - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + assert "expected to have count '1'" in str(e.value) + assert "Actual value: 0" in str(e.value) # Extra value with pytest.raises(AssertionError) as e: check1.set(["blue", "test_value"], timeout=timeout) - assert "expected to have count '1'" in str(e) - assert "Actual value: 0" in str(e) + assert "expected to have count '1'" in str(e.value) + assert "Actual value: 0" in str(e.value) check1.expect_selected(["green"]) diff --git a/tests/pytest/test_sidebar.py b/tests/pytest/test_sidebar.py index 812e9a9b9..66c4597a6 100644 --- a/tests/pytest/test_sidebar.py +++ b/tests/pytest/test_sidebar.py @@ -29,21 +29,21 @@ def test_panel_main_and_panel_sidebar(): with pytest.raises(ValueError) as e: ui.layout_sidebar(_s, _s) - assert "multiple `sidebar()` objects" in str(e) + assert "multiple `sidebar()` objects" in str(e.value) with pytest.raises(ValueError) as e: ui.layout_sidebar(None, _ps) # pyright: ignore[reportArgumentType] - assert "not being supplied with a `sidebar()` object" in str(e) + assert "not being supplied with a `sidebar()` object" in str(e.value) with pytest.raises(ValueError) as e: ui.layout_sidebar(_s, _pm) - assert "is not being used with `panel_sidebar()`" in str(e) + assert "is not being used with `panel_sidebar()`" in str(e.value) with pytest.raises(ValueError, match="not being supplied as the second argument"): ui.layout_sidebar(_ps, None, _pm) with pytest.raises(ValueError) as e: ui.layout_sidebar(_ps, _pm, None, "42") - assert "Unexpected extra legacy `*args`" in str(e) + assert "Unexpected extra legacy `*args`" in str(e.value) @pytest.mark.parametrize( From 1cb1fcea2cc643a2288782a8dea5c6cb5d17e41c Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 13:54:27 -0400 Subject: [PATCH 47/56] Consolidate lines --- ruff.toml | 75 +++++++++++++++++++------------------------------------ 1 file changed, 26 insertions(+), 49 deletions(-) diff --git a/ruff.toml b/ruff.toml index 7286886e9..97f126beb 100644 --- a/ruff.toml +++ b/ruff.toml @@ -34,57 +34,34 @@ extend-ignore = [ # Rules to add https://docs.astral.sh/ruff/rules/ # Default `select = ["E4", "E7", "E9", "F"]` -# E4, E7, E9; pycodestyle: https://docs.astral.sh/ruff/rules/#pycodestyle-e-w -# F; Pyflakes: https://docs.astral.sh/ruff/rules/#pyflakes-f -# I; isort: https://docs.astral.sh/ruff/rules/#isort-i -# B; flake8-bugbear: https://docs.astral.sh/ruff/rules/#flake8-bugbear-b -# Q; flake8-quotes: https://docs.astral.sh/ruff/rules/#flake8-quotes-q -# C90; mccabe: https://docs.astral.sh/ruff/rules/complex-structure/ -# COM; Commas: https://docs.astral.sh/ruff/rules/#flake8-commas-com -# C4; flake8-comprehensions: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 -# DTZ; flake8-datetimez: https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz -# FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa -# ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc -# ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn -# PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie -# PYI013; flake8-pyi Non-empty class body must not contain `...`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi -# PYI030; flake8-pyi Multiple literal members in a union: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi -# PYI034; flake8-pyi `__new__` methods usually reutrn `Self`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi -# PT; flake8-pytest-style: https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt -# SIM118; flake8-simplify Use `key {operator} dict`: https://docs.astral.sh/ruff/rules/#flake8-simplify-sim -# TCH; flake8-type-checking: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch -# FIX; flake8-fixme: https://docs.astral.sh/ruff/rules/#flake8-fixme-fix -# PGH; pygrep-hooks: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh -# FLY; flynt: https://docs.astral.sh/ruff/rules/#flynt-fly -# NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy -# RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf -# RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf + extend-select = [ - # "C90", # Many false positives - # "DTZ", # Dates with timezones are different from dates without timezones + # "C90", # Many false positives # C90; mccabe: https://docs.astral.sh/ruff/rules/complex-structure/ + # "DTZ", # Dates with timezones are different from dates without timezones # DTZ; flake8-datetimez: https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz - "E", - "I", - "B", - "Q", - "COM", - "C4", - "FA102", - "ISC", - "ICN", - "PIE", - "PYI013", - "PYI030", - "PYI034", - "PT", - "SIM118", - "TCH", - # "FIX", - # "PGH", - "FLY", - "NPY", - "RUF005", - "RUF100", + "E", # E; pycodestyle: https://docs.astral.sh/ruff/rules/#pycodestyle-e-w + "F", # F; Pyflakes: https://docs.astral.sh/ruff/rules/#pyflakes-f + "I", # I; isort: https://docs.astral.sh/ruff/rules/#isort-i + "B", # B; flake8-bugbear: https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "Q", # Q; flake8-quotes: https://docs.astral.sh/ruff/rules/#flake8-quotes-q + "COM", # COM; Commas: https://docs.astral.sh/ruff/rules/#flake8-commas-com + "C4", # C4; flake8-comprehensions: https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "FA102", # FA102; flake8-future-annotations: https://docs.astral.sh/ruff/rules/#flake8-future-annotations-fa + "ISC", # ISC; flake8-implicit-str-concat: https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc + "ICN", # ICN; flake8-import-conventions: https://docs.astral.sh/ruff/rules/#flake8-import-conventions-icn + "PIE", # PIE; flake8-pie: https://docs.astral.sh/ruff/rules/#flake8-pie-pie + "PYI013", # PYI013; flake8-pyi Non-empty class body must not contain `...`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi + "PYI030", # PYI030; flake8-pyi Multiple literal members in a union: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi + "PYI034", # PYI034; flake8-pyi `__new__` methods usually reutrn `Self`: https://docs.astral.sh/ruff/rules/#flake8-pyi-pyi + "PT", # PT; flake8-pytest-style: https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt + "SIM118", # SIM118; flake8-simplify Use `key {operator} dict`: https://docs.astral.sh/ruff/rules/#flake8-simplify-sim + "TCH", # TCH; flake8-type-checking: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch + # "FIX", # FIX; flake8-fixme: https://docs.astral.sh/ruff/rules/#flake8-fixme-fix + # "PGH", # PGH; pygrep-hooks: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh + "FLY", # FLY; flynt: https://docs.astral.sh/ruff/rules/#flynt-fly + "NPY", # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy + "RUF005", # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf + "RUF100", # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf ] [lint.extend-per-file-ignores] From 9b140caf656fb4a0c6a867d06e047bed6aa03542 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 13:55:50 -0400 Subject: [PATCH 48/56] Code feedback --- shiny/api-examples/remove_accordion_panel/app-core.py | 2 +- .../remove_accordion_panel/app-express.py | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/shiny/api-examples/remove_accordion_panel/app-core.py b/shiny/api-examples/remove_accordion_panel/app-core.py index 0c2caac02..fc473c077 100644 --- a/shiny/api-examples/remove_accordion_panel/app-core.py +++ b/shiny/api-examples/remove_accordion_panel/app-core.py @@ -27,7 +27,7 @@ def make_panel(letter: str) -> ui.AccordionPanel: def server(input: Inputs, output: Outputs, session: Session): # Copy the list for user - user_choices = list(choices) + user_choices = choices.copy() @reactive.effect @reactive.event(input.remove_panel) diff --git a/shiny/api-examples/remove_accordion_panel/app-express.py b/shiny/api-examples/remove_accordion_panel/app-express.py index 2c1042c57..ce2138077 100644 --- a/shiny/api-examples/remove_accordion_panel/app-express.py +++ b/shiny/api-examples/remove_accordion_panel/app-express.py @@ -20,19 +20,16 @@ f"Some narrative for section {letter}" -user_choices = list(choices) - - @reactive.effect @reactive.event(input.remove_panel) def _(): - if len(user_choices) == 0: + if len(choices) == 0: ui.notification_show("No more panels to remove!") return - ui.remove_accordion_panel("acc", f"Section {user_choices.pop()}") + ui.remove_accordion_panel("acc", f"Section {choices.pop()}") label = "No more panels to remove!" - if len(user_choices) > 0: - label = f"Remove Section {user_choices[-1]}" + if len(choices) > 0: + label = f"Remove Section {choices[-1]}" ui.update_action_button("remove_panel", label=label) From 174a14677da49ab105d1041e36a6bd6c600373e5 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 14:00:42 -0400 Subject: [PATCH 49/56] Disable C408 for file --- shiny/express/ui/_cm_components.py | 167 +++++++++++++++-------------- 1 file changed, 84 insertions(+), 83 deletions(-) diff --git a/shiny/express/ui/_cm_components.py b/shiny/express/ui/_cm_components.py index 7d2002750..f749a9104 100644 --- a/shiny/express/ui/_cm_components.py +++ b/shiny/express/ui/_cm_components.py @@ -1,4 +1,5 @@ "Context manager components for Shiny Express" +# ruff: noqa: C408 # https://docs.astral.sh/ruff/rules/unnecessary-literal-dict/ from __future__ import annotations @@ -658,12 +659,12 @@ def navset_tab( """ return RecallContextManager( ui.navset_tab, - kwargs={ - "id": id, - "selected": selected, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + header=header, + footer=footer, + ), ) @@ -695,12 +696,12 @@ def navset_pill( """ return RecallContextManager( ui.navset_pill, - kwargs={ - "id": id, - "selected": selected, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + header=header, + footer=footer, + ), ) @@ -733,12 +734,12 @@ def navset_underline( """ return RecallContextManager( ui.navset_underline, - kwargs={ - "id": id, - "selected": selected, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + header=header, + footer=footer, + ), ) @@ -770,12 +771,12 @@ def navset_hidden( """ return RecallContextManager( ui.navset_hidden, - kwargs={ - "id": id, - "selected": selected, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + header=header, + footer=footer, + ), ) @@ -811,14 +812,14 @@ def navset_card_tab( """ return RecallContextManager( ui.navset_card_tab, - kwargs={ - "id": id, - "selected": selected, - "title": title, - "sidebar": sidebar, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + title=title, + sidebar=sidebar, + header=header, + footer=footer, + ), ) @@ -854,14 +855,14 @@ def navset_card_pill( """ return RecallContextManager( ui.navset_card_pill, - kwargs={ - "id": id, - "selected": selected, - "title": title, - "sidebar": sidebar, - "header": header, - "footer": footer, - }, + kwargs=dict( + id=id, + selected=selected, + title=title, + sidebar=sidebar, + header=header, + footer=footer, + ), ) @@ -900,15 +901,15 @@ def navset_card_underline( """ return RecallContextManager( ui.navset_card_underline, - kwargs={ - "id": id, - "selected": selected, - "title": title, - "sidebar": sidebar, - "header": header, - "footer": footer, - "placement": placement, - }, + kwargs=dict( + id=id, + selected=selected, + title=title, + sidebar=sidebar, + header=header, + footer=footer, + placement=placement, + ), ) @@ -946,14 +947,14 @@ def navset_pill_list( """ return RecallContextManager( ui.navset_pill_list, - kwargs={ - "id": id, - "selected": selected, - "header": header, - "footer": footer, - "well": well, - "widths": widths, - }, + kwargs=dict( + id=id, + selected=selected, + header=header, + footer=footer, + well=well, + widths=widths, + ), ) @@ -1036,23 +1037,23 @@ def navset_bar( """ return RecallContextManager( ui.navset_bar, - kwargs={ - "title": title, - "id": id, - "selected": selected, - "sidebar": sidebar, - "fillable": fillable, - "gap": gap, - "padding": padding, - "position": position, - "header": header, - "footer": footer, - "bg": bg, - "inverse": inverse, - "underline": underline, - "collapsible": collapsible, - "fluid": fluid, - }, + kwargs=dict( + title=title, + id=id, + selected=selected, + sidebar=sidebar, + fillable=fillable, + gap=gap, + padding=padding, + position=position, + header=header, + footer=footer, + bg=bg, + inverse=inverse, + underline=underline, + collapsible=collapsible, + fluid=fluid, + ), ) @@ -1084,10 +1085,10 @@ def nav_panel( return RecallContextManager( ui.nav_panel, args=(title,), - kwargs={ - "value": value, - "icon": icon, - }, + kwargs=dict( + value=value, + icon=icon, + ), ) @@ -1133,11 +1134,11 @@ def nav_menu( return RecallContextManager( ui.nav_menu, args=(title,), - kwargs={ - "value": value, - "icon": icon, - "align": align, - }, + kwargs=dict( + value=value, + icon=icon, + align=align, + ), ) From 062cddc07a69ba6b721663c8936caa12cf75aaff Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 14:11:31 -0400 Subject: [PATCH 50/56] Disable `B904` / revert changes Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling --- examples/airmass/location.py | 2 +- ruff.toml | 1 + shiny/_connection.py | 2 +- shiny/_docstring.py | 4 ++-- shiny/ui/_markdown.py | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/airmass/location.py b/examples/airmass/location.py index f9ca37838..b644c19a5 100644 --- a/examples/airmass/location.py +++ b/examples/airmass/location.py @@ -130,6 +130,6 @@ def location(): long = (long + 180) % 360 - 180 return (input.lat(), long) except ValueError: - raise ValueError("Invalid latitude/longitude specification") from None + raise ValueError("Invalid latitude/longitude specification") return location diff --git a/ruff.toml b/ruff.toml index 97f126beb..d2bab28c5 100644 --- a/ruff.toml +++ b/ruff.toml @@ -15,6 +15,7 @@ extend-ignore = [ "E501", # E501: Line too long "PT011", # PT011 `pytest.raises(ValueError)` is too broad "PT022", # PT022 [*] No teardown in fixture + "B904", # B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling # Conflicting lint rules: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "E111", # * indentation-with-invalid-multiple (E111) "E114", # * indentation-with-invalid-multiple-comment (E114) diff --git a/shiny/_connection.py b/shiny/_connection.py index 846805089..411259eb3 100644 --- a/shiny/_connection.py +++ b/shiny/_connection.py @@ -94,7 +94,7 @@ async def receive(self) -> str: try: return await self.conn.receive_text() except starlette.websockets.WebSocketDisconnect: - raise ConnectionClosed() from None + raise ConnectionClosed() except Exception: # From RFC6455: # 1008 indicates that an endpoint is terminating the connection because it diff --git a/shiny/_docstring.py b/shiny/_docstring.py index 7b48480eb..93395489c 100644 --- a/shiny/_docstring.py +++ b/shiny/_docstring.py @@ -321,9 +321,9 @@ def _(func: F) -> F: except ImportError: raise RuntimeError( "Please install the latest version of shinylive to build the docs." - ) from None + ) except ModuleNotFoundError: - raise RuntimeError("Please install shinylive to build the docs.") from None + raise RuntimeError("Please install shinylive to build the docs.") class ShinyliveExampleWriter(ExampleWriter): def write_example(self, app_files: list[str]) -> str: diff --git a/shiny/ui/_markdown.py b/shiny/ui/_markdown.py index 551efda28..18ddca3f8 100644 --- a/shiny/ui/_markdown.py +++ b/shiny/ui/_markdown.py @@ -60,7 +60,7 @@ def default_md_renderer( raise ModuleNotFoundError( "The default markdown parser requires the markdown-it-py package" " to be installed. Install it with `pip install markdown-it`." - ) from None + ) if preset == "commonmark": parser = MarkdownIt("commonmark") From beaf1159d4f9f697e26b81afb14fe42ca3700850 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 14:27:30 -0400 Subject: [PATCH 51/56] Disable flynt static string lint --- ruff.toml | 1 - shiny/ui/_modal.py | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ruff.toml b/ruff.toml index d2bab28c5..aa133dbce 100644 --- a/ruff.toml +++ b/ruff.toml @@ -59,7 +59,6 @@ extend-select = [ "TCH", # TCH; flake8-type-checking: https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch # "FIX", # FIX; flake8-fixme: https://docs.astral.sh/ruff/rules/#flake8-fixme-fix # "PGH", # PGH; pygrep-hooks: https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh - "FLY", # FLY; flynt: https://docs.astral.sh/ruff/rules/#flynt-fly "NPY", # NPY; NumPy-specific rules: https://docs.astral.sh/ruff/rules/#numpy-specific-rules-npy "RUF005", # RUF005; Ruff specific rules Consider {expression} instead of concatenation: https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf "RUF100", # RUF100; Ruff specific rules Unused `noqa` directive https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf diff --git a/shiny/ui/_modal.py b/shiny/ui/_modal.py index 18fb736ec..57a11d2dd 100644 --- a/shiny/ui/_modal.py +++ b/shiny/ui/_modal.py @@ -131,7 +131,13 @@ def modal( ) # jQuery plugin doesn't work in Bootstrap 5, but vanilla JS doesn't work in Bootstrap 4 :sob: - js = "if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\. /)) {\n var modal=new bootstrap.Modal(document.getElementById('shiny-modal'))\n modal.show()\n} else {\n $('#shiny-modal').modal().focus()\n}" + js = """\ +if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\. /)) { + var modal=new bootstrap.Modal(document.getElementById('shiny-modal')) + modal.show() +} else { + $('#shiny-modal').modal().focus() +}""" backdrop = None if easy_close else "static" keyboard = None if easy_close else "false" From 9fa6aec498196ac838111dd1af5b2e677e696bf1 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 14:37:28 -0400 Subject: [PATCH 52/56] Fix bad usage of numpy-legacy-random --- examples/brownian/brownian_motion.py | 4 ++-- examples/cpuinfo/fakepsutil.py | 6 +++--- examples/express/accordion_app.py | 2 +- examples/express/column_wrap_app.py | 4 ++-- examples/express/nav_app.py | 4 ++-- examples/express/plot_app.py | 2 +- examples/express/shared_app.py | 2 +- examples/express/sidebar_app.py | 2 +- examples/static_plots/app.py | 7 +++---- shiny/api-examples/download/app-core.py | 8 ++++---- shiny/api-examples/download/app-express.py | 8 ++++---- shiny/api-examples/input_action_button/app-core.py | 2 +- shiny/api-examples/input_action_button/app-express.py | 2 +- shiny/api-examples/input_action_link/app-core.py | 2 +- shiny/api-examples/input_action_link/app-express.py | 2 +- shiny/api-examples/input_dark_mode/app-core.py | 2 +- shiny/api-examples/input_dark_mode/app-express.py | 2 +- shiny/api-examples/input_slider/app-core.py | 2 +- shiny/api-examples/input_slider/app-express.py | 2 +- shiny/api-examples/isolate/app-core.py | 2 +- shiny/api-examples/isolate/app-express.py | 2 +- shiny/api-examples/layout_columns/model_plots.py | 8 ++++---- shiny/api-examples/layout_sidebar/app-core.py | 2 +- shiny/api-examples/layout_sidebar/app-express.py | 2 +- shiny/api-examples/output_plot/app-core.py | 2 +- shiny/api-examples/output_plot/app-express.py | 2 +- shiny/api-examples/page_fixed/app-core.py | 2 +- shiny/api-examples/page_fixed/app-express.py | 2 +- shiny/api-examples/page_fluid/app-core.py | 2 +- shiny/api-examples/page_fluid/app-express.py | 2 +- shiny/api-examples/page_sidebar/app-core.py | 2 +- shiny/api-examples/page_sidebar/app-express.py | 2 +- shiny/api-examples/row/app-core.py | 2 +- 33 files changed, 49 insertions(+), 50 deletions(-) diff --git a/examples/brownian/brownian_motion.py b/examples/brownian/brownian_motion.py index 408743f8a..d2f46a09a 100644 --- a/examples/brownian/brownian_motion.py +++ b/examples/brownian/brownian_motion.py @@ -5,14 +5,14 @@ # * `brownian_motion()` is a function that generates a random walk # * `brownian_widget()` uses restructured plotting code given in article -rs = np.random.RandomState() +rng = np.random.default_rng() # https://plotly.com/python/3d-line-plots/ def brownian_motion(T=1, N=100, mu=0.1, sigma=0.01, S0=20): dt = float(T) / N t = np.linspace(0, T, N) - W = rs.standard_normal(size=N) + W = rng.standard_normal(size=N) W = np.cumsum(W) * np.sqrt(dt) # standard brownian motion X = (mu - 0.5 * sigma**2) * t + sigma * W S = S0 * np.exp(X) # geometric brownian motion diff --git a/examples/cpuinfo/fakepsutil.py b/examples/cpuinfo/fakepsutil.py index ea3773934..50a455646 100644 --- a/examples/cpuinfo/fakepsutil.py +++ b/examples/cpuinfo/fakepsutil.py @@ -7,13 +7,13 @@ def cpu_count(logical: bool = True): return 8 if logical else 4 -rnd = np.random.RandomState() -last_sample = rnd.uniform(0, 100, size=cpu_count(True)) +rng = np.random.default_rng() +last_sample = rng.uniform(0, 100, size=cpu_count(True)) def cpu_percent(percpu: bool = False): global last_sample - delta = rnd.normal(scale=10, size=len(last_sample)) + delta = rng.normal(scale=10, size=len(last_sample)) last_sample = (last_sample + delta).clip(0, 100) if percpu: return last_sample.tolist() diff --git a/examples/express/accordion_app.py b/examples/express/accordion_app.py index 4cb552e4f..f939c4173 100644 --- a/examples/express/accordion_app.py +++ b/examples/express/accordion_app.py @@ -17,5 +17,5 @@ def txt(): @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/column_wrap_app.py b/examples/express/column_wrap_app.py index 0dd7666c8..765917078 100644 --- a/examples/express/column_wrap_app.py +++ b/examples/express/column_wrap_app.py @@ -12,12 +12,12 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) with ui.card(): @render.plot def histogram2(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True, color="red") diff --git a/examples/express/nav_app.py b/examples/express/nav_app.py index 1bbe08040..61797860e 100644 --- a/examples/express/nav_app.py +++ b/examples/express/nav_app.py @@ -13,7 +13,7 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) with ui.navset_card_underline(): @@ -24,5 +24,5 @@ def histogram(): @render.plot def histogram2(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n2(), density=True) diff --git a/examples/express/plot_app.py b/examples/express/plot_app.py index 300f376ea..035305dfc 100644 --- a/examples/express/plot_app.py +++ b/examples/express/plot_app.py @@ -9,5 +9,5 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/shared_app.py b/examples/express/shared_app.py index d7ff51009..779c64586 100644 --- a/examples/express/shared_app.py +++ b/examples/express/shared_app.py @@ -12,7 +12,7 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, shared.rv(), density=True) diff --git a/examples/express/sidebar_app.py b/examples/express/sidebar_app.py index 1d72de82a..326e0a28b 100644 --- a/examples/express/sidebar_app.py +++ b/examples/express/sidebar_app.py @@ -10,5 +10,5 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) plt.hist(x, input.n(), density=True) diff --git a/examples/static_plots/app.py b/examples/static_plots/app.py index ab329bec9..d5b10de9c 100644 --- a/examples/static_plots/app.py +++ b/examples/static_plots/app.py @@ -54,15 +54,14 @@ def server(input: Inputs, output: Outputs, session: Session): - rnd = np.random.RandomState() + rng = np.random.default_rng() @reactive.calc def fake_data(): n = 5000 mean = [0, 0] - rng = np.random.RandomState(0) cov = [(input.var(), input.cov()), (input.cov(), 1 / input.var())] - return rng.multivariate_normal(mean, cov, n).T + return np.random.default_rng(seed=0).multivariate_normal(mean, cov, n).T @render.plot def seaborn(): @@ -100,7 +99,7 @@ def plotnine(): @render.plot def pandas(): ts = pd.Series( - rnd.randn(1000), + rng.randn(1000), index=pd.date_range("1/1/2000", periods=1000), ) ts = ts.cumsum() diff --git a/shiny/api-examples/download/app-core.py b/shiny/api-examples/download/app-core.py index 2b28e0ce9..b57f20d0a 100644 --- a/shiny/api-examples/download/app-core.py +++ b/shiny/api-examples/download/app-core.py @@ -77,7 +77,7 @@ def make_example(id: str, label: str, title: str, desc: str, extra: Any = None): def server(input: Inputs, output: Outputs, session: Session): - rnd = np.random.RandomState() + rng = np.random.default_rng() @render.download() def download1(): @@ -100,8 +100,8 @@ def download2(): """ print(input.num_points()) - x = rnd.uniform(size=input.num_points()) - y = rnd.uniform(size=input.num_points()) + x = rng.uniform(size=input.num_points()) + y = rng.uniform(size=input.num_points()) plt.figure() plt.scatter(x, y) plt.title(input.title()) @@ -110,7 +110,7 @@ def download2(): yield buf.getvalue() @render.download( - filename=lambda: f"新型-{date.today().isoformat()}-{rnd.randint(100, 999)}.csv" + filename=lambda: f"新型-{date.today().isoformat()}-{rng.randint(100, 999)}.csv" ) async def download3(): await asyncio.sleep(0.25) diff --git a/shiny/api-examples/download/app-express.py b/shiny/api-examples/download/app-express.py index 2edfcecd6..a3298a81e 100644 --- a/shiny/api-examples/download/app-express.py +++ b/shiny/api-examples/download/app-express.py @@ -8,7 +8,7 @@ from shiny.express import render, ui -rnd = np.random.RandomState() +rng = np.random.default_rng() ui.page_opts(title="Various download examples") @@ -43,8 +43,8 @@ def download2(): """ print(input.num_points()) - x = rnd.uniform(size=input.num_points()) - y = rnd.uniform(size=input.num_points()) + x = rng.uniform(size=input.num_points()) + y = rng.uniform(size=input.num_points()) plt.figure() plt.scatter(x, y) plt.title(input.title()) @@ -59,7 +59,7 @@ def download2(): @render.download( label="Download filename", - filename=lambda: f"新型-{date.today().isoformat()}-{rnd.randint(100, 999)}.csv", + filename=lambda: f"新型-{date.today().isoformat()}-{rng.randint(100, 999)}.csv", ) async def download3(): await asyncio.sleep(0.25) diff --git a/shiny/api-examples/input_action_button/app-core.py b/shiny/api-examples/input_action_button/app-core.py index cefe4bad5..4830e96dd 100644 --- a/shiny/api-examples/input_action_button/app-core.py +++ b/shiny/api-examples/input_action_button/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_button/app-express.py b/shiny/api-examples/input_action_button/app-express.py index ec832e8d6..6ea5e8541 100644 --- a/shiny/api-examples/input_action_button/app-express.py +++ b/shiny/api-examples/input_action_button/app-express.py @@ -13,7 +13,7 @@ # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-core.py b/shiny/api-examples/input_action_link/app-core.py index 08e2adf5e..b856a6b87 100644 --- a/shiny/api-examples/input_action_link/app-core.py +++ b/shiny/api-examples/input_action_link/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-express.py b/shiny/api-examples/input_action_link/app-express.py index 30484e3ca..ab5a3df6c 100644 --- a/shiny/api-examples/input_action_link/app-express.py +++ b/shiny/api-examples/input_action_link/app-express.py @@ -13,7 +13,7 @@ # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_dark_mode/app-core.py b/shiny/api-examples/input_dark_mode/app-core.py index de3beae05..b7b24751e 100644 --- a/shiny/api-examples/input_dark_mode/app-core.py +++ b/shiny/api-examples/input_dark_mode/app-core.py @@ -45,7 +45,7 @@ def _(): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_dark_mode/app-express.py b/shiny/api-examples/input_dark_mode/app-express.py index c3169d4ef..d7c99d6f0 100644 --- a/shiny/api-examples/input_dark_mode/app-express.py +++ b/shiny/api-examples/input_dark_mode/app-express.py @@ -13,7 +13,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_slider/app-core.py b/shiny/api-examples/input_slider/app-core.py index 1cc773799..f21b7caa4 100644 --- a/shiny/api-examples/input_slider/app-core.py +++ b/shiny/api-examples/input_slider/app-core.py @@ -12,7 +12,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def distPlot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/input_slider/app-express.py b/shiny/api-examples/input_slider/app-express.py index 9394d3ec9..a76a65eb6 100644 --- a/shiny/api-examples/input_slider/app-express.py +++ b/shiny/api-examples/input_slider/app-express.py @@ -8,7 +8,7 @@ @render.plot def distPlot(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/isolate/app-core.py b/shiny/api-examples/isolate/app-core.py index db9585d87..45b039de9 100644 --- a/shiny/api-examples/isolate/app-core.py +++ b/shiny/api-examples/isolate/app-core.py @@ -18,7 +18,7 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - x = 100 + 15 * np.random.RandomState(19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/isolate/app-express.py b/shiny/api-examples/isolate/app-express.py index 35abfc9d4..d28426bf3 100644 --- a/shiny/api-examples/isolate/app-express.py +++ b/shiny/api-examples/isolate/app-express.py @@ -15,7 +15,7 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/layout_columns/model_plots.py b/shiny/api-examples/layout_columns/model_plots.py index 6446fdb9e..c8b9f6cc5 100644 --- a/shiny/api-examples/layout_columns/model_plots.py +++ b/shiny/api-examples/layout_columns/model_plots.py @@ -3,12 +3,12 @@ from shiny import ui -rnd = np.random.RandomState() +rng = np.random.default_rng() def plot_loss_over_time(): epochs = np.arange(1, 101) - loss = 1000 / np.sqrt(epochs) + rnd.rand(100) * 25 + loss = 1000 / np.sqrt(epochs) + rng.uniform(size=100) * 25 fig = plt.figure(figsize=(10, 6)) plt.plot(epochs, loss) @@ -19,7 +19,7 @@ def plot_loss_over_time(): def plot_accuracy_over_time(): epochs = np.arange(1, 101) - accuracy = np.sqrt(epochs) / 12 + rnd.rand(100) * 0.15 + accuracy = np.sqrt(epochs) / 12 + rng.uniform(size=100) * 0.15 accuracy = [np.min([np.max(accuracy[:i]), 1]) for i in range(1, 101)] fig = plt.figure(figsize=(10, 6)) @@ -31,7 +31,7 @@ def plot_accuracy_over_time(): def plot_feature_importance(): features = ["Product Category", "Price", "Brand", "Rating", "Number of Reviews"] - importance = rnd.rand(5) + importance = rng.uniform(size=5) fig = plt.figure(figsize=(10, 6)) plt.barh(features, importance) diff --git a/shiny/api-examples/layout_sidebar/app-core.py b/shiny/api-examples/layout_sidebar/app-core.py index 913e76ca0..9fdc35243 100644 --- a/shiny/api-examples/layout_sidebar/app-core.py +++ b/shiny/api-examples/layout_sidebar/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/layout_sidebar/app-express.py b/shiny/api-examples/layout_sidebar/app-express.py index 782cab3c5..78a2414b2 100644 --- a/shiny/api-examples/layout_sidebar/app-express.py +++ b/shiny/api-examples/layout_sidebar/app-express.py @@ -9,7 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/output_plot/app-core.py b/shiny/api-examples/output_plot/app-core.py index 48b3ea76e..29ab0f47e 100644 --- a/shiny/api-examples/output_plot/app-core.py +++ b/shiny/api-examples/output_plot/app-core.py @@ -14,7 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def p(): - x_rand = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x_rand = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/output_plot/app-express.py b/shiny/api-examples/output_plot/app-express.py index 5227eef60..6594e7cc7 100644 --- a/shiny/api-examples/output_plot/app-express.py +++ b/shiny/api-examples/output_plot/app-express.py @@ -8,7 +8,7 @@ @render.plot def p(): - x_rand = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x_rand = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/page_fixed/app-core.py b/shiny/api-examples/page_fixed/app-core.py index 2036d5b30..40060f46a 100644 --- a/shiny/api-examples/page_fixed/app-core.py +++ b/shiny/api-examples/page_fixed/app-core.py @@ -18,7 +18,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fixed/app-express.py b/shiny/api-examples/page_fixed/app-express.py index aad365661..ef3524222 100644 --- a/shiny/api-examples/page_fixed/app-express.py +++ b/shiny/api-examples/page_fixed/app-express.py @@ -12,7 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-core.py b/shiny/api-examples/page_fluid/app-core.py index 29e2fae5c..5ea1b4ac4 100644 --- a/shiny/api-examples/page_fluid/app-core.py +++ b/shiny/api-examples/page_fluid/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-express.py b/shiny/api-examples/page_fluid/app-express.py index 70c91e22c..582cfa1cc 100644 --- a/shiny/api-examples/page_fluid/app-express.py +++ b/shiny/api-examples/page_fluid/app-express.py @@ -12,7 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-core.py b/shiny/api-examples/page_sidebar/app-core.py index d6e5fbeb1..b242c8284 100644 --- a/shiny/api-examples/page_sidebar/app-core.py +++ b/shiny/api-examples/page_sidebar/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-express.py b/shiny/api-examples/page_sidebar/app-express.py index 815c58e89..18d5d896e 100644 --- a/shiny/api-examples/page_sidebar/app-express.py +++ b/shiny/api-examples/page_sidebar/app-express.py @@ -9,7 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/row/app-core.py b/shiny/api-examples/row/app-core.py index 54563a7e6..9c3df9ed4 100644 --- a/shiny/api-examples/row/app-core.py +++ b/shiny/api-examples/row/app-core.py @@ -14,7 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.RandomState(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) From bfd65666984e6feaffbc78f064a0fff95d441bd2 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 15:04:27 -0400 Subject: [PATCH 53/56] numpy random s/randn/standard_normal/ --- examples/express/accordion_app.py | 2 +- examples/express/column_wrap_app.py | 4 ++-- examples/express/nav_app.py | 4 ++-- examples/express/plot_app.py | 2 +- examples/express/shared_app.py | 2 +- examples/express/sidebar_app.py | 2 +- examples/static_plots/app.py | 2 +- shiny/api-examples/input_action_button/app-core.py | 2 +- shiny/api-examples/input_action_button/app-express.py | 2 +- shiny/api-examples/input_action_link/app-core.py | 2 +- shiny/api-examples/input_action_link/app-express.py | 2 +- shiny/api-examples/input_dark_mode/app-core.py | 2 +- shiny/api-examples/input_dark_mode/app-express.py | 2 +- shiny/api-examples/input_slider/app-core.py | 2 +- shiny/api-examples/input_slider/app-express.py | 2 +- shiny/api-examples/isolate/app-core.py | 4 +++- shiny/api-examples/isolate/app-express.py | 2 +- shiny/api-examples/layout_sidebar/app-core.py | 2 +- shiny/api-examples/layout_sidebar/app-express.py | 2 +- shiny/api-examples/output_plot/app-core.py | 2 +- shiny/api-examples/output_plot/app-express.py | 2 +- shiny/api-examples/page_fixed/app-core.py | 2 +- shiny/api-examples/page_fixed/app-express.py | 2 +- shiny/api-examples/page_fluid/app-core.py | 2 +- shiny/api-examples/page_fluid/app-express.py | 2 +- shiny/api-examples/page_sidebar/app-core.py | 2 +- shiny/api-examples/page_sidebar/app-express.py | 2 +- shiny/api-examples/row/app-core.py | 2 +- 28 files changed, 32 insertions(+), 30 deletions(-) diff --git a/examples/express/accordion_app.py b/examples/express/accordion_app.py index f939c4173..76e2505d2 100644 --- a/examples/express/accordion_app.py +++ b/examples/express/accordion_app.py @@ -17,5 +17,5 @@ def txt(): @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/column_wrap_app.py b/examples/express/column_wrap_app.py index 765917078..b64660ea9 100644 --- a/examples/express/column_wrap_app.py +++ b/examples/express/column_wrap_app.py @@ -12,12 +12,12 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True) with ui.card(): @render.plot def histogram2(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True, color="red") diff --git a/examples/express/nav_app.py b/examples/express/nav_app.py index 61797860e..9410b6085 100644 --- a/examples/express/nav_app.py +++ b/examples/express/nav_app.py @@ -13,7 +13,7 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True) with ui.navset_card_underline(): @@ -24,5 +24,5 @@ def histogram(): @render.plot def histogram2(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n2(), density=True) diff --git a/examples/express/plot_app.py b/examples/express/plot_app.py index 035305dfc..9d31dddf5 100644 --- a/examples/express/plot_app.py +++ b/examples/express/plot_app.py @@ -9,5 +9,5 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True) diff --git a/examples/express/shared_app.py b/examples/express/shared_app.py index 779c64586..10778565a 100644 --- a/examples/express/shared_app.py +++ b/examples/express/shared_app.py @@ -12,7 +12,7 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, shared.rv(), density=True) diff --git a/examples/express/sidebar_app.py b/examples/express/sidebar_app.py index 326e0a28b..b75714204 100644 --- a/examples/express/sidebar_app.py +++ b/examples/express/sidebar_app.py @@ -10,5 +10,5 @@ @render.plot def histogram(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) plt.hist(x, input.n(), density=True) diff --git a/examples/static_plots/app.py b/examples/static_plots/app.py index d5b10de9c..f0dc0af5f 100644 --- a/examples/static_plots/app.py +++ b/examples/static_plots/app.py @@ -99,7 +99,7 @@ def plotnine(): @render.plot def pandas(): ts = pd.Series( - rng.randn(1000), + rng.standard_normal(1000), index=pd.date_range("1/1/2000", periods=1000), ) ts = ts.cumsum() diff --git a/shiny/api-examples/input_action_button/app-core.py b/shiny/api-examples/input_action_button/app-core.py index 4830e96dd..b8dcbeb8b 100644 --- a/shiny/api-examples/input_action_button/app-core.py +++ b/shiny/api-examples/input_action_button/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_button/app-express.py b/shiny/api-examples/input_action_button/app-express.py index 6ea5e8541..5936c2d86 100644 --- a/shiny/api-examples/input_action_button/app-express.py +++ b/shiny/api-examples/input_action_button/app-express.py @@ -13,7 +13,7 @@ # (not when the slider is changed) @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-core.py b/shiny/api-examples/input_action_link/app-core.py index b856a6b87..a7bc48a80 100644 --- a/shiny/api-examples/input_action_link/app-core.py +++ b/shiny/api-examples/input_action_link/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_action_link/app-express.py b/shiny/api-examples/input_action_link/app-express.py index ab5a3df6c..0e5ac98b3 100644 --- a/shiny/api-examples/input_action_link/app-express.py +++ b/shiny/api-examples/input_action_link/app-express.py @@ -13,7 +13,7 @@ # the slider is changed @reactive.event(input.go, ignore_none=False) def plot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) return fig diff --git a/shiny/api-examples/input_dark_mode/app-core.py b/shiny/api-examples/input_dark_mode/app-core.py index b7b24751e..dd6bf0f16 100644 --- a/shiny/api-examples/input_dark_mode/app-core.py +++ b/shiny/api-examples/input_dark_mode/app-core.py @@ -45,7 +45,7 @@ def _(): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_dark_mode/app-express.py b/shiny/api-examples/input_dark_mode/app-express.py index d7c99d6f0..f46b20aee 100644 --- a/shiny/api-examples/input_dark_mode/app-express.py +++ b/shiny/api-examples/input_dark_mode/app-express.py @@ -13,7 +13,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/input_slider/app-core.py b/shiny/api-examples/input_slider/app-core.py index f21b7caa4..0c13e3e9e 100644 --- a/shiny/api-examples/input_slider/app-core.py +++ b/shiny/api-examples/input_slider/app-core.py @@ -12,7 +12,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def distPlot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/input_slider/app-express.py b/shiny/api-examples/input_slider/app-express.py index a76a65eb6..4af08f8c1 100644 --- a/shiny/api-examples/input_slider/app-express.py +++ b/shiny/api-examples/input_slider/app-express.py @@ -8,7 +8,7 @@ @render.plot def distPlot(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.obs(), density=True) diff --git a/shiny/api-examples/isolate/app-core.py b/shiny/api-examples/isolate/app-core.py index 45b039de9..b80278463 100644 --- a/shiny/api-examples/isolate/app-core.py +++ b/shiny/api-examples/isolate/app-core.py @@ -18,7 +18,9 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal( + input.n() + ) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/isolate/app-express.py b/shiny/api-examples/isolate/app-express.py index d28426bf3..192b01344 100644 --- a/shiny/api-examples/isolate/app-express.py +++ b/shiny/api-examples/isolate/app-express.py @@ -15,7 +15,7 @@ def plot(): # ...but don't take a reactive dependency on the slider with reactive.isolate(): - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(input.n()) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(input.n()) fig, ax = plt.subplots() ax.hist(x, bins=30, density=True) diff --git a/shiny/api-examples/layout_sidebar/app-core.py b/shiny/api-examples/layout_sidebar/app-core.py index 9fdc35243..2a819cace 100644 --- a/shiny/api-examples/layout_sidebar/app-core.py +++ b/shiny/api-examples/layout_sidebar/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/layout_sidebar/app-express.py b/shiny/api-examples/layout_sidebar/app-express.py index 78a2414b2..724afe970 100644 --- a/shiny/api-examples/layout_sidebar/app-express.py +++ b/shiny/api-examples/layout_sidebar/app-express.py @@ -9,7 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/output_plot/app-core.py b/shiny/api-examples/output_plot/app-core.py index 29ab0f47e..1abd1b5b4 100644 --- a/shiny/api-examples/output_plot/app-core.py +++ b/shiny/api-examples/output_plot/app-core.py @@ -14,7 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot def p(): - x_rand = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x_rand = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/output_plot/app-express.py b/shiny/api-examples/output_plot/app-express.py index 6594e7cc7..39aea5fde 100644 --- a/shiny/api-examples/output_plot/app-express.py +++ b/shiny/api-examples/output_plot/app-express.py @@ -8,7 +8,7 @@ @render.plot def p(): - x_rand = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x_rand = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x_rand, int(input.n()), density=True) return fig diff --git a/shiny/api-examples/page_fixed/app-core.py b/shiny/api-examples/page_fixed/app-core.py index 40060f46a..42ae1e313 100644 --- a/shiny/api-examples/page_fixed/app-core.py +++ b/shiny/api-examples/page_fixed/app-core.py @@ -18,7 +18,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fixed/app-express.py b/shiny/api-examples/page_fixed/app-express.py index ef3524222..b3f80d4db 100644 --- a/shiny/api-examples/page_fixed/app-express.py +++ b/shiny/api-examples/page_fixed/app-express.py @@ -12,7 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-core.py b/shiny/api-examples/page_fluid/app-core.py index 5ea1b4ac4..5e1888905 100644 --- a/shiny/api-examples/page_fluid/app-core.py +++ b/shiny/api-examples/page_fluid/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_fluid/app-express.py b/shiny/api-examples/page_fluid/app-express.py index 582cfa1cc..86d522912 100644 --- a/shiny/api-examples/page_fluid/app-express.py +++ b/shiny/api-examples/page_fluid/app-express.py @@ -12,7 +12,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-core.py b/shiny/api-examples/page_sidebar/app-core.py index b242c8284..be30313ea 100644 --- a/shiny/api-examples/page_sidebar/app-core.py +++ b/shiny/api-examples/page_sidebar/app-core.py @@ -16,7 +16,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/page_sidebar/app-express.py b/shiny/api-examples/page_sidebar/app-express.py index 18d5d896e..12a2854a5 100644 --- a/shiny/api-examples/page_sidebar/app-express.py +++ b/shiny/api-examples/page_sidebar/app-express.py @@ -9,7 +9,7 @@ @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) diff --git a/shiny/api-examples/row/app-core.py b/shiny/api-examples/row/app-core.py index 9c3df9ed4..ee82d3e25 100644 --- a/shiny/api-examples/row/app-core.py +++ b/shiny/api-examples/row/app-core.py @@ -14,7 +14,7 @@ def server(input: Inputs, output: Outputs, session: Session): @render.plot(alt="A histogram") def plot() -> object: - x = 100 + 15 * np.random.default_rng(seed=19680801).randn(437) + x = 100 + 15 * np.random.default_rng(seed=19680801).standard_normal(437) fig, ax = plt.subplots() ax.hist(x, input.n(), density=True) From 8e0fda3ed2e7719ad388ff30e5d9786f10e0a211 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 15:06:23 -0400 Subject: [PATCH 54/56] More checks for shiny/__init__.py --- ruff.toml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ruff.toml b/ruff.toml index aa133dbce..e40f6e361 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,13 +1,5 @@ -extend-exclude = [ - "docs", - ".venv", - "venv", - "typings", - "build", - "_dev", - "shiny/__init__.py", -] +extend-exclude = ["docs", ".venv", "venv", "typings", "build", "_dev"] [lint] @@ -69,7 +61,7 @@ extend-select = [ "**/__init__.py" = ["I"] # F403: 'from module import *' used; unable to detect undefined names # Also ignore `F403` in all `__init__.py` files. -"shiny/__init__.py" = ["F403"] +"shiny/__init__.py" = ["F403", "F405"] # B018: Found useless expression. Either assign it to a variable or remove it. # This check is incompatible with the `express` framework. "**/app-express.py" = ["B018"] From 74b01a419caa8a37e5b54e0d297ca57fa43096e5 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 15:14:31 -0400 Subject: [PATCH 55/56] Update comment --- shiny/_typing_extensions.py | 1 - tests/pytest/test_display_decorator.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/shiny/_typing_extensions.py b/shiny/_typing_extensions.py index 28bcf8422..5047478a4 100644 --- a/shiny/_typing_extensions.py +++ b/shiny/_typing_extensions.py @@ -1,5 +1,4 @@ # # Within file flags to ignore unused imports -# flake8: noqa: F401 # pyright: reportUnusedImport=false from __future__ import annotations diff --git a/tests/pytest/test_display_decorator.py b/tests/pytest/test_display_decorator.py index 63e014b28..469848002 100644 --- a/tests/pytest/test_display_decorator.py +++ b/tests/pytest/test_display_decorator.py @@ -1,5 +1,5 @@ # pyright: reportUnusedExpression=false -# flake8: noqa +# ruff: noqa: B018 from __future__ import annotations import contextlib From 8fd601fa1d3bf219c66af24b4fabc05c1c5b31fe Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 12 Mar 2024 16:34:43 -0400 Subject: [PATCH 56/56] Format date for py3.12 --- examples/model-score/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/model-score/app.py b/examples/model-score/app.py index ca13ccffc..e1f2cc815 100644 --- a/examples/model-score/app.py +++ b/examples/model-score/app.py @@ -58,7 +58,7 @@ def df(): params=[150], ) # Convert timestamp to datetime object, which SQLite doesn't support natively - tbl["timestamp"] = pd.to_datetime(tbl["timestamp"], utc=True) + tbl["timestamp"] = pd.to_datetime(tbl["timestamp"], utc=True, format="ISO8601") # Create a short label for readability tbl["time"] = tbl["timestamp"].dt.strftime("%H:%M:%S") # Reverse order of rows