[Python-checkins] r87776 - in python/branches/py3k: Lib/test/test_time.py Modules/timemodule.c

alexander.belopolsky python-checkins at python.org
Thu Jan 6 00:00:47 CET 2011


Author: alexander.belopolsky
Date: Thu Jan  6 00:00:47 2011
New Revision: 87776

Log:
- time.accept2dyear = True is now equivalent to time.accept2dyear = 1
- removed unnecessary struct_time to tuple conversion
- added more unit tests
(See issue #10827 for discussion.)


Modified:
   python/branches/py3k/Lib/test/test_time.py
   python/branches/py3k/Modules/timemodule.c

Modified: python/branches/py3k/Lib/test/test_time.py
==============================================================================
--- python/branches/py3k/Lib/test/test_time.py	(original)
+++ python/branches/py3k/Lib/test/test_time.py	Thu Jan  6 00:00:47 2011
@@ -263,8 +263,48 @@
         # This should not cause an exception
         time.strftime("%B", (2009,2,1,0,0,0,0,0,0))
 
+class TestAccept2Year(unittest.TestCase):
+    accept2dyear = 1
+    def setUp(self):
+        self.saved_accept2dyear = time.accept2dyear
+        time.accept2dyear = self.accept2dyear
+
+    def tearDown(self):
+        time.accept2dyear = self.saved_accept2dyear
+
+    def yearstr(self, y):
+        return time.strftime('%Y', (y,) + (0,) * 8)
+
+    def test_2dyear(self):
+        self.assertEqual(self.yearstr(0), '2000')
+        self.assertEqual(self.yearstr(69), '1969')
+        self.assertEqual(self.yearstr(68), '2068')
+        self.assertEqual(self.yearstr(99), '1999')
+
+    def test_invalid(self):
+        self.assertRaises(ValueError, self.yearstr, 1899)
+        self.assertRaises(ValueError, self.yearstr, 100)
+        self.assertRaises(ValueError, self.yearstr, -1)
+
+class TestAccept2YearBool(TestAccept2Year):
+    accept2dyear = True
+
+class TestDontAccept2Year(TestAccept2Year):
+    accept2dyear = 0
+    def test_2dyear(self):
+        self.assertRaises(ValueError, self.yearstr, 0)
+        self.assertRaises(ValueError, self.yearstr, 69)
+        self.assertRaises(ValueError, self.yearstr, 68)
+        self.assertRaises(ValueError, self.yearstr, 99)
+
+class TestDontAccept2YearBool(TestDontAccept2Year):
+    accept2dyear = False
+
+
 def test_main():
-    support.run_unittest(TimeTestCase, TestLocale)
+    support.run_unittest(TimeTestCase, TestLocale,
+                         TestAccept2Year, TestAccept2YearBool,
+                         TestDontAccept2Year, TestDontAccept2YearBool)
 
 if __name__ == "__main__":
     test_main()

Modified: python/branches/py3k/Modules/timemodule.c
==============================================================================
--- python/branches/py3k/Modules/timemodule.c	(original)
+++ python/branches/py3k/Modules/timemodule.c	Thu Jan  6 00:00:47 2011
@@ -217,29 +217,6 @@
 }
 
 static PyObject *
-structtime_totuple(PyObject *t)
-{
-    PyObject *x = NULL;
-    unsigned int i;
-    PyObject *v = PyTuple_New(9);
-    if (v == NULL)
-        return NULL;
-
-    for (i=0; i<9; i++) {
-        x = PyStructSequence_GET_ITEM(t, i);
-        Py_INCREF(x);
-        PyTuple_SET_ITEM(v, i, x);
-    }
-
-    if (PyErr_Occurred()) {
-        Py_XDECREF(v);
-        return NULL;
-    }
-
-    return v;
-}
-
-static PyObject *
 time_convert(double when, struct tm * (*function)(const time_t *))
 {
     struct tm *p;
@@ -328,9 +305,6 @@
         t = args;
         Py_INCREF(t);
     }
-    else if (Py_TYPE(args) == &StructTimeType) {
-        t = structtime_totuple(args);
-    }
     else {
         PyErr_SetString(PyExc_TypeError,
                         "Tuple or struct_time argument required");
@@ -352,19 +326,30 @@
     }
     Py_DECREF(t);
 
+    /* XXX: Why 1900?  If the goal is to interpret 2-digit years as those in
+     * 20th / 21st century according to the POSIX standard, we can just treat
+     * 0 <= y < 100 as special.  Year 100 is probably too ambiguous and should
+     * be rejected, but years 101 through 1899 can be passed through.
+     */
     if (y < 1900) {
         PyObject *accept = PyDict_GetItemString(moddict,
                                                 "accept2dyear");
-        if (accept == NULL || !PyLong_CheckExact(accept) ||
-            !PyObject_IsTrue(accept)) {
-            PyErr_SetString(PyExc_ValueError,
-                            "year >= 1900 required");
+        int acceptval = accept != NULL && PyObject_IsTrue(accept);
+        if (acceptval == -1)
             return 0;
+        if (acceptval) {
+            if (69 <= y && y <= 99)
+                y += 1900;
+            else if (0 <= y && y <= 68)
+                y += 2000;
+            else {
+                PyErr_SetString(PyExc_ValueError,
+                                "year out of range");
+                return 0;
+            }
         }
-        if (69 <= y && y <= 99)
-            y += 1900;
-        else if (0 <= y && y <= 68)
-            y += 2000;
+        /* XXX: When accept2dyear is false, we don't have to reject y < 1900.
+         * Consider removing the following else-clause. */
         else {
             PyErr_SetString(PyExc_ValueError,
                             "year out of range");


More information about the Python-checkins mailing list