Skip to content

Commit

Permalink
Require Python 3.8, update CI
Browse files Browse the repository at this point in the history
Python 3.6 and 3.7 have both been end-of-life for over a year. This PR starts requiring Python 3.8 and higher for Solara. CI and test code is modified in sync.
  • Loading branch information
EwoutH committed Aug 26, 2024
1 parent 48c1c77 commit 3d9c80f
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 71 deletions.
46 changes: 14 additions & 32 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.12"

- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -138,20 +138,13 @@ jobs:
id: install_no_lock
run: |
mkdir -p .ci-package-locks/code-quality
pip install pre-commit
pip freeze --exclude solara --exclude solara-enterprise > ${{ env.LOCK_FILE_LOCATION }}
git diff --quiet || echo "HAS_DIFF=true" >> "$GITHUB_OUTPUT"
- name: Install
if: github.event_name != 'schedule' && steps.prepare.outputs.LOCKS_EXIST == 'true'
run: pip install -r ${{ env.LOCK_FILE_LOCATION }}

- name: Install pre-commit
run: pre-commit install

- name: Run pre-commit
run: pre-commit run --all-files

- name: Upload CI package locks
if: steps.install_no_lock.outputs.HAS_DIFF == 'true' || steps.prepare.outputs.LOCKS_EXIST == 'false'
uses: actions/upload-artifact@v4
Expand All @@ -161,15 +154,12 @@ jobs:

test-install:
needs: [build]
runs-on: ${{ matrix.os }}-${{(matrix.os == 'ubuntu' && matrix.python == '3.6') && '20.04' || (matrix.os == 'macos' && matrix.python == '3.6') && '13' || 'latest' }}
runs-on: ${{ matrix.os }}-'latest'
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos, windows]
python: ["3.6", "3.10"]
exclude:
- os: windows
python: 3.6
python: ["3.8", "3.12"]

steps:
- name: Set up Python
Expand Down Expand Up @@ -229,13 +219,13 @@ jobs:
# osx should work fine (and we test that locally often)
os: [ubuntu, windows]
# just 1 version, it's heavy
python-version: [3.8]
python-version: ["3.12"]
ipywidgets_major: ["7", "8"]
include:
- ipywidgets_major: "7"
ipywidgets: "7.7"
ipywidgets: "7.8"
- ipywidgets_major: "8"
ipywidgets: "8.0"
ipywidgets: "8.1"
env:
LOCK_FILE_LOCATION: .ci-package-locks/integration/os${{ matrix.os }}-python${{ matrix.python-version }}-ipywidgets${{ matrix.ipywidgets_major }}.txt

Expand Down Expand Up @@ -338,11 +328,11 @@ jobs:
# osx should work fine (and we test that locally often)
os: [ubuntu]
# just 1 version, it's heavy
python-version: [3.8]
python-version: ["3.12"]
ipywidgets_major: ["8"]
include:
- ipywidgets_major: "8"
ipywidgets: "8.0"
ipywidgets: "8.1"
env:
LOCK_FILE_LOCATION: .ci-package-locks/integration-vue3/os${{ matrix.os }}-ipywidgets${{ matrix.ipywidgets_major }}.txt

Expand Down Expand Up @@ -431,22 +421,14 @@ jobs:

unit-test:
needs: [build]
runs-on: ${{ matrix.os }}-${{(matrix.os == 'ubuntu' && matrix.python == '3.6') && '20.04' || (matrix.os == 'macos' && matrix.python == '3.6') && '13' || 'latest' }}
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos, windows]
python: [3.6, 3.9]
ipywidgets: ["7.7", "8.0"]
exclude:
- os: windows
python: 3.6
- os: ubuntu
python: 3.6
ipywidgets: "8.0"
- os: macos
python: 3.6
ipywidgets: "8.0"
python: ["3.8", "3.12"]
ipywidgets: ["7.8", "8.1"]

env:
LOCK_FILE_LOCATION: .ci-package-locks/unit/os${{ matrix.os }}-python${{ matrix.python }}-ipywidgets${{ matrix.ipywidgets }}.txt

Expand Down Expand Up @@ -557,10 +539,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.7
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.7
python-version: "3.12"

