Skip to content

Add mypy annotations and mark it as checkable.#76

Merged
alexprengere merged 8 commits intocolour-science:masterfrom
orborde:claude/fix-flask-compress-mypy-ORAw4
Feb 25, 2026
Merged

Add mypy annotations and mark it as checkable.#76
alexprengere merged 8 commits intocolour-science:masterfrom
orborde:claude/fix-flask-compress-mypy-ORAw4

Conversation

@orborde
Copy link
Copy Markdown
Contributor

@orborde orborde commented Feb 23, 2026

Currently, when I run mypy on my flask-compress-using project, I get the following sad message:

web_server.py:24: error: Skipping analyzing "flask_compress": module is installed, but missing library stubs or py.typed marker  [import-untyped]
web_server.py:24: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports

This PR does two things to fix that:

  1. Marks the package as py.typed to tell mypy that, yes, it's typed and should not be skipped (nor require import-typed in mypy-using projects).
  2. Adds type annotations to most functions/members so that it actually means something to claim "this package can be checked by mypy".

The code changes in this PR were mostly generated by an AI, but under the close supervision of a human with substantial SWE experience. 🙂

claude and others added 5 commits February 23, 2026 10:24
Without a py.typed marker, mypy skips analyzing flask_compress with
the error "module is installed, but missing library stubs or py.typed
marker [import-untyped]". Adding the marker declares PEP 561
compliance so mypy will process the package's inline types.

https://claude.ai/code/session_01PDkg6syU6fe15ngPYLPoyT
Annotates all functions and classes in flask_compress.py:
- DictCache: typed dict storage with str keys and bytes values
- Compress: Flask app parameter, cache, and config attribute types
- _choose_algorithm, _format, _compress_data, _uncompress_data,
  _compress_chunks: full parameter and return type annotations

Uses `from __future__ import annotations` for modern union syntax
on Python 3.9+.

https://claude.ai/code/session_01PDkg6syU6fe15ngPYLPoyT
- Silence brotli/brotlicffi import errors (no stubs available)
- Add explicit type for algos_by_quality defaultdict (set[str | None])
- Assert cache_key is not None when cache is present
- Pass weak=False directly in set_etag (is_weak is falsy in that branch)

mypy now reports: "Success: no issues found in 4 source files"
All 55 tests pass.

https://claude.ai/code/session_01PDkg6syU6fe15ngPYLPoyT
@alexprengere
Copy link
Copy Markdown
Collaborator

The PR looks good, thanks!

Would it be possible to enforce the type checking by either updating pre-commit or GitHub Actions?

Configure mypy in strict mode via pre-commit (mirrors-mypy v1.19.1)
with Flask as an additional dependency. Add [tool.mypy] config to
pyproject.toml with warn_return_any disabled since third-party
compression libraries lack type stubs.

https://claude.ai/code/session_01PDkg6syU6fe15ngPYLPoyT
Keep mypy strict mode fully enabled. Suppress no-any-return only at the
8 specific call sites where untyped third-party compression libraries
(brotli, zstd, gzip, zlib) return Any.

https://claude.ai/code/session_01PDkg6syU6fe15ngPYLPoyT
# This is used for tests purposes only.
if algorithm == "zstd":
return compression.zstd.decompress(data)
return compression.zstd.decompress(data) # type: ignore[no-any-return]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type: ignore is needed because compression is a SimpleNamespace indirection instead of a pile of direct module references. Fortunately, if this ever changes, mypy will flag this ignore as unnecessary.

Along the way, added a CacheBackend Protocol to represent the common interface of flask_caching.Cache + DictCache for type-checking purposes.
@orborde
Copy link
Copy Markdown
Contributor Author

orborde commented Feb 24, 2026

Would it be possible to enforce the type checking by either updating pre-commit or GitHub Actions?

Done. Thankfully I just needed to add some stuff to pre-commit (and a bunch of mostly repetitive updates to make the tests pass mypy).

We could get rid of the -> None that's all over the tests by adding the following to pyproject.toml:

[mypy-tests.*]
disallow_untyped_defs = false

I elected to just live with the boilerplate since I think it's more valuable for a library to have all the checks passing at their strictest, but I can do the above instead if you prefer.

Also, sorry for the spammy commit history; I thought (and still think) such a mechanical cleanup would be a good task for LLMs, but I'm still learning how to use the tooling.

@alexprengere alexprengere merged commit 4ab0b11 into colour-science:master Feb 25, 2026
25 checks passed
@alexprengere
Copy link
Copy Markdown
Collaborator

Great, thanks!

@orborde orborde deleted the claude/fix-flask-compress-mypy-ORAw4 branch February 25, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants