[Alexander Belopolsky email@example.com]
I think we can change the behavior datetime.__add__ and datetime.__sub__ if we do it based on the type of the object attached as tzinfo. For example, if we introduce a new abstract subclass of the tzinfo class called say "tzstrict", then we can be sure that there is no tzinfo implementation in the wild that inherits from tzstrict (we fully control the datetime module namespace.) Now, we can make datetime.__add__ and __sub__ check the type of the tzinfo member on its argument(s) and apply the new rules if one of them is an instance of tzstrict.
It's a happy idea :-)
With these changes in place, users who want new aware datetime arithmetic will use timezone implementations that inherit from tzstrict and legacy applications can continue using existing timezone libraries. And we can spend the next decade arguing what kind of timezone implementation belongs to the standard library. :-)
Or fixing all the bugs in the recommended way to write tzstrict instances ;-)
Speaking of which, the current tzinfo API has no way to ask "is this an ambiguous time?" or "is this an invalid (missing) time?" The most important new question callers will want to resolve is "what should `first` (aka is_dst) be now?". The only (at best indirectly) relevant things we can ask it now are "what's the total UTC offset at the local-time instant I represent?", and likewise "what's the DST adjustment component of the total UTC offset at (etc)?:" And there's no way at all now to ask (not even indirectly) whether the standard UTC offset has changed.
So it's unclear to me how arithmetic (or anything else) can use the current tzinfo API efficiently to set the `first` (aka is_dst) flag correctly in all cases. Perhaps tzstrict could grow a helpful new method or two to make this easy for callers? The logic is bound to be annoying enough that we'd want to concentrate it in tzstrict (rather then replicate it all over call sites).
But no concrete suggestions from me at this time.