diff --git a/pkg-py/tests/playwright/conftest.py b/pkg-py/tests/playwright/conftest.py index 961af01f..3a2db45d 100644 --- a/pkg-py/tests/playwright/conftest.py +++ b/pkg-py/tests/playwright/conftest.py @@ -359,9 +359,20 @@ def _stop_streamlit_server(process: subprocess.Popen) -> None: process.kill() -@pytest.fixture(scope="module") +@pytest.fixture def app_04_streamlit() -> Generator[str, None, None]: - """Start the 04-streamlit-app.py Streamlit server for testing.""" + """ + Start the 04-streamlit-app.py Streamlit server for testing. + + Function-scoped (a fresh subprocess per test), unlike the Shiny/Gradio/Dash + app fixtures in this file. A single Streamlit server was observed to stop + re-running its script for new browser sessions after the first test's + session completed successfully -- the static page shell still loads, but + no reactive content (e.g. the chat greeting) ever streams in, with no + error on either side, and the condition persists for the rest of the + server's life (a fresh browser context/page doesn't recover it; only a + new server process does). + """ app_path = str(EXAMPLES_DIR / "04-streamlit-app.py") def start_factory(): @@ -381,9 +392,9 @@ def streamlit_cleanup(process, _): _stop_streamlit_server(process) -@pytest.fixture(scope="module") +@pytest.fixture def app_09_streamlit_custom() -> Generator[str, None, None]: - """Start the 09-streamlit-custom-app.py Streamlit server for testing.""" + """Start the 09-streamlit-custom-app.py Streamlit server for testing. Function-scoped; see app_04_streamlit().""" app_path = str(EXAMPLES_DIR / "09-streamlit-custom-app.py") def start_factory(): diff --git a/pyproject.toml b/pyproject.toml index bec6902f..cddceb52 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ classifiers = [ [project.optional-dependencies] # For SQLAlchemySource and sample data, one of polars or pandas is required pandas = ["pandas"] -polars = ["polars", "pyarrow"] # duckdb requires pyarrow for polars DataFrame registration +polars = ["polars", "pyarrow<25.0.0"] # duckdb requires pyarrow for polars DataFrame registration; pyarrow>=25.0.0 segfaults when its native conversion code runs on more than ~2 OS threads over a process's lifetime (e.g. Streamlit reruns each script on a fresh thread) -- see #268 ibis = ["ibis-framework>=9.0.0", "pandas"] # pandas required for ibis .execute() to return DataFrames pins = ["pins>=0.9.1"] # Web framework extras @@ -101,7 +101,7 @@ dev = [ "tox-uv>=1.11.4", "pytest>=8.4.0", "polars>=1.0.0", - "pyarrow>=14.0.0", + "pyarrow<25.0.0", # see comment on the `polars` extra above "ibis-framework[duckdb]>=9.0.0", "ggsql>=0.3.2", "altair>=6.0",