Skip to content

Empty vs filled cache inconsistency for google-cloud-logging & google-cloud-pubsub together with type: ignore comments #19037

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sh-at-cs opened this issue May 5, 2025 · 3 comments · Fixed by #19044
Labels
bug mypy got something wrong topic-incremental

Comments

@sh-at-cs
Copy link

sh-at-cs commented May 5, 2025

Bug Report

Running Mypy on a certain set of files (see below) that import things from both the google-cloud-logging and google-cloud-pubsub packages with some # type: ignore comments applied results in different type checking outcomes (failure vs success) depending on whether the cache has been populated or not.

To Reproduce

Note: There is a bash script at the end of this section to make reproducing this more convenient!

  1. Create a package bug with an __init__.py and these two files:

foo.py:

import google.cloud.logging

client = google.cloud.logging.Client()  # type: ignore[no-untyped-call]

bar.py:

from google.cloud.pubsub_v1 import PublisherClient  # type: ignore[import-untyped]

publisher: PublisherClient = PublisherClient()
  1. Create a venv with mypy, google-cloud-logging, and google-cloud-pubsub installed.

  2. Ensure there is no .mypy_cache dir present.

  3. Run mypy --strict bug/ twice.

❗ Script to perform all these steps automatically

Needs uv to be installed.

#!/bin/bash

# Prepare directory:

rm -rf bug/ .mypy_cache/

mkdir bug
touch bug/__init__.py

cat > bug/foo.py <<HEREDOC
import google.cloud.logging

client = google.cloud.logging.Client()  # type: ignore[no-untyped-call]
HEREDOC

cat > bug/bar.py <<HEREDOC
from google.cloud.pubsub_v1 import PublisherClient  # type: ignore[import-untyped]

publisher: PublisherClient = PublisherClient()
HEREDOC

# Run Mypy:

MYPY="uv run --with google-cloud-logging,google-cloud-pubsub,mypy mypy"

echo "***** Version info: *****"
$MYPY --version

echo "***** First invocation: *****"
$MYPY --strict bug/

echo "***** Second invocation: *****"
$MYPY --strict bug/

Expected Behavior

Both mypy invocations result in the same outcome.

Actual Behavior

The first invocation reports some errors:

$ mypy --strict bug/
bug/foo.py:1: error: Skipping analyzing "google.cloud": module is installed, but missing library stubs or py.typed marker  [import-untyped]
bug/foo.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
bug/foo.py:1: error: Skipping analyzing "google": module is installed, but missing library stubs or py.typed marker  [import-untyped]
bug/foo.py:3: error: Unused "type: ignore" comment  [unused-ignore]
Found 3 errors in 1 file (checked 3 source files)

While the second invocation reports success:

$ mypy --strict bug/
Success: no issues found in 3 source files

Your Environment

  • Mypy version used: 1.15.0, but I also tried with the current master and it's the same
  • Mypy command-line flags: --strict to get 1 more error that differs between invocations, but the basic issue also appears without it
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.13.2

Additional Context

I'm actually trying to create a minimal reproducible example for a slightly different, more severe issue involving these two packages, in which there is no possible configuration of type: ignore comments (or lack thereof) that satisfies Mypy, but this is proving much more difficult to boil down (only seems to happen in our production repo). My hope is that this issue here is "related enough" to it that fixing one will fix both 🤞 Never mind, putting # type: ignore on all of the imports but none of the usages did satisfy Mypy. But this issue here still made it needlessly difficult to arrive at that solution by trial and error, and it hints at perhaps more general caching bugs, so it should still be fixed IMHO.

Related Issues

@sh-at-cs sh-at-cs added the bug mypy got something wrong label May 5, 2025
@sterliakov
Copy link
Collaborator

We definitely have problems when only sub-packages contain py.typed markers, also #16149.

$ find .venv/lib/python3.13/site-packages/google -name 'py.typed'
.venv/lib/python3.13/site-packages/google/auth/py.typed
.venv/lib/python3.13/site-packages/google/oauth2/py.typed
.venv/lib/python3.13/site-packages/google/api_core/py.typed
.venv/lib/python3.13/site-packages/google/pubsub_v1/py.typed
.venv/lib/python3.13/site-packages/google/pubsub/py.typed
.venv/lib/python3.13/site-packages/google/cloud/appengine_logging/py.typed
.venv/lib/python3.13/site-packages/google/cloud/appengine_logging_v1/py.typed
.venv/lib/python3.13/site-packages/google/cloud/logging_v2/py.typed
.venv/lib/python3.13/site-packages/google/cloud/logging/py.typed
.venv/lib/python3.13/site-packages/google/cloud/_http/py.typed
.venv/lib/python3.13/site-packages/google/cloud/environment_vars/py.typed
.venv/lib/python3.13/site-packages/google/cloud/obsolete/py.typed
.venv/lib/python3.13/site-packages/google/cloud/_testing/py.typed
.venv/lib/python3.13/site-packages/google/cloud/exceptions/py.typed
.venv/lib/python3.13/site-packages/google/cloud/operation/py.typed
.venv/lib/python3.13/site-packages/google/cloud/client/py.typed
.venv/lib/python3.13/site-packages/google/cloud/_helpers/py.typed

@sterliakov
Copy link
Collaborator

If anyone wants to jump in, the following can be used to achieve reasonable check times and iterate quickly while still reproducing the same errors (assuming direct installation in venv in cwd instead of uv run --with):

rm -rf .venv/lib/python*/site-packages/google/{api,api_core,auth,gapic,iam,longrunning,oauth2,protobuf,pubsub,pubsub_v1,rpc,type,_upb,logging}
rm -rf .venv/lib/python*/site-packages/google/cloud/{appengine_logging,appengine_logging_v1,_helpers,_testing,pubsub,location,obsolete,_http,audit,exceptions,operation,environment_vars,logging_v2/{handlers,services,types},pubsub_v1/{types,publisher,subscriber}}

@sterliakov
Copy link
Collaborator

Okay, the behaviour of 2nd and subsequent runs seems to be correct. As usual, there are two things that are most difficult to get correctly... And this one is a caching issue.

When we look up sources, we may run build.in_partial_package. It swallows ModuleNotFound errors, but the lookup result is cached at a lower level. This block should've caught our case:

mypy/mypy/modulefinder.py

Lines 579 to 581 in bd1f51a

ancestor = self.ns_ancestors.get(id)
if ancestor is not None:
return ancestor

...except that it doesn't because in_partial_package was called too early, ns_ancestors wasn't populated yet. And cache is already poisoned with ModuleNotFoundReason.NOT_FOUND, so we will happily return that when asked for google next time.

I have a patch for this, but haven't managed to extract a simple testcase yet. Let's move the following discussion to #19044.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-incremental
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants