Determine this is the right repository
Summary of the issue
Context
An application uses google-cloud-firestore (e.g. version 2.27.0) as a dependency on Python 3.10–3.13 and executes:
from google.cloud import firestore
Expected Behavior:
from google.cloud import firestore succeeds.
Actual Behavior:
from google.cloud import firestore fails with:
ModuleNotFoundError: No module named 'typing_extensions'
The root cause is in firestore itself: google/cloud/firestore_v1/async_transaction.py (line 31) directly imports typing_extensions, but the package does not declare it in setup.py or testing/constraints-*.txt. In practice this only fires when no other dependency provides typing-extensions transitively — most commonly when grpcio < 1.75.0 is resolved, which is within firestore's own declared range. To be explicit: grpcio < 1.75.0 is the trigger that exposes the defect, not the cause; the defect is firestore's undeclared direct import. See "Why this manifests" in Additional context for the full mechanism.
API client name and version
google-cloud-firestore 2.27.0
Reproduction steps: code
file: repro.sh
python -m venv venv
venv/bin/pip install "google-cloud-firestore" "grpcio==1.74.0"
venv/bin/python -c "from google.cloud import firestore"
Reproduction steps: supporting files
N/A
Reproduction steps: actual results
file: stderr.txt
Traceback (most recent call last):
File "<string>", line 1, in <module>
from google.cloud import firestore
File ".../site-packages/google/cloud/firestore/__init__.py", line 18, in <module>
from google.cloud.firestore_v1 import gapic_version as package_version
File ".../site-packages/google/cloud/firestore_v1/__init__.py", line 33, in <module>
from google.cloud.firestore_v1.async_client import AsyncClient
File ".../site-packages/google/cloud/firestore_v1/async_client.py", line 50, in <module>
from google.cloud.firestore_v1.async_transaction import AsyncTransaction
File ".../site-packages/google/cloud/firestore_v1/async_transaction.py", line 31, in <module>
from typing_extensions import Concatenate, ParamSpec, TypeVar
ModuleNotFoundError: No module named 'typing_extensions'
Reproduction steps: expected results
file: stderr.txt
(no output — import succeeds)
OS & version + platform
Debian GNU/Linux 13 (trixie)
Python environment
Python 3.13.13
Python dependencies
$ pip list
Package Version
------------------------ ---------
certifi 2026.5.20
cffi 2.0.0
charset-normalizer 3.4.7
cryptography 48.0.0
google-api-core 2.30.3
google-auth 2.53.0
google-cloud-core 2.6.0
google-cloud-firestore 2.27.0
googleapis-common-protos 1.75.0
grpcio 1.74.0
grpcio-status 1.69.0
idna 3.16
proto-plus 1.28.0
protobuf 5.29.6
pyasn1 0.6.3
pyasn1-modules 0.4.2
pycparser 3.0
requests 2.34.2
urllib3 2.7.0
Additional context
Why this manifests the way it does
typing-extensions was added to grpcio's requires_dist only in grpcio 1.75.0. Any grpcio in firestore's declared range (1.44.0–1.74.x on Python 3.10–3.13) does not pull typing-extensions in transitively, leaving firestore's own import unresolved.
- The failure surfaces directly in firestore's own source code at
async_transaction.py:31, not inside grpc. grpcio 1.74.0 does not use typing_extensions internally, so the import chain reaches firestore's undeclared import without any intermediate grpcio failure. This forecloses any "this is a grpcio bug" interpretation.
- The bug is also statically visible in the source:
async_transaction.py line 31 imports it, setup.py does not declare it.
- Python 3.14 is incidentally protected (not actually fixed) by firestore's extra
grpcio >= 1.75.1; python_version >= '3.14' constraint, which forces a grpcio version that does declare typing-extensions.
Even setting aside the runtime failure described above, firestore should declare what it directly imports, regardless of any particular grpcio version's transitive behavior. The fix is warranted on PEP 508 conformance grounds alone; the runtime failure on grpcio < 1.75 is just the most visible consequence of that violation. A sibling package in this monorepo (bigframes) already declares typing-extensions>=4.5.0,<5, so there is recent precedent for the declaration.
Workaround for affected users
Until a fix is released, applications hitting this bug can either:
- Pin or constrain
grpcio>=1.75.0 in their own requirements (gets typing-extensions transitively via grpcio's declaration), or
- Add
typing-extensions explicitly to their own requirements as a direct dependency.
The first workaround relies on grpcio 1.75.0 incidentally papering over the bug, not on a fix. Users who pin grpcio for legitimate reasons (downstream compatibility, OS package availability) cannot apply it and must use the second.
Recommended fix
Declare typing-extensions >= 4.5.0, < 5.0.0 in setup.py (matching the sibling bigframes package, which targets a release published after Python 3.11 GA). This keeps async_transaction.py:31 unchanged.
An alternative would be to switch that import to the stdlib typing module (Concatenate and ParamSpec are available there since Python 3.10), which would avoid adding a dependency at the cost of changing the import. Open to maintainer preference.
Happy to submit a PR for either direction.
Determine this is the right repository
Summary of the issue
Context
An application uses
google-cloud-firestore(e.g. version 2.27.0) as a dependency on Python 3.10–3.13 and executes:Expected Behavior:
from google.cloud import firestoresucceeds.Actual Behavior:
from google.cloud import firestorefails with:The root cause is in firestore itself:
google/cloud/firestore_v1/async_transaction.py(line 31) directly importstyping_extensions, but the package does not declare it insetup.pyortesting/constraints-*.txt. In practice this only fires when no other dependency providestyping-extensionstransitively — most commonly whengrpcio < 1.75.0is resolved, which is within firestore's own declared range. To be explicit:grpcio < 1.75.0is the trigger that exposes the defect, not the cause; the defect is firestore's undeclared direct import. See "Why this manifests" in Additional context for the full mechanism.API client name and version
google-cloud-firestore 2.27.0
Reproduction steps: code
file: repro.sh
Reproduction steps: supporting files
N/A
Reproduction steps: actual results
file: stderr.txt
Reproduction steps: expected results
file: stderr.txt
OS & version + platform
Debian GNU/Linux 13 (trixie)
Python environment
Python 3.13.13
Python dependencies
Additional context
Why this manifests the way it does
typing-extensionswas added to grpcio'srequires_distonly in grpcio 1.75.0. Any grpcio in firestore's declared range (1.44.0–1.74.x on Python 3.10–3.13) does not pulltyping-extensionsin transitively, leaving firestore's own import unresolved.async_transaction.py:31, not insidegrpc. grpcio 1.74.0 does not usetyping_extensionsinternally, so the import chain reaches firestore's undeclared import without any intermediate grpcio failure. This forecloses any "this is a grpcio bug" interpretation.async_transaction.pyline 31 imports it,setup.pydoes not declare it.grpcio >= 1.75.1; python_version >= '3.14'constraint, which forces a grpcio version that does declare typing-extensions.Even setting aside the runtime failure described above, firestore should declare what it directly imports, regardless of any particular grpcio version's transitive behavior. The fix is warranted on PEP 508 conformance grounds alone; the runtime failure on grpcio < 1.75 is just the most visible consequence of that violation. A sibling package in this monorepo (
bigframes) already declarestyping-extensions>=4.5.0,<5, so there is recent precedent for the declaration.Workaround for affected users
Until a fix is released, applications hitting this bug can either:
grpcio>=1.75.0in their own requirements (getstyping-extensionstransitively via grpcio's declaration), ortyping-extensionsexplicitly to their own requirements as a direct dependency.The first workaround relies on grpcio 1.75.0 incidentally papering over the bug, not on a fix. Users who pin grpcio for legitimate reasons (downstream compatibility, OS package availability) cannot apply it and must use the second.
Recommended fix
Declare
typing-extensions >= 4.5.0, < 5.0.0insetup.py(matching the siblingbigframespackage, which targets a release published after Python 3.11 GA). This keepsasync_transaction.py:31unchanged.An alternative would be to switch that import to the stdlib
typingmodule (ConcatenateandParamSpecare available there since Python 3.10), which would avoid adding a dependency at the cost of changing the import. Open to maintainer preference.Happy to submit a PR for either direction.