PageRenderTime 45ms CodeModel.GetById 2ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 1ms

/pypy/module/cpyext/cdatetime.py

https://bitbucket.org/pypy/pypy/
Python | 296 lines | 278 code | 16 blank | 2 comment | 0 complexity | b152ebe5f33a076a371d7bf75fc81f5e MD5 | raw file
  1from rpython.rtyper.lltypesystem import rffi, lltype
  2from rpython.rtyper.annlowlevel import llhelper
  3from pypy.module.cpyext.pyobject import PyObject, make_ref
  4from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, cpython_struct,
  5    PyObjectFields)
  6from pypy.module.cpyext.import_ import PyImport_Import
  7from pypy.module.cpyext.typeobject import PyTypeObjectPtr
  8from pypy.interpreter.error import OperationError
  9from rpython.tool.sourcetools import func_renamer
 10
 11# API import function
 12
 13PyDateTime_CAPI = cpython_struct(
 14    'PyDateTime_CAPI',
 15    (('DateType', PyTypeObjectPtr),
 16     ('DateTimeType', PyTypeObjectPtr),
 17     ('TimeType', PyTypeObjectPtr),
 18     ('DeltaType', PyTypeObjectPtr),
 19     ('TZInfoType', PyTypeObjectPtr),
 20
 21     ('Date_FromDate', lltype.Ptr(lltype.FuncType(
 22         [rffi.INT_real, rffi.INT_real, rffi.INT_real, PyTypeObjectPtr],
 23         PyObject))),
 24     ('Time_FromTime', lltype.Ptr(lltype.FuncType(
 25         [rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
 26          PyObject, PyTypeObjectPtr],
 27         PyObject))),
 28     ('DateTime_FromDateAndTime', lltype.Ptr(lltype.FuncType(
 29         [rffi.INT_real, rffi.INT_real, rffi.INT_real,
 30          rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
 31          PyObject, PyTypeObjectPtr],
 32         PyObject))),
 33     ('Delta_FromDelta', lltype.Ptr(lltype.FuncType(
 34         [rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
 35          PyTypeObjectPtr],
 36         PyObject))),
 37     ))
 38
 39@cpython_api([], lltype.Ptr(PyDateTime_CAPI))
 40def _PyDateTime_Import(space):
 41    datetimeAPI = lltype.malloc(PyDateTime_CAPI, flavor='raw',
 42                                track_allocation=False)
 43
 44    w_datetime = PyImport_Import(space, space.wrap("datetime"))
 45
 46    w_type = space.getattr(w_datetime, space.wrap("date"))
 47    datetimeAPI.c_DateType = rffi.cast(
 48        PyTypeObjectPtr, make_ref(space, w_type))
 49
 50    w_type = space.getattr(w_datetime, space.wrap("datetime"))
 51    datetimeAPI.c_DateTimeType = rffi.cast(
 52        PyTypeObjectPtr, make_ref(space, w_type))
 53
 54    w_type = space.getattr(w_datetime, space.wrap("time"))
 55    datetimeAPI.c_TimeType = rffi.cast(
 56        PyTypeObjectPtr, make_ref(space, w_type))
 57
 58    w_type = space.getattr(w_datetime, space.wrap("timedelta"))
 59    datetimeAPI.c_DeltaType = rffi.cast(
 60        PyTypeObjectPtr, make_ref(space, w_type))
 61
 62    w_type = space.getattr(w_datetime, space.wrap("tzinfo"))
 63    datetimeAPI.c_TZInfoType = rffi.cast(
 64        PyTypeObjectPtr, make_ref(space, w_type))
 65
 66    datetimeAPI.c_Date_FromDate = llhelper(
 67        _PyDate_FromDate.api_func.functype,
 68        _PyDate_FromDate.api_func.get_wrapper(space))
 69    datetimeAPI.c_Time_FromTime = llhelper(
 70        _PyTime_FromTime.api_func.functype,
 71        _PyTime_FromTime.api_func.get_wrapper(space))
 72    datetimeAPI.c_DateTime_FromDateAndTime = llhelper(
 73        _PyDateTime_FromDateAndTime.api_func.functype,
 74        _PyDateTime_FromDateAndTime.api_func.get_wrapper(space))
 75    datetimeAPI.c_Delta_FromDelta = llhelper(
 76        _PyDelta_FromDelta.api_func.functype,
 77        _PyDelta_FromDelta.api_func.get_wrapper(space))
 78
 79    return datetimeAPI
 80
 81PyDateTime_DateStruct = lltype.ForwardReference()
 82PyDateTime_TimeStruct = lltype.ForwardReference()
 83PyDateTime_DateTimeStruct = lltype.ForwardReference()
 84cpython_struct("PyDateTime_Date", PyObjectFields, PyDateTime_DateStruct)
 85PyDateTime_Date = lltype.Ptr(PyDateTime_DateStruct)
 86cpython_struct("PyDateTime_Time", PyObjectFields, PyDateTime_TimeStruct)
 87PyDateTime_Time = lltype.Ptr(PyDateTime_TimeStruct)
 88cpython_struct("PyDateTime_DateTime", PyObjectFields, PyDateTime_DateTimeStruct)
 89PyDateTime_DateTime = lltype.Ptr(PyDateTime_DateTimeStruct)
 90
 91PyDeltaObjectStruct = lltype.ForwardReference()
 92cpython_struct("PyDateTime_Delta", PyObjectFields, PyDeltaObjectStruct)
 93PyDateTime_Delta = lltype.Ptr(PyDeltaObjectStruct)
 94
 95# Check functions
 96
 97def make_check_function(func_name, type_name):
 98    @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
 99    @func_renamer(func_name)
100    def check(space, w_obj):
101        try:
102            return space.is_true(
103                space.appexec([w_obj], """(obj):
104                    from datetime import %s as datatype
105                    return isinstance(obj, datatype)
106                    """ % (type_name,)))
107        except OperationError:
108            return 0
109
110    @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
111    @func_renamer(func_name + "Exact")
112    def check_exact(space, w_obj):
113        try:
114            return space.is_true(
115                space.appexec([w_obj], """(obj):
116                    from datetime import %s as datatype
117                    return type(obj) is datatype
118                    """ % (type_name,)))
119        except OperationError:
120            return 0
121
122make_check_function("PyDateTime_Check", "datetime")
123make_check_function("PyDate_Check", "date")
124make_check_function("PyTime_Check", "time")
125make_check_function("PyDelta_Check", "timedelta")
126make_check_function("PyTZInfo_Check", "tzinfo")
127
128# Constructors. They are better used as macros.
129
130@cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, PyTypeObjectPtr],
131             PyObject)
132def _PyDate_FromDate(space, year, month, day, w_type):
133    """Return a datetime.date object with the specified year, month and day.
134    """
135    year = rffi.cast(lltype.Signed, year)
136    month = rffi.cast(lltype.Signed, month)
137    day = rffi.cast(lltype.Signed, day)
138    return space.call_function(
139        w_type,
140        space.wrap(year), space.wrap(month), space.wrap(day))
141
142@cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
143              PyObject, PyTypeObjectPtr], PyObject)
144def _PyTime_FromTime(space, hour, minute, second, usecond, w_tzinfo, w_type):
145    """Return a ``datetime.time`` object with the specified hour, minute, second and
146    microsecond."""
147    hour = rffi.cast(lltype.Signed, hour)
148    minute = rffi.cast(lltype.Signed, minute)
149    second = rffi.cast(lltype.Signed, second)
150    usecond = rffi.cast(lltype.Signed, usecond)
151    return space.call_function(
152        w_type,
153        space.wrap(hour), space.wrap(minute), space.wrap(second),
154        space.wrap(usecond), w_tzinfo)
155
156@cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real,
157              rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
158              PyObject, PyTypeObjectPtr], PyObject)
159def _PyDateTime_FromDateAndTime(space, year, month, day,
160                                hour, minute, second, usecond,
161                                w_tzinfo, w_type):
162    """Return a datetime.datetime object with the specified year, month, day, hour,
163    minute, second and microsecond.
164    """
165    year = rffi.cast(lltype.Signed, year)
166    month = rffi.cast(lltype.Signed, month)
167    day = rffi.cast(lltype.Signed, day)
168    hour = rffi.cast(lltype.Signed, hour)
169    minute = rffi.cast(lltype.Signed, minute)
170    second = rffi.cast(lltype.Signed, second)
171    usecond = rffi.cast(lltype.Signed, usecond)
172    return space.call_function(
173        w_type,
174        space.wrap(year), space.wrap(month), space.wrap(day),
175        space.wrap(hour), space.wrap(minute), space.wrap(second),
176        space.wrap(usecond), w_tzinfo)
177
178@cpython_api([PyObject], PyObject)
179def PyDateTime_FromTimestamp(space, w_args):
180    """Create and return a new datetime.datetime object given an argument tuple
181    suitable for passing to datetime.datetime.fromtimestamp().
182    """
183    w_datetime = PyImport_Import(space, space.wrap("datetime"))
184    w_type = space.getattr(w_datetime, space.wrap("datetime"))
185    w_method = space.getattr(w_type, space.wrap("fromtimestamp"))
186    return space.call(w_method, w_args)
187
188@cpython_api([PyObject], PyObject)
189def PyDate_FromTimestamp(space, w_args):
190    """Create and return a new datetime.date object given an argument tuple
191    suitable for passing to datetime.date.fromtimestamp().
192    """
193    w_datetime = PyImport_Import(space, space.wrap("datetime"))
194    w_type = space.getattr(w_datetime, space.wrap("date"))
195    w_method = space.getattr(w_type, space.wrap("fromtimestamp"))
196    return space.call(w_method, w_args)
197
198@cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real,
199              PyTypeObjectPtr],
200             PyObject)
201def _PyDelta_FromDelta(space, days, seconds, useconds, normalize, w_type):
202    """Return a datetime.timedelta object representing the given number of days,
203    seconds and microseconds.  Normalization is performed so that the resulting
204    number of microseconds and seconds lie in the ranges documented for
205    datetime.timedelta objects.
206    """
207    days = rffi.cast(lltype.Signed, days)
208    seconds = rffi.cast(lltype.Signed, seconds)
209    useconds = rffi.cast(lltype.Signed, useconds)
210    return space.call_function(
211        w_type,
212        space.wrap(days), space.wrap(seconds), space.wrap(useconds))
213
214# Accessors
215
216@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
217def PyDateTime_GET_YEAR(space, w_obj):
218    """Return the year, as a positive int.
219    """
220    return space.int_w(space.getattr(w_obj, space.wrap("year")))
221
222@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
223def PyDateTime_GET_MONTH(space, w_obj):
224    """Return the month, as an int from 1 through 12.
225    """
226    return space.int_w(space.getattr(w_obj, space.wrap("month")))
227
228@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
229def PyDateTime_GET_DAY(space, w_obj):
230    """Return the day, as an int from 1 through 31.
231    """
232    return space.int_w(space.getattr(w_obj, space.wrap("day")))
233
234@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
235def PyDateTime_DATE_GET_HOUR(space, w_obj):
236    """Return the hour, as an int from 0 through 23.
237    """
238    return space.int_w(space.getattr(w_obj, space.wrap("hour")))
239
240@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
241def PyDateTime_DATE_GET_MINUTE(space, w_obj):
242    """Return the minute, as an int from 0 through 59.
243    """
244    return space.int_w(space.getattr(w_obj, space.wrap("minute")))
245
246@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
247def PyDateTime_DATE_GET_SECOND(space, w_obj):
248    """Return the second, as an int from 0 through 59.
249    """
250    return space.int_w(space.getattr(w_obj, space.wrap("second")))
251
252@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
253def PyDateTime_DATE_GET_MICROSECOND(space, w_obj):
254    """Return the microsecond, as an int from 0 through 999999.
255    """
256    return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
257
258@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
259def PyDateTime_TIME_GET_HOUR(space, w_obj):
260    """Return the hour, as an int from 0 through 23.
261    """
262    return space.int_w(space.getattr(w_obj, space.wrap("hour")))
263
264@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
265def PyDateTime_TIME_GET_MINUTE(space, w_obj):
266    """Return the minute, as an int from 0 through 59.
267    """
268    return space.int_w(space.getattr(w_obj, space.wrap("minute")))
269
270@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
271def PyDateTime_TIME_GET_SECOND(space, w_obj):
272    """Return the second, as an int from 0 through 59.
273    """
274    return space.int_w(space.getattr(w_obj, space.wrap("second")))
275
276@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
277def PyDateTime_TIME_GET_MICROSECOND(space, w_obj):
278    """Return the microsecond, as an int from 0 through 999999.
279    """
280    return space.int_w(space.getattr(w_obj, space.wrap("microsecond")))
281
282# XXX these functions are not present in the Python API
283# But it does not seem possible to expose a different structure
284# for types defined in a python module like lib/datetime.py.
285
286@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
287def PyDateTime_DELTA_GET_DAYS(space, w_obj):
288    return space.int_w(space.getattr(w_obj, space.wrap("days")))
289
290@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
291def PyDateTime_DELTA_GET_SECONDS(space, w_obj):
292    return space.int_w(space.getattr(w_obj, space.wrap("seconds")))
293
294@cpython_api([rffi.VOIDP], rffi.INT_real, error=CANNOT_FAIL)
295def PyDateTime_DELTA_GET_MICROSECONDS(space, w_obj):
296    return space.int_w(space.getattr(w_obj, space.wrap("microseconds")))