[pypy-commit] pypy cpyext-datetime2: move datetime type typedefs into parse, try to add a make_typedescr (for tzinfo)

mattip pypy.commits at gmail.com
Mon Jan 15 11:52:29 EST 2018


Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-datetime2
Changeset: r93675:4b6249f566e2
Date: 2018-01-15 18:51 +0200
http://bitbucket.org/pypy/pypy/changeset/4b6249f566e2/

Log:	move datetime type typedefs into parse, try to add a make_typedescr
	(for tzinfo)

diff --git a/pypy/module/cpyext/cdatetime.py b/pypy/module/cpyext/cdatetime.py
--- a/pypy/module/cpyext/cdatetime.py
+++ b/pypy/module/cpyext/cdatetime.py
@@ -1,40 +1,17 @@
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rtyper.annlowlevel import llhelper
-from pypy.module.cpyext.pyobject import PyObject, make_ref
+from pypy.module.cpyext.pyobject import PyObject, make_ref, make_typedescr
 from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, cpython_struct,
-    PyObjectFields)
+    PyObjectFields, cts, parse_dir, bootstrap_function, slot_function)
 from pypy.module.cpyext.import_ import PyImport_Import
 from pypy.module.cpyext.typeobject import PyTypeObjectPtr
 from pypy.interpreter.error import OperationError
 from rpython.tool.sourcetools import func_renamer
 
-# API import function
+cts.parse_header(parse_dir / 'cpyext_datetime.h')
 
-PyDateTime_CAPI = cpython_struct(
-    'PyDateTime_CAPI',
-    (('DateType', PyTypeObjectPtr),
-     ('DateTimeType', PyTypeObjectPtr),
-     ('TimeType', PyTypeObjectPtr),
-     ('DeltaType', PyTypeObjectPtr),
-     ('TZInfoType', PyTypeObjectPtr),
 
-     ('Date_FromDate', lltype.Ptr(lltype.FuncType(
-         [rffi.INT_real, rffi.INT_real, rffi.INT_real, PyTypeObjectPtr],
-         PyObject))),
-     ('Time_FromTime', lltype.Ptr(lltype.FuncType(
-         [rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
-          PyObject, PyTypeObjectPtr],
-         PyObject))),
-     ('DateTime_FromDateAndTime', lltype.Ptr(lltype.FuncType(
-         [rffi.INT_real, rffi.INT_real, rffi.INT_real,
-          rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
-          PyObject, PyTypeObjectPtr],
-         PyObject))),
-     ('Delta_FromDelta', lltype.Ptr(lltype.FuncType(
-         [rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
-          PyTypeObjectPtr],
-         PyObject))),
-     ))
+PyDateTime_CAPI = cts.gettype('PyDateTime_CAPI')
 
 @cpython_api([], lltype.Ptr(PyDateTime_CAPI))
 def _PyDateTime_Import(space):
@@ -78,19 +55,9 @@
 
     return datetimeAPI
 
-PyDateTime_DateStruct = lltype.ForwardReference()
-PyDateTime_TimeStruct = lltype.ForwardReference()
-PyDateTime_DateTimeStruct = lltype.ForwardReference()
-cpython_struct("PyDateTime_Date", PyObjectFields, PyDateTime_DateStruct)
-PyDateTime_Date = lltype.Ptr(PyDateTime_DateStruct)
-cpython_struct("PyDateTime_Time", PyObjectFields, PyDateTime_TimeStruct)
-PyDateTime_Time = lltype.Ptr(PyDateTime_TimeStruct)
-cpython_struct("PyDateTime_DateTime", PyObjectFields, PyDateTime_DateTimeStruct)
-PyDateTime_DateTime = lltype.Ptr(PyDateTime_DateTimeStruct)
-
-PyDeltaObjectStruct = lltype.ForwardReference()
-cpython_struct("PyDateTime_Delta", PyObjectFields, PyDeltaObjectStruct)
-PyDateTime_Delta = lltype.Ptr(PyDeltaObjectStruct)
+PyDateTime_Time = cts.gettype('PyDateTime_Time*')
+PyDateTime_DateTime = cts.gettype('PyDateTime_DateTime*')
+PyDateTime_Delta = cts.gettype('PyDateTime_Delta*')
 
 # Check functions
 
@@ -129,6 +96,66 @@
 PyTZInfo_Check, PyTZInfo_CheckExact = make_check_function(
     "PyTZInfo_Check", "tzinfo")
 
