[Datetime-SIG] Version check (was Re: PEP 495: What's left to resolve)

Alexander Belopolsky alexander.belopolsky at gmail.com
Tue Sep 8 19:38:11 CEST 2015

On Tue, Sep 8, 2015 at 12:41 PM, Tim Peters <tim.peters at gmail.com> wrote:

> [Alex]
> > ...
> > Once you decide to use a post-PEP tzinfo, you have no choice but to test
> > your software on the edge cases if you care about them.
> Which reminds me:  the PEP should add a way for a post-495 tzinfo to
> say it supplies post-495 semantics, so users can check whether they're
> getting a tzinfo they require (if they need fold disambiguation) or
> can't tolerate (if they need folds to be ignored for legacy reasons).

We may end up providing something like this, but I hope developing this
mechanism can be left to the tzinfo implementers.  (Which can as well be
us, but in another PEP.)  I am not sure a tzinfo object will need a
persistent attribute rather than just a way to require specific
capabilities at the construction time.  For example, a hypothetical
zoneinfo() constructor or a factory function can take a "fold_aware"
boolean argument and let the user specify what kind of tzinfo is
requested.  It will then become a QOI issue of whether zoneinfo() supports
both pre- and post-PEP semantics or not.

Note that zoneinfo() providers may end up extending  the tzinfo API to
include queries such as give me all folds between year A and year B.

The downside of a persistent run-time attribute that differentiate between
pre-PEP and post-PEP tzinfos is that it may promote writing code that tries
to cope with the presence of pre-PEP and post-PEP tzinfos in the same
program.   This is a recipe for a combinatorial disaster.  Note that on top
of pre-PEP/post-PEP distinction a good tzinfo() library will probably also
supply a TZ database version.  Imagine writing a simple "within(t, start,
stop)" function that should account for the tree arguments possibly having
different    "fold_aware" attribute and different tzversion?

> It's not a change to the tzinfo API, but is a change to tzinfo semantics.
> I guess requiring a new `__version__ = 2` attribute would be OK.

I generally dislike "version" constants or attributes.  My preferred
solution would be to provide a generic PEP 495 compliant fromutc() in a
tzinfo subclass and ask PEP 495 compliant implementations to derive from

> Or (preferably "and") add an optional `fold=None` argument to
> .utcoffset()  (by default, use the datetime's .fold attribute, else
> use the passed value).

I thought about this as an optimization.  dt.utcoffset(fold=1) being an
equivalent of dt.replace(fold=1).utcoffset() which avoids copying of the
entire dt object into a temporary.  I think this is a minor issue.  I can
go either way on this.

>   Then an obscure form of version-checking could
> be done by seeing whether dt.utcoffset(fold=1) blows up.

I would not add dt.utcoffset(fold=x) just for that and if we end up adding
it for other reasons will probably consider such use a hack.

>   That's a
> poor way to spell "check the version", but would at least allow
> checking to see what would happen if `fold` changed without the
> expense of creating new short-lived datetime objects.

Yes, this is a good reason and since calling utcoffset() both ways will be
typical for "careful" applications, I don't mind giving them some syntactic
sugar for that.

Yet again, this is not a "live or die" issue for PEP 495.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/datetime-sig/attachments/20150908/5a979570/attachment.html>

More information about the Datetime-SIG mailing list