@@ -699,3 +699,55 @@ Example:
699699 @printing_decorator # E: Untyped decorator makes function "add_forty_two" untyped [untyped-decorator]
700700 def add_forty_two (value : int ) -> int :
701701 return value + 42
702+
703+ .. _code-unsafe-subtype :
704+
705+ Check for unsafe subtype relationships [unsafe-subtype]
706+ --------------------------------------------------------
707+
708+ If enabled with :option: `--enable-error-code unsafe-subtype <mypy --enable-error-code> `,
709+ mypy will block certain subtype relationships that are unsafe at runtime despite
710+ being valid in Python's type system.
711+
712+ The primary use case is blocking the ``datetime.datetime `` to ``datetime.date ``
713+ inheritance relationship. While ``datetime `` is a subclass of ``date `` at runtime,
714+ comparing a ``datetime `` with a ``date `` raises a ``TypeError ``. When this error
715+ code is enabled, mypy will prevent ``datetime `` objects from being used where
716+ ``date `` is expected, catching these errors at type-check time.
717+
718+ Example:
719+
720+ .. code-block :: python
721+
722+ # mypy: enable-error-code="unsafe-subtype"
723+ from datetime import date, datetime
724+
725+ # Error: Incompatible types in assignment (expression has type "datetime", variable has type "date")
726+ d: date = datetime.now()
727+
728+ def accept_date (d : date) -> None :
729+ pass
730+
731+ # Error: Argument 1 to "accept_date" has incompatible type "datetime"; expected "date"
732+ accept_date(datetime.now())
733+
734+ Without this error code enabled, the above code passes type checking (as ``datetime ``
735+ is a valid subtype of ``date ``), but comparisons between the two types will fail at
736+ runtime:
737+
738+ .. code-block :: python
739+
740+ from datetime import date, datetime
741+
742+ dt = datetime.now()
743+ d = date.today()
744+
745+ # This raises: TypeError: can't compare datetime.datetime to datetime.date
746+ if dt < d:
747+ print (" never reached" )
748+
749+ When ``unsafe-subtype `` is enabled, assignment and parameter passing are blocked,
750+ preventing the runtime error.
751+
752+ **Note: ** Equality comparisons (``== `` and ``!= ``) still work between these types,
753+ as ``__eq__ `` accepts ``object `` as its parameter.
0 commit comments