Skip to content

[Flask-Cors] Update type annotation for origins to also allow Pattern#15825

Open
wvanbergen wants to merge 2 commits into
python:mainfrom
wvanbergen:wvanbergen/Flask-Cors
Open

[Flask-Cors] Update type annotation for origins to also allow Pattern#15825
wvanbergen wants to merge 2 commits into
python:mainfrom
wvanbergen:wvanbergen/Flask-Cors

Conversation

@wvanbergen
Copy link
Copy Markdown

@wvanbergen wvanbergen commented May 23, 2026

Small fix: this updates the type annotation for the origins argument for CORS() and CORS.init_app to also accept Patterns. Also, use Iterable rather than list to not cause compatibility issues.

@github-actions

This comment has been minimized.

@wvanbergen wvanbergen force-pushed the wvanbergen/Flask-Cors branch from ed1a6d6 to 555f3da Compare May 23, 2026 10:13
@github-actions
Copy link
Copy Markdown
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Copy link
Copy Markdown
Collaborator

@brianschubert brianschubert left a comment

Choose a reason for hiding this comment

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

Thanks! See remarks below. This change looks good, but I'm noticing some inconsistencies with the previous annotations that we should fix while we're here.

Comment on lines +16 to 19
origins: str | Pattern[str] | Iterable[str | Pattern[str]] | None
methods: str | list[str] | None
expose_headers: str | list[str] | None
allow_headers: str | list[str] | None
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Unless I'm missing something, it appears that these function assume that the options have already been processed with serialize_options, which wraps a single string or pattern object in a list to ensure that origins is iterable. They'll raise a TypeError if you attempt to use a plain pattern object.

It also doesn't appear that None (or [None]) is a valid value (will also raise a TypeError). I'm guessing that that was added since the options are accessed with options.get(...), which suggests that None could be returned. But in actuality the options dict is pre-populated with the values from DEFAULT_OPTIONS, which sets non-None defaults, so I don't think a None value is ever valid?

A few examples of what I'm talking about:

# Non-iterable origins wrapped in list
$ uv run -w flask_cors python3 -c 'import flask_cors.core as c; print(c.serialize_options({"origins": "foo"}))'
{'origins': ['foo'], 'allow_headers': [None]}

# Raise on plain pattern object for origins
$ uv run -w flask_cors python3 -c 'import flask_cors.core as c; import re; print(c.get_cors_origins({"origins": re.compile("foo")}, "foo"))'
TypeError: argument of type 're.Pattern' is not a container or iterable

# Raise on None for origins
$ uv run -w flask_cors python3 -c 'import flask_cors.core as c; import re; print(c.get_cors_origins({"origins": None}, "foo"))'
TypeError: argument of type 'NoneType' is not a container or iterable

# Raise on [None] for origins
$ uv run -w flask_cors python3 -c 'import flask_cors.core as c; import re; print(c.get_cors_origins({"origins": [None]}, "foo"))'
TypeError: argument of type 'NoneType' is not a container or iterable

Does that match your experience?

The same appears to be true for allow_headers, so I'd suggest using the same type for it. It also appears that some of the other options can't be None in practice -- up to you if you want to try to fix those while we're here.

Suggested change
origins: str | Pattern[str] | Iterable[str | Pattern[str]] | None
methods: str | list[str] | None
expose_headers: str | list[str] | None
allow_headers: str | list[str] | None
origins: Iterable[str | Pattern[str]]
methods: str | list[str] | None
expose_headers: str | list[str] | None
allow_headers: Iterable[str | Pattern[str]]

*,
resources: dict[str, dict[str, Any]] | list[str] | str | None = ...,
origins: str | list[str] | None = ...,
origins: str | Pattern[str] | Iterable[str | Pattern[str]] | None = ...,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Per above, it doesn't appear that passing None is valid.

Suggested change
origins: str | Pattern[str] | Iterable[str | Pattern[str]] | None = ...,
origins: str | Pattern[str] | Iterable[str | Pattern[str]] = ...,

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.

2 participants