Considering the difference between aware and naive datetime objects and that by default without specifying the tzinfo argument all datetime objects are “naive”, we’re in a bit of a pickle if we want to require aware datetime objects only and if we can’t control all creations of datetime objects (because third-party packages return them).
The proper way would be to subclass stdlib’s
datetime class but that doesn’t ensure that all datetime objects are aware.
We could try and monkey patch the stdlib and hijack the
datetime.__new__() function but that’s a built-in:
<built-in method __new__ of type object at 0x101ac3b88>
can't set attributes of built-in/extension type 'datetime.datetime'. More interesting conversation here.
I think the ideal solution would be a way to “configure” the
datetime class such that the
tzinfo’s default argument could be changed, e.g. from
timezone.utc. Short of such a feature, what do folks here suggest to work with this pickle?
This seems like an XY problem. Naïve datetime objects have their uses (in fact, there’s not a better way to represent system local times) and trying to globally make it impossible to construct them would almost certainly be a bad idea.
If you want your interface to require aware datetimes, you should probably add some enforcement mechanism into the relevant functions or constructors that must take aware datetimes.
Another option would be to create a subclass of
datetime.datetime that does not allow
tzinfo. If you use static typing, you can annotate your functions to require this subclass.
It’s probably worth noting that this is not a good thing to do unless people are actually intending to represent a datetime in UTC when they create their
datetime.datetime objects. It’s kind of like saying, “Well we want all numbers to have units, so we will make the default units meters for all numbers.” If someone is using numbers to mean miles or seconds or kilometers or parsecs, you have just made the situation more confusing, not less.