mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
...
This commit is contained in:
parent
a6adcfd0c1
commit
04229f438f
@ -172,7 +172,7 @@ py_i64 py_toint(py_Ref);
|
||||
/// Convert a `float` object in python to `double`.
|
||||
py_f64 py_tofloat(py_Ref);
|
||||
/// Cast a `int` or `float` object in python to `double`.
|
||||
/// If successful, returns true and set the value to `out`.
|
||||
/// If successful, return true and set the value to `out`.
|
||||
/// Otherwise, return false and raise `TypeError`.
|
||||
bool py_castfloat(py_Ref, py_f64* out) PY_RAISE;
|
||||
/// Convert a `bool` object in python to `bool`.
|
||||
@ -203,6 +203,9 @@ void* py_touserdata(py_Ref);
|
||||
|
||||
/// Get the type of the object.
|
||||
py_Type py_typeof(py_Ref self);
|
||||
/// Get type by module and name. e.g. `py_gettype("time", "struct_time")`.
|
||||
/// Return `0` if not found.
|
||||
py_Type py_gettype(const char* module, py_Name name);
|
||||
/// Check if the object is exactly the given type.
|
||||
bool py_istype(py_Ref, py_Type);
|
||||
/// Check if the object is an instance of the given type.
|
||||
|
@ -1,4 +1,5 @@
|
||||
from time import localtime
|
||||
import operator
|
||||
|
||||
class timedelta:
|
||||
def __init__(self, days=0, seconds=0):
|
||||
@ -13,25 +14,10 @@ class timedelta:
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) == (other.days, other.seconds)
|
||||
|
||||
def __lt__(self, other: 'timedelta') -> bool:
|
||||
def __ne__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) < (other.days, other.seconds)
|
||||
|
||||
def __le__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) <= (other.days, other.seconds)
|
||||
|
||||
def __gt__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) > (other.days, other.seconds)
|
||||
|
||||
def __ge__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) >= (other.days, other.seconds)
|
||||
return (self.days, self.seconds) != (other.days, other.seconds)
|
||||
|
||||
|
||||
class date:
|
||||
@ -44,31 +30,33 @@ class date:
|
||||
def today():
|
||||
t = localtime()
|
||||
return date(t.tm_year, t.tm_mon, t.tm_mday)
|
||||
|
||||
def __cmp(self, other, op):
|
||||
if not isinstance(other, date):
|
||||
return NotImplemented
|
||||
if self.year != other.year:
|
||||
return op(self.year, other.year)
|
||||
if self.month != other.month:
|
||||
return op(self.month, other.month)
|
||||
return op(self.day, other.day)
|
||||
|
||||
def __eq__(self, other: 'date') -> bool:
|
||||
if type(other) is not date:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day) == (other.year, other.month, other.day)
|
||||
return self.__cmp(other, operator.eq)
|
||||
|
||||
def __ne__(self, other: 'date') -> bool:
|
||||
return self.__cmp(other, operator.ne)
|
||||
|
||||
def __lt__(self, other: 'date') -> bool:
|
||||
if type(other) is not date:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day) < (other.year, other.month, other.day)
|
||||
return self.__cmp(other, operator.lt)
|
||||
|
||||
def __le__(self, other: 'date') -> bool:
|
||||
if type(other) is not date:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day) <= (other.year, other.month, other.day)
|
||||
return self.__cmp(other, operator.le)
|
||||
|
||||
def __gt__(self, other: 'date') -> bool:
|
||||
if type(other) is not date:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day) > (other.year, other.month, other.day)
|
||||
return self.__cmp(other, operator.gt)
|
||||
|
||||
def __ge__(self, other: 'date') -> bool:
|
||||
if type(other) is not date:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day) >= (other.year, other.month, other.day)
|
||||
return self.__cmp(other, operator.ge)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.year}-{self.month:02}-{self.day:02}"
|
||||
@ -108,41 +96,37 @@ class datetime(date):
|
||||
def __repr__(self):
|
||||
return f"datetime.datetime({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})"
|
||||
|
||||
def __cmp(self, other, op):
|
||||
if not isinstance(other, datetime):
|
||||
return NotImplemented
|
||||
if self.year != other.year:
|
||||
return op(self.year, other.year)
|
||||
if self.month != other.month:
|
||||
return op(self.month, other.month)
|
||||
if self.day != other.day:
|
||||
return op(self.day, other.day)
|
||||
if self.hour != other.hour:
|
||||
return op(self.hour, other.hour)
|
||||
if self.minute != other.minute:
|
||||
return op(self.minute, other.minute)
|
||||
return op(self.second, other.second)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if type(other) is not datetime:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day, self.hour, self.minute, self.second) ==\
|
||||
(other.year, other.month, other.day,
|
||||
other.hour, other.minute, other.second)
|
||||
|
||||
return self.__cmp(other, operator.eq)
|
||||
|
||||
def __ne__(self, other) -> bool:
|
||||
return self.__cmp(other, operator.ne)
|
||||
|
||||
def __lt__(self, other) -> bool:
|
||||
if type(other) is not datetime:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day, self.hour, self.minute, self.second) <\
|
||||
(other.year, other.month, other.day,
|
||||
other.hour, other.minute, other.second)
|
||||
|
||||
return self.__cmp(other, operator.lt)
|
||||
|
||||
def __le__(self, other) -> bool:
|
||||
if type(other) is not datetime:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day, self.hour, self.minute, self.second) <=\
|
||||
(other.year, other.month, other.day,
|
||||
other.hour, other.minute, other.second)
|
||||
|
||||
return self.__cmp(other, operator.le)
|
||||
|
||||
def __gt__(self, other) -> bool:
|
||||
if type(other) is not datetime:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day, self.hour, self.minute, self.second) >\
|
||||
(other.year, other.month, other.day,
|
||||
other.hour, other.minute, other.second)
|
||||
|
||||
return self.__cmp(other, operator.gt)
|
||||
|
||||
def __ge__(self, other) -> bool:
|
||||
if type(other) is not datetime:
|
||||
return NotImplemented
|
||||
return (self.year, self.month, self.day, self.hour, self.minute, self.second) >=\
|
||||
(other.year, other.month, other.day,
|
||||
other.hour, other.minute, other.second)
|
||||
return self.__cmp(other, operator.ge)
|
||||
|
||||
def timestamp(self) -> float:
|
||||
raise NotImplementedError
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -330,7 +330,9 @@ py_Type pk_newtype(const char* name,
|
||||
}
|
||||
|
||||
py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
|
||||
return pk_newtype(name, base, module, dtor, false, false);
|
||||
py_Type type = pk_newtype(name, base, module, dtor, false, false);
|
||||
if(module) py_setdict(module, py_name(name), py_tpobject(type));
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
#include "pocketpy/interpreter/vm.h"
|
||||
#include "time.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define NANOS_PER_SEC 1000000000
|
||||
|
||||
@ -51,10 +51,53 @@ static bool time_sleep(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool time_localtime(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(0);
|
||||
py_Type tp_struct_time = py_gettype("time", py_name("struct_time"));
|
||||
assert(tp_struct_time);
|
||||
struct tm* ud = py_newobject(py_retval(), tp_struct_time, 0, sizeof(struct tm));
|
||||
time_t t = time(NULL);
|
||||
*ud = *localtime(&t);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DEF_STRUCT_TIME__PROPERTY(name, expr) \
|
||||
static bool struct_time__##name(int argc, py_Ref argv) { \
|
||||
PY_CHECK_ARGC(1); \
|
||||
struct tm* tm = py_touserdata(argv); \
|
||||
py_newint(py_retval(), expr); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_year, tm->tm_year + 1900)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_mon, tm->tm_mon + 1)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_mday, tm->tm_mday)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_hour, tm->tm_hour)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_min, tm->tm_min)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_sec, tm->tm_sec)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_wday, (tm->tm_wday + 6) % 7)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_yday, tm->tm_yday + 1)
|
||||
DEF_STRUCT_TIME__PROPERTY(tm_isdst, tm->tm_isdst)
|
||||
|
||||
#undef DEF_STRUCT_TIME__PROPERTY
|
||||
|
||||
void pk__add_module_time() {
|
||||
py_Ref mod = py_newmodule("time");
|
||||
|
||||
py_Type tp_struct_time = py_newtype("struct_time", tp_object, mod, NULL);
|
||||
|
||||
py_bindproperty(tp_struct_time, "tm_year", struct_time__tm_year, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_mon", struct_time__tm_mon, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_mday", struct_time__tm_mday, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_hour", struct_time__tm_hour, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_min", struct_time__tm_min, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_sec", struct_time__tm_sec, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_wday", struct_time__tm_wday, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_yday", struct_time__tm_yday, NULL);
|
||||
py_bindproperty(tp_struct_time, "tm_isdst", struct_time__tm_isdst, NULL);
|
||||
|
||||
py_bindfunc(mod, "time", time_time);
|
||||
py_bindfunc(mod, "time_ns", time_time_ns);
|
||||
py_bindfunc(mod, "sleep", time_sleep);
|
||||
py_bindfunc(mod, "localtime", time_localtime);
|
||||
}
|
@ -57,4 +57,12 @@ bool py_issubclass(py_Type derived, py_Type base) {
|
||||
return false;
|
||||
}
|
||||
|
||||
py_Type py_typeof(py_Ref self) { return self->type; }
|
||||
py_Type py_typeof(py_Ref self) { return self->type; }
|
||||
|
||||
py_Type py_gettype(const char* module, py_Name name) {
|
||||
py_Ref mod = py_getmodule(module);
|
||||
if(!mod) return 0;
|
||||
py_Ref object = py_getdict(mod, name);
|
||||
if(object && py_istype(object, tp_type)) return py_totype(object);
|
||||
return 0;
|
||||
}
|
@ -4,11 +4,6 @@ import datetime
|
||||
def test_timedelta():
|
||||
assert datetime.timedelta(days=1) == datetime.timedelta(days=1)
|
||||
assert datetime.timedelta(days=1) != datetime.timedelta(days=2)
|
||||
assert datetime.timedelta(days=1, seconds=1) >= datetime.timedelta(days=1)
|
||||
assert datetime.timedelta(days=0, seconds=1) <= datetime.timedelta(days=1)
|
||||
assert datetime.timedelta(days=1, seconds=1) < datetime.timedelta(days=2)
|
||||
assert datetime.timedelta(days=1, seconds=1) > datetime.timedelta(days=0)
|
||||
|
||||
|
||||
def test_date():
|
||||
assert datetime.date(2023, 8, 5) == datetime.date(2023, 8, 5)
|
||||
@ -18,7 +13,6 @@ def test_date():
|
||||
assert datetime.date(2024, 8, 5) > datetime.date(2023, 8, 6)
|
||||
assert datetime.date(2023, 8, 5) < datetime.date(2024, 8, 6)
|
||||
|
||||
|
||||
def test_datetime():
|
||||
assert datetime.datetime(
|
||||
2023, 8, 5, 12, 0, 0) == datetime.datetime(2023, 8, 5, 12, 0, 0)
|
||||
@ -33,7 +27,6 @@ def test_datetime():
|
||||
assert datetime.datetime(
|
||||
2023, 8, 5, 12, 0, 0) <= datetime.datetime(2023, 8, 5, 12, 1, 0)
|
||||
|
||||
|
||||
test_timedelta()
|
||||
test_date()
|
||||
test_datetime()
|
||||
|
Loading…
x
Reference in New Issue
Block a user