Type annotations in Django's tests?

Is there a policy on using type annotations (or type comments) in Django’s own test cases? (I know Django doesn’t use typing in the package code.)

I’m updating several cases in tests/mail/tests.py, and a handful of well-placed type annotations would really improve readability—particularly with an IDE that does type inference and can flag problems when given a few hints.

The mail tests use variations on “message” and “email” to refer to all of:

  • django.core.mail.EmailMessage or a subclass (usually “email,” but often “msg” or “email_msg”)
  • Python email.message.Message (usually “message,” but sometimes “msg”)
  • a local str variable to improve formatting of assertRaisesMessage() (almost always msg)

And I’m about to add Python’s email.message.EmailMessage to the mix.

Yes, it’s usually clear what’s meant from context. But it gets trickier with test helpers like assertMessageHasHeaders(), get_the_message(), get_mailbox_content(), etc. (And don’t get me started on “outbox” vs. “mailbox” and the multiple meanings of “content.”)

If type annotations are a no-go even in tests, how do we feel about Sphinx :param:, :type: and :rtype: directives in docstrings?

The existing policy is no type annotations.

There’s been some discussion about whether to revisit that. (Please don’t read too much into that. The policy stands :sweat_smile:)

The idea might be that small areas that could benefit could incrementally have such annotations added. But that’s only a maybe.

I think it might be interesting here if you could make a draft PR with the suggested change, and then show how that leads to wins.

A additional step might be to craft the minimal mypy config to check only those few annotated functions.

Doing so would allow a much more concrete discussion I think.

(I can’t imagine anything happening very quickly here, just to set expectations.)

I hope that makes sense.

1 Like

Thanks for the info and suggestions.

I was really just looking to improve coding assistance in editors that make use of lazy type inference—not trying to actually enforce type checking anywhere. This is probably better experienced than described, but I’ll try think about a useful demonstration that might fit in a draft PR. (Perhaps an interim commit from what I’m working on in the mail tests.)

In the meantime, it looks like Django already has some docstrings with Sphinx :param: type directives, so I guess those are OK? Docstring typing enables similar coding assistance in PyCharm (though excludes VS Code users), and I’ll probably just go that route for now.