Skip to content

Message covariant type annotation #240

@adanaja

Description

@adanaja

@davidism I noticed something which led me to the PR for adding static type annotations #221

This modified version of the simple example shown in the README (notice the added recipients = ["[email protected]"]):

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)
app.config["MAIL_SERVER"] = "your_mail_server"
app.config["MAIL_PORT"] = 587
app.config["MAIL_USE_TLS"] = True
app.config["MAIL_USE_SSL"] = False
app.config["MAIL_USERNAME"] = "your_username"
app.config["MAIL_PASSWORD"] = "your_password"
app.config["MAIL_DEFAULT_SENDER"] = "[email protected]"

mail = Mail(app)


@app.route("/")
def send_email() -> str:
    recipients = ["[email protected]"]

    msg = Message(
        "Hello",
        recipients=recipients,
        body="This is a test email sent from Flask-Mail!",
    )
    mail.send(msg)
    return "Email sent succesfully!"

Makes mypy output this error:

error: Argument "recipients" to "Message" has incompatible type "list[str]"; expected "list[str | tuple[str, str]] | None"  [arg-type]
note: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
note: Consider using "Sequence" instead, which is covariant

This is because the recipients variable is considered of type list[str] and not list[str | tuple[str, str]] by mypy.

Now it could be easy to fix the error by explicitly setting the type:

    recipients: list[str | tuple[str, str]] = ["[email protected]"]

    msg = Message(
        "Hello",
        recipients=recipients,
        body="This is a test email sent from Flask-Mail!",
    )

But doing that is not really safe as the type should be modified if someday Message changes the accepted type. Ideally it should work transparently with list[str].

So I don't know if it could be possible to make Message accept a Sequence as mypy suggests, or maybe list[str] | list[tuple[str, str]]?

I used:

  • mypy 1.16.1
  • flask 3.1.1
  • flask_mail 0.10.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions