Commit 338af286 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Basic datetime support

parent f250404f
......@@ -290,7 +290,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS)
STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o
STDLIB_RELEASE_OBJS := stdlib.release.bc.o
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c $(EXTRA_STDMODULE_SRCS)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
......
......@@ -15,7 +15,7 @@ endforeach(STDLIB_FILE)
add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
# compile specified files in from_cpython/Modules
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c)
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c)
# compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c)
......
// This file is originally from CPython 2.7, with modifications for Pyston
/* datetime.h
*/
#ifndef DATETIME_H
#define DATETIME_H
#ifdef __cplusplus
extern "C" {
#endif
/* Fields are packed into successive bytes, each viewed as unsigned and
* big-endian, unless otherwise noted:
*
* byte offset
* 0 year 2 bytes, 1-9999
* 2 month 1 byte, 1-12
* 3 day 1 byte, 1-31
* 4 hour 1 byte, 0-23
* 5 minute 1 byte, 0-59
* 6 second 1 byte, 0-59
* 7 usecond 3 bytes, 0-999999
* 10
*/
/* # of bytes for year, month, and day. */
#define _PyDateTime_DATE_DATASIZE 4
/* # of bytes for hour, minute, second, and usecond. */
#define _PyDateTime_TIME_DATASIZE 6
/* # of bytes for year, month, day, hour, minute, second, and usecond. */
#define _PyDateTime_DATETIME_DATASIZE 10
typedef struct
{
PyObject_HEAD
long hashcode; /* -1 when unknown */
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;
typedef struct
{
PyObject_HEAD /* a pure abstract base class */
} PyDateTime_TZInfo;
/* The datetime and time types have hashcodes, and an optional tzinfo member,
* present if and only if hastzinfo is true.
*/
#define _PyTZINFO_HEAD \
PyObject_HEAD \
long hashcode; \
char hastzinfo; /* boolean flag */
/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
* convenient to cast to, when getting at the hastzinfo member of objects
* starting with _PyTZINFO_HEAD.
*/
typedef struct
{
_PyTZINFO_HEAD
} _PyDateTime_BaseTZInfo;
/* All time objects are of PyDateTime_TimeType, but that can be allocated
* in two ways, with or without a tzinfo member. Without is the same as
* tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an
* internal struct used to allocate the right amount of space for the
* "without" case.
*/
#define _PyDateTime_TIMEHEAD \
_PyTZINFO_HEAD \
unsigned char data[_PyDateTime_TIME_DATASIZE];
typedef struct
{
_PyDateTime_TIMEHEAD
} _PyDateTime_BaseTime; /* hastzinfo false */
typedef struct
{
_PyDateTime_TIMEHEAD
PyObject *tzinfo;
} PyDateTime_Time; /* hastzinfo true */
/* All datetime objects are of PyDateTime_DateTimeType, but that can be
* allocated in two ways too, just like for time objects above. In addition,
* the plain date type is a base class for datetime, so it must also have
* a hastzinfo member (although it's unused there).
*/
typedef struct
{
_PyTZINFO_HEAD
unsigned char data[_PyDateTime_DATE_DATASIZE];
} PyDateTime_Date;
#define _PyDateTime_DATETIMEHEAD \
_PyTZINFO_HEAD \
unsigned char data[_PyDateTime_DATETIME_DATASIZE];
typedef struct
{
_PyDateTime_DATETIMEHEAD
} _PyDateTime_BaseDateTime; /* hastzinfo false */
typedef struct
{
_PyDateTime_DATETIMEHEAD
PyObject *tzinfo;
} PyDateTime_DateTime; /* hastzinfo true */
/* Apply for date and datetime instances. */
#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \
((PyDateTime_Date*)o)->data[1])
#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2])
#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3])
#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4])
#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5])
#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6])
#define PyDateTime_DATE_GET_MICROSECOND(o) \
((((PyDateTime_DateTime*)o)->data[7] << 16) | \
(((PyDateTime_DateTime*)o)->data[8] << 8) | \
((PyDateTime_DateTime*)o)->data[9])
/* Apply for time instances. */
#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0])
#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1])
#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2])
#define PyDateTime_TIME_GET_MICROSECOND(o) \
((((PyDateTime_Time*)o)->data[3] << 16) | \
(((PyDateTime_Time*)o)->data[4] << 8) | \
((PyDateTime_Time*)o)->data[5])
/* 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*);
/* constructors for the DB API */
PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
} PyDateTime_CAPI;
#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI"
/* "magic" constant used to partially protect against developer mistakes. */
#define DATETIME_API_MAGIC 0x414548d5
#ifdef Py_BUILD_CORE
/* Macros for type checking when building the Python core. */
#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType)
#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType)
#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType)
#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType)
#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType)
#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType)
#else
/* Define global variable for the C API and a macro for setting it. */
static PyDateTime_CAPI *PyDateTimeAPI = NULL;
#define PyDateTime_IMPORT \
PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0)
/* Macros for type checking when not building the Python core. */
#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType)
#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType)
#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType)
#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType)
#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType)
/* Macros for accessing constructors in a simplified fashion. */
#define PyDate_FromDate(year, month, day) \
PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
#define PyTime_FromTime(hour, minute, second, usecond) \
PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
Py_None, PyDateTimeAPI->TimeType)
#define PyDelta_FromDSU(days, seconds, useconds) \
PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \
PyDateTimeAPI->DeltaType)
/* Macros supporting the DB API. */
#define PyDateTime_FromTimestamp(args) \
PyDateTimeAPI->DateTime_FromTimestamp( \
(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
#define PyDate_FromTimestamp(args) \
PyDateTimeAPI->Date_FromTimestamp( \
(PyObject*) (PyDateTimeAPI->DateType), args)
#endif /* Py_BUILD_CORE */
#ifdef __cplusplus
}
#endif
#endif
......@@ -38,7 +38,7 @@ PyAPI_DATA(PyTypeObject*) int_cls;
// Pyston changes: these aren't direct macros any more [they potentially could be though]
PyAPI_FUNC(bool) _PyInt_Check(PyObject*) PYSTON_NOEXCEPT;
#define PyInt_Check(op) _PyInt_Check((PyObject*)op)
#define PyInt_Check(op) _PyInt_Check((PyObject*)(op))
#if 0
#define PyInt_Check(op) \
PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_INT_SUBCLASS)
......
......@@ -66,7 +66,7 @@ PyAPI_DATA(PyTypeObject*) str_cls;
// Pyston changes: these aren't direct macros any more [they potentially could be though]
PyAPI_FUNC(bool) _PyString_Check(PyObject*) PYSTON_NOEXCEPT;
#define PyString_Check(op) _PyString_Check((PyObject*)op)
#define PyString_Check(op) _PyString_Check((PyObject*)(op))
#if 0
#define PyString_Check(op) \
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_STRING_SUBCLASS)
......
// This file is originally from CPython 2.7, with modifications for Pyston
/* timefuncs.h
*/
/* Utility function related to timemodule.c. */
#ifndef TIMEFUNCS_H
#define TIMEFUNCS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Cast double x to time_t, but raise ValueError if x is too large
* to fit in a time_t. ValueError is set on return iff the return
* value is (time_t)-1 and PyErr_Occurred().
*/
PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x) PYSTON_NOEXCEPT;
/* Get the current time since the epoch in seconds */
PyAPI_FUNC(double) _PyTime_FloatTime(void) PYSTON_NOEXCEPT;
#ifdef __cplusplus
}
#endif
#endif /* TIMEFUNCS_H */
......@@ -353,4 +353,8 @@ extern "C" int PyObject_IsSubclass(PyObject* derived, PyObject* cls) noexcept {
}
return recursive_issubclass(derived, cls);
}
extern "C" PyObject* _PyObject_CallFunction_SizeT(PyObject* callable, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
}
......@@ -123,4 +123,9 @@ extern "C" int PyObject_RichCompareBool(PyObject* v, PyObject* w, int op) noexce
Py_DECREF(res);
return ok;
}
// I'm not sure how we can support this one:
extern "C" PyObject** _PyObject_GetDictPtr(PyObject* obj) noexcept {
Py_FatalError("unimplemented");
}
}
......@@ -79,6 +79,32 @@ RICHCMP_WRAPPER(ne, Py_NE)
RICHCMP_WRAPPER(gt, Py_GT)
RICHCMP_WRAPPER(ge, Py_GE)
static PyObject* wrap_coercefunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
coercion func = (coercion)wrapped;
PyObject* other, *res;
int ok;
if (!check_num_args(args, 1))
return NULL;
other = PyTuple_GET_ITEM(args, 0);
ok = func(&self, &other);
if (ok < 0)
return NULL;
if (ok > 0) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
res = PyTuple_New(2);
if (res == NULL) {
Py_DECREF(self);
Py_DECREF(other);
return NULL;
}
PyTuple_SET_ITEM(res, 0, self);
PyTuple_SET_ITEM(res, 1, other);
return res;
}
static PyObject* wrap_ternaryfunc(PyObject* self, PyObject* args, void* wrapped) noexcept {
ternaryfunc func = (ternaryfunc)wrapped;
PyObject* other;
......@@ -853,6 +879,12 @@ static int slot_nb_nonzero(PyObject* self) noexcept {
return result;
}
static PyObject* slot_nb_index(PyObject* self) noexcept {
static PyObject* index_str;
return call_method(self, "__index__", &index_str, "()");
}
SLOT0(slot_nb_invert, "__invert__")
SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
SLOT1BIN(slot_nb_rshift, nb_rshift, "__rshift__", "__rrshift__")
......@@ -860,13 +892,82 @@ SLOT1BIN(slot_nb_and, nb_and, "__and__", "__rand__")
SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__")
SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")
static int slot_nb_coerce(PyObject** a, PyObject** b) noexcept;
static int slot_nb_coerce(PyObject** a, PyObject** b) noexcept {
static PyObject* coerce_str;
PyObject* self = *a, * other = *b;
if (self->cls->tp_as_number != NULL && self->cls->tp_as_number->nb_coerce == slot_nb_coerce) {
PyObject* r;
r = call_maybe(self, "__coerce__", &coerce_str, "(O)", other);
if (r == NULL)
return -1;
if (r == Py_NotImplemented) {
Py_DECREF(r);
} else {
if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
PyErr_SetString(PyExc_TypeError, "__coerce__ didn't return a 2-tuple");
Py_DECREF(r);
return -1;
}
*a = PyTuple_GET_ITEM(r, 0);
Py_INCREF(*a);
*b = PyTuple_GET_ITEM(r, 1);
Py_INCREF(*b);
Py_DECREF(r);
return 0;
}
}
if (other->cls->tp_as_number != NULL && other->cls->tp_as_number->nb_coerce == slot_nb_coerce) {
PyObject* r;
r = call_maybe(other, "__coerce__", &coerce_str, "(O)", self);
if (r == NULL)
return -1;
if (r == Py_NotImplemented) {
Py_DECREF(r);
return 1;
}
if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
PyErr_SetString(PyExc_TypeError, "__coerce__ didn't return a 2-tuple");
Py_DECREF(r);
return -1;
}
*a = PyTuple_GET_ITEM(r, 1);
Py_INCREF(*a);
*b = PyTuple_GET_ITEM(r, 0);
Py_INCREF(*b);
Py_DECREF(r);
return 0;
}
return 1;
}
SLOT0(slot_nb_int, "__int__")
SLOT0(slot_nb_long, "__long__")
SLOT0(slot_nb_float, "__float__")
SLOT0(slot_nb_oct, "__oct__")
SLOT0(slot_nb_hex, "__hex__")
SLOT1(slot_nb_inplace_add, "__iadd__", PyObject*, "O")
SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject*, "O")
SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject*, "O")
SLOT1(slot_nb_inplace_divide, "__idiv__", PyObject*, "O")
SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject*, "O")
/* Can't use SLOT1 here, because nb_inplace_power is ternary */
static PyObject* slot_nb_inplace_power(PyObject* self, PyObject* arg1, PyObject* arg2) {
static PyObject* cache_str;
return call_method(self, "__ipow__", &cache_str, "("
"O"
")",
arg1);
}
SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject*, "O")
SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject*, "O")
SLOT1(slot_nb_inplace_and, "__iand__", PyObject*, "O")
SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject*, "O")
SLOT1(slot_nb_inplace_or, "__ior__", PyObject*, "O")
SLOT1BIN(slot_nb_floor_divide, nb_floor_divide, "__floordiv__", "__rfloordiv__")
SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__")
SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject*, "O")
SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject*, "O")
typedef wrapper_def slotdef;
......@@ -937,40 +1038,59 @@ static slotdef slotdefs[]
PyWrapperFlag_KEYWORDS),
TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""),
BINSLOT("__add__", nb_add, slot_nb_add, "+"), // [force clang-format to line break]
RBINSLOT("__radd__", nb_add, slot_nb_add, "+"), //
BINSLOT("__sub__", nb_subtract, slot_nb_subtract, "-"), //
RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, "-"), //
BINSLOT("__mul__", nb_multiply, slot_nb_multiply, "*"), //
RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, "*"), //
BINSLOT("__div__", nb_divide, slot_nb_divide, "/"), //
RBINSLOT("__rdiv__", nb_divide, slot_nb_divide, "/"), //
BINSLOT("__mod__", nb_remainder, slot_nb_remainder, "%"), //
RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, "%"), //
BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, "divmod(x, y)"),
RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, "divmod(y, x)"),
NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, "x.__pow__(y[, z]) <==> pow(x, y[, z])"),
NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, "y.__rpow__(x[, z]) <==> pow(x, y[, z])"),
UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), //
UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), //
UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(x)"), //
UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred, "x != 0"), //
UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), //
BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), //
RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), //
BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), //
RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), //
BINSLOT("__and__", nb_and, slot_nb_and, "&"), //
RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), //
BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), //
RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), //
BINSLOT("__or__", nb_or, slot_nb_or, "|"), //
RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), //
UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, "int(x)"), //
UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc, "long(x)"), //
UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, "float(x)"), //
UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, "oct(x)"), //
UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, "hex(x)"), //
BINSLOT("__add__", nb_add, slot_nb_add, "+"), // [force clang-format to line break]
RBINSLOT("__radd__", nb_add, slot_nb_add, "+"), //
BINSLOT("__sub__", nb_subtract, slot_nb_subtract, "-"), //
RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, "-"), //
BINSLOT("__mul__", nb_multiply, slot_nb_multiply, "*"), //
RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, "*"), //
BINSLOT("__div__", nb_divide, slot_nb_divide, "/"), //
RBINSLOT("__rdiv__", nb_divide, slot_nb_divide, "/"), //
BINSLOT("__mod__", nb_remainder, slot_nb_remainder, "%"), //
RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, "%"), //
BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, "divmod(x, y)"), //
RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, "divmod(y, x)"), //
NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, "x.__pow__(y[, z]) <==> pow(x, y[, z])"), //
NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, "y.__rpow__(x[, z]) <==> pow(x, y[, z])"), //
UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), //
UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), //
UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(x)"), //
UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred, "x != 0"), //
UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), //
BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), //
RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), //
BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), //
RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), //
BINSLOT("__and__", nb_and, slot_nb_and, "&"), //
RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), //
BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), //
RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), //
BINSLOT("__or__", nb_or, slot_nb_or, "|"), //
RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), //
NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc, "x.__coerce__(y) <==> coerce(x, y)"), //
UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, "int(x)"), //
UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc, "long(x)"), //
UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, "float(x)"), //
UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, "oct(x)"), //
UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, "hex(x)"), //
IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), //
IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, wrap_binaryfunc, "-="), //
IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, wrap_binaryfunc, "*="), //
IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide, wrap_binaryfunc, "/="), //
IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, wrap_binaryfunc, "%="), //
IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, wrap_binaryfunc, "**="), //
IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, wrap_binaryfunc, "<<="), //
IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, wrap_binaryfunc, ">>="), //
IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, wrap_binaryfunc, "&="), //
IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, wrap_binaryfunc, "^="), //
IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, wrap_binaryfunc, "|="), //
BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), //
RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), //
BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), //
RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), //
IBSLOT("__ifloordiv__", nb_inplace_floor_divide, slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"), //
IBSLOT("__itruediv__", nb_inplace_true_divide, slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), //
NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, "x[y:z] <==> x[y.__index__():z.__index__()]"), //
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, "x.__len__() <==> len(x)"),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, wrap_binaryfunc, "x.__getitem__(y) <==> x[y]"),
......@@ -1563,28 +1683,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
RELEASE_ASSERT(cls->tp_setattr == NULL, "");
RELEASE_ASSERT(cls->tp_compare == NULL, "");
if (cls->tp_as_number) {
auto num = cls->tp_as_number;
// Members not added yet:
assert(num->nb_coerce == NULL);
assert(num->nb_inplace_add == NULL);
assert(num->nb_inplace_subtract == NULL);
assert(num->nb_inplace_multiply == NULL);
assert(num->nb_inplace_divide == NULL);
assert(num->nb_inplace_remainder == NULL);
assert(num->nb_inplace_power == NULL);
assert(num->nb_inplace_lshift == NULL);
assert(num->nb_inplace_rshift == NULL);
assert(num->nb_inplace_and == NULL);
assert(num->nb_inplace_xor == NULL);
assert(num->nb_inplace_or == NULL);
assert(num->nb_floor_divide == NULL);
assert(num->nb_true_divide == NULL);
assert(num->nb_inplace_floor_divide == NULL);
assert(num->nb_inplace_true_divide == NULL);
assert(num->nb_index == NULL);
}
RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
RELEASE_ASSERT(cls->tp_setattro == NULL || cls->tp_setattro == PyObject_GenericSetAttr, "");
RELEASE_ASSERT(cls->tp_as_buffer == NULL, "");
......@@ -1623,6 +1721,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
base = cls->tp_base = object_cls;
if (!cls->cls)
cls->cls = cls->tp_base->cls;
cls->giveAttr("__base__", base);
assert(cls->tp_dict == NULL);
cls->tp_dict = makeAttrWrapper(cls);
......@@ -1672,4 +1771,8 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
return 0;
}
extern "C" PyObject* PyType_GenericNew(PyTypeObject* type, PyObject* args, PyObject* kwds) noexcept {
return type->tp_alloc(type, 0);
}
} // namespace pyston
......@@ -26,6 +26,29 @@ namespace pyston {
BoxedModule* time_module;
/* Exposed in timefuncs.h. */
extern "C" time_t _PyTime_DoubleToTimet(double x) noexcept {
time_t result;
double diff;
result = (time_t)x;
/* How much info did we lose? time_t may be an integral or
* floating type, and we don't know which. If it's integral,
* we don't know whether C truncates, rounds, returns the floor,
* etc. If we lost a second or more, the C rounding is
* unreasonable, or the input just doesn't fit in a time_t;
* call it an error regardless. Note that the original cast to
* time_t can cause a C error too, but nothing we can do to
* worm around that.
*/
diff = x - (double)result;
if (diff <= -1.0 || diff >= 1.0) {
PyErr_SetString(PyExc_ValueError, "timestamp out of range for platform time_t");
result = (time_t)-1;
}
return result;
}
Box* timeTime() {
struct timeval now;
gettimeofday(&now, NULL);
......
......@@ -144,7 +144,9 @@ extern "C" PyAPI_FUNC(PyObject*) _PyLong_Format(PyObject* aa, int base, int addL
}
extern "C" PyObject* PyLong_FromDouble(double v) noexcept {
Py_FatalError("unimplemented");
BoxedLong* rtn = new BoxedLong();
mpz_init_set_d(rtn->n, v);
return rtn;
}
extern "C" PyObject* PyLong_FromLong(long ival) noexcept {
......
......@@ -1716,7 +1716,12 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
return 0;
}
static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, const void** ptr) {
extern "C" void PyString_ConcatAndDel(register PyObject** pv, register PyObject* w) noexcept {
Py_FatalError("unimplemented");
}
static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, const void** ptr) noexcept {
RELEASE_ASSERT(index == 0, "");
// I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type
......@@ -1727,7 +1732,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
return s->s.size();
}
static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) {
static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexcept {
RELEASE_ASSERT(lenp == NULL, "");
RELEASE_ASSERT(o->cls == str_cls, "");
......
......@@ -48,6 +48,7 @@ extern "C" void initbinascii();
extern "C" void initpwd();
extern "C" void initposix();
extern "C" void init_struct();
extern "C" void initdatetime();
namespace pyston {
......@@ -1137,6 +1138,7 @@ void setupRuntime() {
initpwd();
initposix();
init_struct();
initdatetime();
setupSysEnd();
......
# Simple datetime test
# Doesn't test much of the functionality, but even importing the module is tough:
import datetime
print repr(datetime.time())
print datetime.datetime.__base__
print repr(datetime.datetime(1, 2, 3))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment