Skip to content

Port to Python 3.14: blocked only by one dead import and two grpcio pins (both verified) #213

Description

@sspickle

app.yaml pins runtime: python312. python314 is GA on App Engine standard (gcloud app runtimes list --environment=standard), and the port turns out to be small — I ran it end to end locally.

The blockers, and what each actually costs

1. import cgi at ide/routes.py:36 — a dead import.

cgi was removed in Python 3.13 (PEP 594), so today a fresh 3.13+ venv cannot even import the app:

ide/routes.py:36: in <module>
    import cgi
E   ModuleNotFoundError: No module named 'cgi'

But there are zero uses of cgi. anywhere in the tree — it is an unused import. Deleting the line is the whole fix. No html.escape migration, no request-parsing rewrite.

Nothing else from PEP 594 is used (checked cgitb, telnetlib, imghdr, sndhdr, nntplib, smtpd, distutils, pipes, crypt, spwd, audioop, chunk — all absent).

2. Two requirements.txt pins.

google-cloud-datastore 2.23.0 depends on grpcio<2.0.0 and >=1.75.1; python_version >= "3.14"

but we pin grpcio==1.73.1. Bumping that alone then collides with grpcio-status==1.63.0rc1 (a release candidate, pinned against a 2024 google-api-core). Both need to move together:

-grpcio==1.73.1
-grpcio-status==1.63.0rc1
+grpcio==1.83.1
+grpcio-status==1.83.1

Verified

With those three edits, on a real 3.14.6 interpreter:

$ /tmp/gsvenv314/bin/python -m pytest tests/ -q --ignore=tests/test_e2e.py
2 failed, 22 passed

Identical to the 3.12 baseline — the same two test_plotusers failures, which pre-exist on master and are unrelated (confirmed by running master under 3.12). test_e2e.py is excluded in both cases because it needs playwright.

I also confirmed the intermediate step: with only the cgi line removed, the app imports cleanly under the repo's existing 3.13 .venv.

Why it is worth doing now rather than later

The repo currently ships a .venv on Python 3.13, where the test suite cannot run at all. Anyone creating a fresh environment hits ModuleNotFoundError: No module named 'cgi' and reasonably concludes the tests are broken. That is a trap for exactly the newcomer we would want running tests.

Suggested order

  1. Delete ide/routes.py:36. Independent of everything else, unblocks 3.13 and 3.14 alike, and can go in on its own.
  2. Bump the two grpcio pins.
  3. Flip app.yaml to runtime: python314 and deploy to a --no-promote version first.

Steps 1 and 2 are safe to merge before anyone is ready to change the runtime — they are a no-op on 3.12.

Unrelated but adjacent

pytest-mock is missing from requirements.txt although tests/conftest.py requires the mocker fixture. Without it, tests error at setup rather than fail, which reads like broken tests rather than a missing dependency. Worth adding in the same pass.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions