[Python-Dev] Checking input range in time.asctime and time.ctime (original) (raw)

Alexander Belopolsky alexander.belopolsky at gmail.com
Thu Jan 6 05:48:38 CET 2011


On Wed, Jan 5, 2011 at 10:50 PM, Guido van Rossum <guido at python.org> wrote: ..

I propose to change that to

if y < 1000:_  _if accept2dyear:_  _if 69 <= y <= 99:_  _y += 1900_  _elif 0 <= y <= 68:_  _y += 2000_  _else:_  _raise ValueError("year out of range")_ _# call system function with tmyear = y - 1900_ _The new logic doesn't look right, am I right that this is what you meant?_ _if accept2dyear and 0 <= y < 100:_  _(convert to year >= 1970) if y < 1000:  raise ...

Not quite. My proposed logic would not do any range checking if accept2dyear == 0.

But what guarantees do we have that the system functions accept negative values for tmyear on all relevant platforms?

I've already committed an implementation of asctime, so time.asctime and time.ctime don't call system functions anymore. This leaves time.mktime and time.strftime. The latter caused Tim Peters to limit year range to >= 1900 eight years ago:

http://svn.python.org/view?view=rev&revision=30224

For these functions, range checks are necessary only when system functions may crash on out of range values. If we can detect error return and convert it to an exception, there is no need to look before you leap. (Note that asctime was different because the relevant standards specifically allowed it to have undefined behavior for out of range values.)

I cannot rule out that there are systems out there with buggy strftime, but the situation has improved in the last eight years and we have buildbots and unittests to check behavior on relevant platforms. If we do find a platform with buggy strftime which crashes or produces nonsense with negative tm_year, we can add a platform specific range check to work around platform bug, or just ask users to bug their OS vendor. :-)

The 1000 limit still seems pretty arbitrary to me -- if it's only because you don't want to decide whether to use leading spaces or zeros for numbers shorter than 4 digits, let me propose leading zeros since we use those uniformly for months, days, hours, minutes and seconds < 10,

Except we don't:

time.asctime((2000, 1, 1, 0, 0, 0, 0, 0, -1)) 'Sat Jan 1 00:00:00 2000'

(note that day is space-filled.)

I am not sure, however, what you are proposing here. Are you arguing for a wider or a narrower year range? I would be happy with just

if accept2dyear: if 69 <= y <= 99: y += 1900 elif 0 <= y <= 68: y += 2000

call system function with tm_year = y - 1900

but I thought that would be too radical.



More information about the Python-Dev mailing list