+ at bootstrap_function
+def init_datetime(space):
+    w_datetime = PyImport_Import(space, space.newtext("datetime"))
+
+    w_datetimetype = space.getattr(w_datetime, space.newtext("datetime"))
+    w_timetype = space.getattr(w_datetime, space.newtext("time"))
+    w_timedeltatype = space.getattr(w_datetime, space.newtext("timedelta"))
+    
+    # XXX doesn't work, the w_datetimetype, w_timetype, w_timedeltatype all
+    #     share the object layout.typedef so the typedescr specialization fails
+    return
+    # no realize functions since there are no getters
+    make_typedescr(w_datetimetype.layout.typedef,
+                   basestruct=PyDateTime_DateTime.TO,
+                   attach=type_attach,
+                   dealloc=type_dealloc,
+                  )
+
+    make_typedescr(w_timetype.layout.typedef,
+                   basestruct=PyDateTime_Time.TO,
+                   attach=type_attach,
+                   dealloc=type_dealloc,
+                  )
+
+    make_typedescr(w_timedeltatype.layout.typedef,
+                   basestruct=PyDateTime_Delta.TO,
+                   attach=timedeltatype_attach,
+                  )
+
+def type_attach(space, py_obj, w_obj, w_userdata=None):
+    "Fills a newly allocated py_obj from the w_obj"
+    import pdb;pdb.set_trace()
+    py_datetime = rffi.cast(PyDateTime_Time, py_obj)
+    w_tzinfo = space.getattr(w_obj, space.wrap('tzinfo'))
+    if space.is_none(w_tzinfo):
+        py_datetime.c_hastzinfo = 0
+        py_datetime.c_tzinfo = lltype.nullptr(PyObject.TO)
+    else:
+        py_datetime.c_hastzinfo = 1
+        py_datetime.c_tzinfo = make_ref(w_tzinfo)
+
+ at slot_function([PyObject], lltype.Void)
+def type_dealloc(space, py_obj):
+    import pdb;pdb.set_trace()
+    py_datetime = rffi.cast(PyDateTime_Time, py_obj)
+    if (py_datetime.hastzinfo):
+        decref(space, py_datetime.c_tzinfo)
+    from pypy.module.cpyext.object import _dealloc
+    _dealloc(space, py_obj)
+    
+def timedeltatype_attach(space, py_obj, w_obj, w_userdata=None):
+    "Fills a newly allocated py_obj from the w_obj"
+    py_delta = rffi.cast(PyDateTime_Delta, py_obj)
+    days = space.int_w(space.getattr(w_obj, space.newtext('days')))
+    py_delta.c_days = days
+    seconds = space.int_w(space.getattr(w_obj, space.newtext('seconds')))
+    py_delta.c_seconds = seconds
+    microseconds = space.int_w(space.getattr(w_obj, space.newtext('microseconds')))
+    py_delta.c_microseconds = microseconds
+
 # Constructors. They are better used as macros.
 
 @cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, PyTypeObjectPtr],
diff --git a/pypy/module/cpyext/include/datetime.h b/pypy/module/cpyext/include/datetime.h
--- a/pypy/module/cpyext/include/datetime.h
+++ b/pypy/module/cpyext/include/datetime.h
@@ -4,23 +4,7 @@
 extern "C" {
 #endif
 
-/* Define structure for C API. */
-typedef struct {
-    /* type objects */
-    PyTypeObject *DateType;
-    PyTypeObject *DateTimeType;
-    PyTypeObject *TimeType;
-    PyTypeObject *DeltaType;
-    PyTypeObject *TZInfoType;
-
-    /* constructors */
-    PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
-    PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
-        PyObject*, PyTypeObject*);
-    PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
-    PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
-} PyDateTime_CAPI;
-
+#include "cpyext_datetime.h"
 PyAPI_DATA(PyDateTime_CAPI*) PyDateTimeAPI;
 #define PyDateTime_IMPORT                           \
     do {                                            \
@@ -28,26 +12,6 @@
             PyDateTimeAPI = _PyDateTime_Import();   \
     } while (0)
 
-typedef struct {
-    PyObject_HEAD
-} PyDateTime_Delta;
-
-typedef struct {
-    PyObject_HEAD
-} PyDateTime_Date;
-
-typedef struct {
-    PyObject_HEAD
-} PyDateTime_Time;
-
-typedef struct {
-    PyObject_HEAD
-} PyDateTime_DateTime;
-
-typedef struct {
-    PyObject_HEAD
-} PyDateTime_TZInfo;
-
 /* Macros for accessing constructors in a simplified fashion. */
 #define PyDate_FromDate(year, month, day) \
     PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
diff --git a/pypy/module/cpyext/parse/cpyext_datetime.h b/pypy/module/cpyext/parse/cpyext_datetime.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/parse/cpyext_datetime.h
@@ -0,0 +1,47 @@
+/* Define structure for C API. */
+typedef struct {
+    /* type objects */
+    PyTypeObject *DateType;
+    PyTypeObject *DateTimeType;
+    PyTypeObject *TimeType;
+    PyTypeObject *DeltaType;
+    PyTypeObject *TZInfoType;
+
+    /* constructors */
+    PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
+    PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
+        PyObject*, PyTypeObject*);
+    PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
+    PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
+} PyDateTime_CAPI;
+
+typedef struct
+{
+    PyObject_HEAD
+    int days;                   /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */
+    int seconds;                /* 0 <= seconds < 24*3600 is invariant */
+    int microseconds;           /* 0 <= microseconds < 1000000 is invariant */
+} PyDateTime_Delta;
+
+/* The datetime and time types have an optional tzinfo member,
+ * PyNone if hastzinfo is false.
+ */
+typedef struct
+{
+    PyObject_HEAD
+    char hastzinfo;
+    PyObject *tzinfo;
+} PyDateTime_Time;
+
+typedef struct
+{
+    PyObject_HEAD
+    char hastzinfo;
+    PyObject *tzinfo;
+} PyDateTime_DateTime;
+
+
+typedef struct {
+    PyObject_HEAD
+} PyDateTime_Date;
+


More information about the pypy-commit mailing list