Class `date` is unsafe in typed Python

Hello,

I’d like to discuss adding an optional mypy feature that rejects unsafe subtype-based usage between date and datetime.

Currently the following code passes type checking but raises TypeError at runtime:

from datetime import date, datetime

if datetime.now() < date.today():
    print("that's a surprise!")

This happens because datetime inherits from date, but does not fully behave as a substitutable subtype. In particular, ordering comparisons between date and datetime raise TypeError.

This mismatch has been a long-standing source of subtle runtime errors that type checkers currently do not catch.

I’ve opened a prototype implementation in mypy:

One design consideration is that this is not merely a check for comparisons that would fail at runtime. In practice, the implementation works by restricting use of the datetime <: date subtype relationship itself. Detecting only comparison operations would be incomplete and would miss many cases where the relationship has already been relied upon by the type checker.

This proposal assumes no changes to typeshed and preserves current runtime inheritance relationships.

I would appreciate feedback on the following questions:

Assuming this is implemented as an optional feature, should it be:
  • a new error code (enabled when feature is on)
  • a dedicated flag
0 voters

I also briefly considered a more general mechanism for handling known problematic subtype relationships (for example bool/int or str/Iterable[str]; suggested by Jukka). However, similar discussions already exist for those cases, and I think it is easier to evaluate the date/datetime case on its own merits before considering a broader framework.

I would also welcome any feedback on the PR, particularly on the design and scope.

What should be a name of the feature?
  • safe-datetime
  • strict-date
  • other (comment)
0 voters
Chronological references
3 Likes