[Python-Dev] PEP: New timestamp formats (original) (raw)

Paul Moore p.f.moore at gmail.com
Thu Feb 2 11:53:49 CET 2012


On 2 February 2012 03:47, Nick Coghlan <ncoghlan at gmail.com> wrote:

Rather than being timestamp specific, such a protocol would be a general numeric protocol. If (integer, numerator, denominator) is used (i.e. a "mixed number" in mathematical terms), then "frommixed" would be an appropriate name. If (integer, fractional, exponent) is used (i.e. a fixed point notation), then "fromfixed" would work.

 # Algorithm for a "from mixed numbers" protocol, assuming division doesn't lose precision...  def frommixed(cls, integer, numerator, denominator):  return cls(integer) + cls(numerator) / cls(denominator)  # Algorithm for a "from fixed point" protocol, assuming negative exponents don't lose precision...  def fromfixed(cls, integer, mantissa, base, exponent):  return cls(integer) + cls(mantissa) * cls(base) ** cls(exponent) >From a usage point of view, this idea is actually the same as the proposal currently in the PEP. The difference is that instead of adding custom support for a few particular types directly to time and os, it instead defines a more general purpose protocol that covers not only this use case, but also any other situation where high precision fractions are relevant. One interesting question with a named protocol approach is whether such a protocol should require explicit support, or if it should fall back to the underlying mathematical operations. Since the conversions to float and int in the timestamp case are already known to be lossy, permitting lossy conversion via the mathematical equivalents seems reasonable, suggesting possible protocol definitions as follows:  # Algorithm for a potentially precision-losing "from mixed numbers" protocol  def frommixed(cls, integer, numerator, denominator):  try:  factory = cls.frommixed  except AttributeError:  return cls(integer) + cls(numerator) / cls(denominator)  return factory(integer, numerator, denominator)  # Algorithm for a potentially lossy "from fixed point" protocol  def fromfixed(cls, integer, mantissa, base, exponent):  try:  factory = cls.fromfixed  except AttributeError:  return cls(integer) + cls(mantissa) * cls(base) ** cls(exponent)  return factory(integer, mantissa, base, exponent)

The key problem with a protocol is that the implementer has to make these decisions. The callback approach defers that decision to the end user. After all, the end user is the one who knows for his app whether precision loss is acceptable.

You could probably also have a standard named protocol which can be used as a callback in straightforward cases

time.time(callback=timedelta.__from_mixed__)

That's wordy, and a bit ugly, though. The callback code could special-case types and look for from_mixed, I guess. Or use an ABC, and have the code that uses the callback do

if issubclass(cb, MixedNumberABC):
    return cb.__from_mixed__(whole, num, den)
else:
    return cb(whole, num, den)

(The second branch is the one that allows the user to override the predefined types that work - if you omit that, you're back to a named protocol and ABCs don't gain you much beyond documentation).

Part of me feels that there's a use case for generic functions in here, but maybe not (as it's overloading on the return type). Let's not open that discussion again, though.

Paul.



More information about the Python-Dev mailing list