Hi everyone
I’d like to propose a solution to a problem that I keep running into regularly at work. The names of the attributes of datetime.timedelta
objects, .days
, .seconds
, and .microseconds
, are very easily mistaken as representation of the full accumulated value of the timedelta
object. However, the only exposed way of accessing that is through the .total_seconds()
method. Instead, these attributes rather represents broken apart pieces of a timedelta at different resolutions, that when added together make up the full value.
This issue has surfaced countless of times in code review, and I bet we have lingering production bugs that are due to this, yet to be discovered. This is also backed up by the fact that the .seconds
attribute has a special warning call-out in the documentation that informs of this common mixup.
To remedy this issue, I would like to propose a long-term plan of phasing these three attributes out, in preference of a set of new and more verbose names. The attributes would be renamed like below (though feel free to suggest other naming schemes):
timedelta.days
→timedelta.part_days
timedelta.seconds
→timedelta.part_seconds
timedelta.microseconds
→timedelta.part_microseconds
The idea of this renaming is that the new names in a much better way are communicating that they are not the full timedelta value, but only a part of it.
In order not to break any existing code, and give plenty of time for users to migrate, the old names will be considered deprecated aliases of the new ones. The implementation could for example be done as @property
methods that return the underlying values.
I suggest marking the alias properties with @deprecated("Superseded by .part_$attribute", category=None)
for an initial period of 5 years, until all supported Python versions have the new attributes, and then after that with @deprecated("Superseded by .part_$attribute")
to give a runtime warning for another 5 years before the existing attributes can be finally scheduled for removal.
Marking the attributes with the non-warning @deprecated()
decorator initially will allow IDEs and type checker to yield diagnoses for usages of the attributes, encouraging users to migrate to the newly proposed ones, well ahead of time of their planned removal.
Edit: and also linters can be given functionality for giving diagnoses during this initial period.
I believe this will make Python friendlier to newcomers and long-timers alike, as this is a quirk that’s very easy to miss, a common issue, and not trivial to solve with something like linting, as the attributes also have legitimate uses.