Repository: jupyterhub/jupyterhub

Issue:
ci: test against python 3.11
As @minrk noted in https://github.com/jupyterhub/jupyterhub/pull/3976#issuecomment-1184975768, we can't yet do this

> Can't test 3.11 on linux because sqlalchemy requires greenlet on linux (specifically because it's easy to install there), but greenlet can't be installed with Python 3.11 yet. Ref: https://github.com/gevent/gevent/issues/1867
>
>sqlalchemy issue about how optional greenlet should be: https://github.com/sqlalchemy/sqlalchemy/issues/6136



Discussion:
Since gevent is technically optional, we could get tests running by producing a requirements.txt and omitting gevent, as [described here](https://stackoverflow.com/questions/52126116/prevent-pip-from-installing-some-dependencies):

1. `pip-compile requirements.txt > frozen.txt` (resolves all dependencies)
2. `grep -v gevent frozen.txt > without-gevent.txt` (remove gevent)
3. `pip install --no-deps -r without-gevent.txt` (install only listed packages, including dependencies, avoiding resolving dependencies a second time)

We could also get it running by testing 3.11 on mac, where gevent is not listed as a default dependency of sqlalchemy

Resolving patch:
diff --git a/ci/mock-greenlet/greenlet.py b/ci/mock-greenlet/greenlet.py
new file mode 100644
--- /dev/null
+++ b/ci/mock-greenlet/greenlet.py
@@ -0,0 +1,3 @@
+__version__ = "22.0.0.dev0"
+
+raise ImportError("Don't actually have greenlet")


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -71,6 +71,8 @@ jobs:
         # NOTE: Since only the value of these parameters are presented in the
         #       GitHub UI when the workflow run, we avoid using true/false as
         #       values by instead duplicating the name to signal true.
+        # Python versions available at:
+        #   https://github.com/actions/python-versions/blob/HEAD/versions-manifest.json
         include:
           - python: "3.7"
             oldest_dependencies: oldest_dependencies
@@ -85,10 +87,7 @@ jobs:
             subdomain: subdomain
           - python: "3.10"
             ssl: ssl
-          # can't test 3.11.0-beta.4 until a greenlet release
-          # greenlet is a dependency of sqlalchemy on linux
-          # see https://github.com/gevent/gevent/issues/1867
-          # - python: "3.11.0-beta.4"
+          - python: "3.11.0-rc.1"
           - python: "3.10"
             main_dependencies: main_dependencies
 
@@ -136,9 +135,19 @@ jobs:
         uses: actions/setup-python@v4
         with:
           python-version: "${{ matrix.python }}"
+
       - name: Install Python dependencies
         run: |
           pip install --upgrade pip
+
+          if [[ "${{ matrix.python }}" == "3.11"* ]]; then
+            # greenlet is not actually required,
+            # but is an install dependency of sqlalchemy.
+            # It does not yet install on 3.11
+            # see: see https://github.com/gevent/gevent/issues/1867
+            pip install ./ci/mock-greenlet
+          fi
+
           pip install --upgrade . -r dev-requirements.txt
 
           if [ "${{ matrix.oldest_dependencies }}" != "" ]; then