- uses: actions/download-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ repos:
rev: v3.17.0
hooks:
- id: pyupgrade
args: [--py36-plus]
args: [--py38-plus]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import sys
import typing
from base64 import b64decode, b64encode

Expand All @@ -10,10 +9,7 @@
from starlette.requests import HTTPConnection
from starlette.types import ASGIApp, Message, Receive, Scope, Send

if sys.version_info >= (3, 8): # pragma: no cover
from typing import Literal
else: # pragma: no cover
from typing_extensions import Literal
from typing import Literal


# mutable mapping that keeps track of whether it has been modified
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["hatchling==1.22.2"]
requires = ["hatchling==1.25.0"]
build-backend = "hatchling.build"


Expand All @@ -13,6 +13,7 @@ dynamic = ["version", "description"]
packages = [
{ include = "solara" }
]
requires-python = ">= 3.8"
dependencies = [
"reacton>=1.7.1",
"ipywidgets>=7.7",
Expand Down Expand Up @@ -69,7 +70,6 @@ markdown = [
"markdown",
"pymdown-extensions",
"pygments",
"pygments==2.10; python_version < '3.7'",
]

cache = [
Expand Down
10 changes: 1 addition & 9 deletions solara/server/starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import math
import os
from pathlib import Path
import sys
import threading
import typing
from typing import Any, Dict, List, Optional, Set, Union, cast
Expand All @@ -24,7 +23,7 @@
has_solara_enterprise = True
except ImportError:
has_solara_enterprise = False
if has_solara_enterprise and sys.version_info[:2] > (3, 6):
if has_solara_enterprise:
has_auth_support = True
from solara_enterprise.auth.middleware import MutateDetectSessionMiddleware
from solara_enterprise.auth.starlette import (
Expand Down Expand Up @@ -195,13 +194,6 @@ def serve(self):
from uvicorn.config import Config
from uvicorn.server import Server

if sys.version_info[:2] < (3, 7):
# make python 3.6 work
import asyncio

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

# uvloop will trigger a: RuntimeError: There is no current event loop in thread 'fastapi-thread'
config = Config(self.app, host=self.host, port=self.port, **self.kwargs, access_log=False, loop="asyncio")
self.server = Server(config=config)
Expand Down
4 changes: 0 additions & 4 deletions tests/integration/enterprise/oauth_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import sys

import playwright.sync_api
import pytest
Expand All @@ -10,9 +9,6 @@

from solara.server import settings # noqa

if sys.version_info[:2] <= (3, 6):
pytest.skip("Test requires python 3.7 or higher", allow_module_level=True)


@pytest.mark.skipif(not bool(os.environ.get("AUTH0_PASSWORD")), reason="AUTH0_PASSWORD not set")
def test_oauth_from_app_auth0(page_session: playwright.sync_api.Page, solara_server, solara_app):
Expand Down
2 changes: 0 additions & 2 deletions tests/integration/esm_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import sys
from pathlib import Path

import ipyreact
Expand Down Expand Up @@ -37,7 +36,6 @@ def PageDefineDuringRun():
ipyreact.ValueWidget.element(_module="solara-test-dynamic", value=0, on_value=value.set)


@pytest.mark.skipif(sys.version_info < (3, 7, 0), reason="ipyreact requires python 3.7 or higher")
@pytest.mark.parametrize("app", ["esm_test:Page", "esm_test:PageDefineDuringRun"])
def test_ipyreact(browser: playwright.sync_api.Browser, page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, app):
with extra_include_path(HERE), solara_app(app):
Expand Down
16 changes: 0 additions & 16 deletions tests/unit/patch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@

from solara.server import kernel, kernel_context

# import pytest


# temporary disabled
# # with python 3.6 we don't use the comm package
# @pytest.mark.skipif(sys.version_info < (3, 7, 0), reason="ipykernel version too low")
# def test_widget_error_message_outside_context(no_kernel_context):
# from ipyvuetify.Themes import theme

# theme.get_state()
# kernel_shared = kernel.Kernel()
# context1 = kernel_context.VirtualKernelContext(id="1", kernel=kernel_shared, session_id="session-1")
# with pytest.raises(RuntimeError):
# with context1:
# assert theme.model_id


def test_widget_dict(no_kernel_context):
kernel_shared = kernel.Kernel()
Expand Down

0 comments on commit 3d9c80f

Please sign in to comment.