[pygobject/gsoc2009: 81/160] Add time_t marshalling



commit 35b5a7661312f3739d98a442b84a8bca2f4e3849
Author: Simon van der Linden <svdlinden src gnome org>
Date:   Thu Jul 30 12:29:04 2009 +0200

    Add time_t marshalling

 gi/gimodule.c              |    1 +
 gi/pygargument.c           |   54 +++++++++++++++++++++++++++++++++++++++-----
 gi/pygargument.h           |    2 +
 tests/test_girepository.py |   38 ++++++++++--------------------
 4 files changed, 64 insertions(+), 31 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 63f8e9f..56910cb 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -130,5 +130,6 @@ init_gi(void)
 
     pygi_repository_register_types(m);
     pygi_info_register_types(m);
+    pyg_argument_init();
 }
 
diff --git a/gi/pygargument.c b/gi/pygargument.c
index 3c607be..a3fa020 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -24,6 +24,9 @@
 #include "pygi-private.h"
 
 #include <string.h>
+#include <time.h>
+
+#include <datetime.h>
 #include <pygobject.h>
 
 gint
@@ -252,8 +255,12 @@ check_number_release:
             break;
         }
         case GI_TYPE_TAG_TIME_T:
-            /* TODO */
-            g_assert_not_reached();
+            if (!PyDateTime_Check(object)) {
+                PyErr_Format(PyExc_TypeError, "Must be datetime.datetime, not %s",
+                        object->ob_type->tp_name);
+                retval = 0;
+                break;
+            }
             break;
         case GI_TYPE_TAG_GTYPE:
         {
@@ -683,9 +690,33 @@ pygi_g_argument_from_py_object(PyObject *object, GITypeInfo *type_info, GITransf
             break;
         }
         case GI_TYPE_TAG_TIME_T:
-            /* TODO */
-            g_assert_not_reached();
+        {
+            PyDateTime_DateTime *py_datetime;
+            struct tm datetime;
+            time_t time_;
+
+            py_datetime = (PyDateTime_DateTime *)object;
+
+            if (py_datetime->hastzinfo) {
+                PyErr_WarnEx(NULL, "tzinfo ignored; only local time is supported", 1);
+            }
+
+            datetime.tm_sec = PyDateTime_DATE_GET_SECOND(py_datetime);
+            datetime.tm_min = PyDateTime_DATE_GET_MINUTE(py_datetime);
+            datetime.tm_hour = PyDateTime_DATE_GET_HOUR(py_datetime);
+            datetime.tm_mday = PyDateTime_GET_DAY(py_datetime);
+            datetime.tm_mon = PyDateTime_GET_MONTH(py_datetime) - 1;
+            datetime.tm_year = PyDateTime_GET_YEAR(py_datetime) - 1900;
+            datetime.tm_isdst = -1;
+
+            time_ = mktime(&datetime);
+            if (time_ == -1) {
+                PyErr_SetString(PyExc_RuntimeError, "datetime conversion failed");
+            }
+
+            arg.v_long = time_;
             break;
+        }
         case GI_TYPE_TAG_GTYPE:
         {
             GType type;
@@ -1149,9 +1180,14 @@ pygi_g_argument_to_py_object(GArgument *arg, GITypeInfo *type_info)
             object = PyFloat_FromDouble(arg->v_double);
             break;
         case GI_TYPE_TAG_TIME_T:
-            /* TODO */
-            g_assert_not_reached();
+        {
+            struct tm *datetime;
+            datetime = localtime(&arg->v_long);
+            object = PyDateTime_FromDateAndTime(datetime->tm_year + 1900,
+                datetime->tm_mon + 1, datetime->tm_mday, datetime->tm_hour,
+                datetime->tm_min, datetime->tm_sec, 0);
             break;
+        }
         case GI_TYPE_TAG_GTYPE:
             object = pyg_type_wrapper_new(arg->v_long);
             break;
@@ -1624,3 +1660,9 @@ pygi_g_argument_release(GArgument *arg, GITypeInfo *type_info, GITransfer transf
     }
 }
 
+void
+pyg_argument_init(void)
+{
+    PyDateTime_IMPORT;
+}
+
diff --git a/gi/pygargument.h b/gi/pygargument.h
index 1c42861..7a7591b 100644
--- a/gi/pygargument.h
+++ b/gi/pygargument.h
@@ -50,6 +50,8 @@ void pygi_g_argument_release(GArgument *arg,
                              GITransfer transfer,
                              GIDirection direction);
 
+void pyg_argument_init(void);
+
 G_END_DECLS
 
 #endif /* __PYG_ARGUMENT_H__ */
diff --git a/tests/test_girepository.py b/tests/test_girepository.py
index 1693b89..edcb44e 100644
--- a/tests/test_girepository.py
+++ b/tests/test_girepository.py
@@ -2,8 +2,8 @@
 # vim: tabstop=4 shiftwidth=4 expandtab
 
 import unittest
+from datetime import datetime
 
-import time
 import gobject
 from gobject import constants
 
@@ -223,30 +223,18 @@ class TestGIEverything(unittest.TestCase):
         self.assertAlmostEqual(-3.14, Everything.test_double(-3.14))
         self.assertRaises(TypeError, Everything.test_double, 'a')
 
-# FIXME
-#======================================================================
-#ERROR: testTimeT (__main__.TestGIEverything)
-#----------------------------------------------------------------------
-#Traceback (most recent call last):
-#  File "test_girepository.py", line 193, in testTimeT
-#    bounced = Everything.test_timet(now)
-#  File "/opt/gnome-introspection/lib64/python2.5/site-packages/gtk-2.0/girepository/btypes.py", line 124, in __call__
-#    self.type_check(name, value, argType)
-#  File "/opt/gnome-introspection/lib64/python2.5/site-packages/gtk-2.0/girepository/btypes.py", line 97, in type_check
-#    raise NotImplementedError('type checking for tag %d' % tag)
-#NotImplementedError: type checking for tag 18
-#    def testTimeT(self):
-#        now = time.time()
-#        bounced = Everything.test_timet(now)
-#        self.assertEquals(now.tm_year, bounced.tm_year)
-#        self.assertEquals(now.tm_year, bounced.tm_mon)
-#        self.assertEquals(now.tm_year, bounced.tm_mday)
-#        self.assertEquals(now.tm_year, bounced.tm_hour)
-#        self.assertEquals(now.tm_year, bounced.tm_min)
-#        self.assertEquals(now.tm_year, bounced.tm_sec)
-#        self.assertEquals(now.tm_year, bounced.tm_wday)
-#        self.assertEquals(now.tm_year, bounced.tm_yday)
-#        self.assertEquals(now.tm_year, bounced.tm_isdst)
+    def testTimeT(self):
+        now = datetime.now()
+        retval = Everything.test_timet(now)
+
+        # We can't do a direct comparison because we lost the microseconds precision.
+        self.assertEquals(retval.year, now.year)
+        self.assertEquals(retval.month, now.month)
+        self.assertEquals(retval.day, now.day)
+        self.assertEquals(retval.hour, now.hour)
+        self.assertEquals(retval.minute, now.minute)
+        self.assertEquals(retval.second, now.second)
+        self.assertEquals(retval.tzinfo, now.tzinfo)
 
     def testGType(self):
         self.assertEqual(gobject.TYPE_INT, Everything.test_gtype(gobject.TYPE_INT))



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]