allow ctime(), gmtime(), and localtime() to take None as equivalent to an omitted arg

(closes SF bug #658254, patch #663482)
This commit is contained in:
Fred Drake 2004-08-03 17:58:55 +00:00
parent d04573fef0
commit f901abdd62
4 changed files with 69 additions and 17 deletions

View File

@ -157,11 +157,14 @@ The resolution is typically better than one microsecond.
\begin{funcdesc}{ctime}{\optional{secs}}
Convert a time expressed in seconds since the epoch to a string
representing local time. If \var{secs} is not provided, the current time
as returned by \function{time()} is used. \code{ctime(\var{secs})}
is equivalent to \code{asctime(localtime(\var{secs}))}.
representing local time. If \var{secs} is not provided or
\constant{None}, the current time as returned by \function{time()} is
used. \code{ctime(\var{secs})} is equivalent to
\code{asctime(localtime(\var{secs}))}.
Locale information is not used by \function{ctime()}.
\versionchanged[Allowed \var{secs} to be omitted]{2.1}
\versionchanged[If \var{secs} is \constant{None}, the current time is
used]{2.3}
\end{funcdesc}
\begin{datadesc}{daylight}
@ -171,16 +174,22 @@ Nonzero if a DST timezone is defined.
\begin{funcdesc}{gmtime}{\optional{secs}}
Convert a time expressed in seconds since the epoch to a \class{struct_time}
in UTC in which the dst flag is always zero. If \var{secs} is not
provided, the current time as returned by \function{time()} is used.
Fractions of a second are ignored. See above for a description of the
\class{struct_time} object.
provided or \constant{None}, the current time as returned by
\function{time()} is used. Fractions of a second are ignored. See
above for a description of the \class{struct_time} object.
\versionchanged[Allowed \var{secs} to be omitted]{2.1}
\versionchanged[If \var{secs} is \constant{None}, the current time is
used]{2.3}
\end{funcdesc}
\begin{funcdesc}{localtime}{\optional{secs}}
Like \function{gmtime()} but converts to local time. The dst flag is
set to \code{1} when DST applies to the given time.
Like \function{gmtime()} but converts to local time. If \var{secs} is
not provided or \constant{None}, the current time as returned by
\function{time()} is used. The dst flag is set to \code{1} when DST
applies to the given time.
\versionchanged[Allowed \var{secs} to be omitted]{2.1}
\versionchanged[If \var{secs} is \constant{None}, the current time is
used]{2.3}
\end{funcdesc}
\begin{funcdesc}{mktime}{t}

View File

@ -185,6 +185,23 @@ class TimeTestCase(unittest.TestCase):
for unreasonable in -1e200, 1e200:
self.assertRaises(ValueError, func, unreasonable)
def test_ctime_without_arg(self):
# Not sure how to check the values, since the clock could tick
# at any time. Make sure these are at least accepted and
# don't raise errors.
time.ctime()
time.ctime(None)
def test_gmtime_without_arg(self):
t0 = time.mktime(time.gmtime())
t1 = time.mktime(time.gmtime(None))
self.assert_(0 <= (t1-t0) < 0.2)
def test_localtime_without_arg(self):
t0 = time.mktime(time.localtime())
t1 = time.mktime(time.localtime(None))
self.assert_(0 <= (t1-t0) < 0.2)
def test_main():
test_support.run_unittest(TimeTestCase)

View File

@ -72,6 +72,11 @@ Extension modules
Library
-------
- The following methods in time support passing of None: ctime(), gmtime(),
and localtime(). If None is provided, the current time is used (the
same as when the argument is omitted).
[SF bug 658254, patch 663482]
- nntplib does now allow to ignore a .netrc file.
- urllib2 now recognizes Basic authentication even if other authentication

View File

@ -277,13 +277,33 @@ time_convert(double when, struct tm * (*function)(const time_t *))
return tmtotuple(p);
}
/* Parse arg tuple that can contain an optional float-or-None value;
format needs to be "|O:name".
Returns non-zero on success (parallels PyArg_ParseTuple).
*/
static int
parse_time_double_args(PyObject *args, char *format, double *pwhen)
{
PyObject *ot = NULL;
if (!PyArg_ParseTuple(args, format, &ot))
return 0;
if (ot == NULL || ot == Py_None)
*pwhen = floattime();
else {
double when = PyFloat_AsDouble(ot);
if (PyErr_Occurred())
return 0;
*pwhen = when;
}
return 1;
}
static PyObject *
time_gmtime(PyObject *self, PyObject *args)
{
double when;
if (PyTuple_Size(args) == 0)
when = floattime();
if (!PyArg_ParseTuple(args, "|d:gmtime", &when))
if (!parse_time_double_args(args, "|O:gmtime", &when))
return NULL;
return time_convert(when, gmtime);
}
@ -299,9 +319,7 @@ static PyObject *
time_localtime(PyObject *self, PyObject *args)
{
double when;
if (PyTuple_Size(args) == 0)
when = floattime();
if (!PyArg_ParseTuple(args, "|d:localtime", &when))
if (!parse_time_double_args(args, "|O:localtime", &when))
return NULL;
return time_convert(when, localtime);
}
@ -502,14 +520,17 @@ is used.");
static PyObject *
time_ctime(PyObject *self, PyObject *args)
{
double dt;
PyObject *ot = NULL;
time_t tt;
char *p;
if (PyTuple_Size(args) == 0)
if (!PyArg_ParseTuple(args, "|O:ctime", &ot))
return NULL;
if (ot == NULL || ot == Py_None)
tt = time(NULL);
else {
if (!PyArg_ParseTuple(args, "|d:ctime", &dt))
double dt = PyFloat_AsDouble(ot);
if (PyErr_Occurred())
return NULL;
tt = _PyTime_DoubleToTimet(dt);
if (tt == (time_t)-1 && PyErr_Occurred())