I’m trying to type the replace()
method for a subclass of Python 3.13 datetime class, and I’m somewhat puzzled.
First, the tzinfo
arg in the implementation here has the default value True
and in the documentation here self.tzinfo
and the type annotation in Typeshed here says _TzInfo | None
. For now I’m going with what the type annotation says, but True
seems really far off.
Second, the existing type annotations here for replace()
state SupportsIndex = ...
which, confusingly, doesn’t look like an optional arg. If in my subclass I use that exact same annotation
class DateTime(datetime):
def replace(
self,
year: typing.SupportsIndex = ...,
# The rest.
) -> Self:
# Do stuff.
then I get a mypy error
error: Incompatible default for argument "year" (default has type "EllipsisType", argument has type "SupportsIndex") [assignment]
If I go with year: int | None = None
— where int
indeed implements the SupportsIndex
protocol, and making it optional — I get an error
error: Signature of "replace" incompatible with supertype "date" [override]
note: Superclass:
note: def replace(self, year: SupportsIndex = ..., month: SupportsIndex = ..., day: SupportsIndex = ...) -> datetime
note: Subclass:
note: def replace(self, year: int | None = ..., month: int | None = ..., day: int | None = ..., hour: int | None = ..., minute: int | None = ..., second: int | None = ..., microsecond: int | None = ..., tzinfo: tzinfo | None = ..., *, fold: int | None = ...) -> datetime
error: Argument 1 of
"replace" is incompatible with supertype "datetime"; supertype defines the
argument type as "SupportsIndex" [override]
note: This violates the Liskov substitution principle
note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
I poked around for more details and found this and this article, but nothing that helps this situation.
Can somebody please shed some light on all of this? Thank you!