Skip to content

Restore Blueprint support in CORS type signatures (#410) - #411

Merged
corydolphin merged 1 commit into
mainfrom
claude/gallant-einstein-lzvx7r
Jun 8, 2026
Merged

Restore Blueprint support in CORS type signatures (#410)#411
corydolphin merged 1 commit into
mainfrom
claude/gallant-einstein-lzvx7r

Conversation

@corydolphin

Copy link
Copy Markdown
Owner

Summary

Fixes #410.

The strict typing added in #409 (released in 6.0.4) narrowed the app parameter of CORS.__init__/init_app to Flask | None. Flask-CORS supports applying CORS directly to a Blueprint at runtime — get_app_kwarg_dict already guards for the missing config attribute, and the exception-handler wrapping is guarded by hasattr(app, "handle_exception") — so passing a Blueprint still worked, but it began failing mypy --strict for downstream users:

error: Argument 1 to "CORS" has incompatible type "Blueprint"; expected "Flask | None"  [arg-type]

This realigns the type annotation with the behavior the runtime guards already implement.

Changes

  • Widen the accepted type to Flask | Blueprint | None on CORS.__init__, init_app, and the internal merge_options / get_cors_options / get_app_kwarg_dict helpers.
  • Route the Flask-only make_response / handle_exception accesses through an Any alias, gated by the existing hasattr guard, so the wider union type-checks cleanly (no behavior change — the block already only ran for full apps).
  • Add runtime tests exercising CORS on a Blueprint via both the constructor and init_app (there was previously no Blueprint test coverage).
  • Add a type-checking regression test (tests/typecheck/) included in the mypy files list, so a future narrowing of the signature fails CI. Verified: reverting the signature makes mypy fail on exactly that test.
  • Type-check the examples/ directory under strict mypy as well, fixing the non-exported os.sys path hack and adding view return annotations.

Verification

  • mypy — clean (9 source files)
  • pytest — 98 passed, 1 skipped
  • ruff — clean

Follow-up

6.0.4 isn't broken at runtime (it only fails strict typing for Blueprint users), so the suggested path is to release this as 6.0.5 and then yank 6.0.4 on PyPI with a reason pointing at 6.0.5 (yank keeps it installable for anyone already pinned, while steering new installs past it).


Generated by Claude Code

The strict typing added in #409 (released in 6.0.4) narrowed the ``app``
parameter of ``CORS.__init__``/``init_app`` to ``Flask | None``. Flask-CORS
supports applying CORS directly to a ``Blueprint`` at runtime
(``get_app_kwarg_dict`` already guards for the missing ``config`` attribute,
and the exception-handler wrapping is guarded by ``hasattr``), so passing a
Blueprint still worked but failed ``mypy --strict`` for downstream users.

- Widen the accepted type to ``Flask | Blueprint | None`` on ``CORS.__init__``,
  ``init_app``, and the internal ``merge_options`` / ``get_cors_options`` /
  ``get_app_kwarg_dict`` helpers.
- Route the Flask-only ``make_response`` / ``handle_exception`` accesses through
  an ``Any`` alias, gated by the existing ``hasattr`` guard, so the union type
  checks cleanly.
- Add runtime tests exercising CORS on a Blueprint via both the constructor and
  ``init_app`` (there was previously no Blueprint test coverage).
- Add a type-checking regression test (``tests/typecheck``) included in the mypy
  ``files`` list so a future narrowing of the signature fails CI.
- Type-check the ``examples`` directory under strict mypy as well, fixing the
  ``os.sys`` path hack and adding view return annotations.
@corydolphin
corydolphin merged commit 91ebc49 into main Jun 8, 2026
7 checks passed
@corydolphin
corydolphin deleted the claude/gallant-einstein-lzvx7r branch June 8, 2026 19:59
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.

MyPy Strict typing broke support for Flask Blueprint in 6.0.4

2 participants