mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-28 15:30:17 +00:00
Compare commits
7 Commits
11f709b768
...
e51f86c599
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e51f86c599 | ||
|
|
7263550fc1 | ||
|
|
f1c969fe76 | ||
|
|
f73ebd1f62 | ||
|
|
ec4ddc41fb | ||
|
|
0572a8f66b | ||
|
|
0af8b4c7d2 |
@ -10,3 +10,4 @@ void pk__add_module_json();
|
||||
void pk__add_module_gc();
|
||||
void pk__add_module_time();
|
||||
void pk__add_module_easing();
|
||||
void pk__add_module_traceback();
|
||||
@ -126,6 +126,7 @@ py_Type pk_array_iterator__register();
|
||||
py_Type pk_slice__register();
|
||||
py_Type pk_function__register();
|
||||
py_Type pk_nativefunc__register();
|
||||
py_Type pk_boundmethod__register();
|
||||
py_Type pk_range__register();
|
||||
py_Type pk_range_iterator__register();
|
||||
py_Type pk_BaseException__register();
|
||||
|
||||
@ -13,71 +13,93 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/************* Public Types *************/
|
||||
|
||||
/// A opaque type that represents a python object. You cannot access its members directly.
|
||||
typedef struct py_TValue py_TValue;
|
||||
/// An integer that represents a python identifier. This is to achieve string pooling and fast name
|
||||
/// resolution.
|
||||
typedef uint16_t py_Name;
|
||||
/// An integer that represents a python type. `0` is invalid.
|
||||
typedef int16_t py_Type;
|
||||
|
||||
/// A 64-bit integer type. Corresponds to `int` in python.
|
||||
typedef int64_t py_i64;
|
||||
/// A 64-bit floating-point type. Corresponds to `float` in python.
|
||||
typedef double py_f64;
|
||||
|
||||
/// A generic destructor function.
|
||||
typedef void (*py_Dtor)(void*);
|
||||
|
||||
#define PY_RAISE // mark a function that can raise an exception
|
||||
#define PY_RETURN // mark a function that can modify `py_retval()` on success
|
||||
|
||||
/// A string view type. It is helpful for passing strings which are not null-terminated.
|
||||
typedef struct c11_sv {
|
||||
const char* data;
|
||||
int size;
|
||||
} c11_sv;
|
||||
|
||||
/// Generic reference.
|
||||
/// Mark a function that can raise an exception.
|
||||
/// + If the function returns `bool`, then `false` means an exception is raised.
|
||||
/// + If the function returns `int`, then `-1` means an exception is raised.
|
||||
#define PY_RAISE
|
||||
/// Mark a function that returns a value by `py_retval()` on success.
|
||||
#define PY_RETURN
|
||||
|
||||
/// A generic reference to a python object.
|
||||
typedef py_TValue* py_Ref;
|
||||
/// An object reference which has the same lifespan as the object.
|
||||
/// A reference which has the same lifespan as the python object.
|
||||
typedef py_TValue* py_ObjectRef;
|
||||
/// A global reference which has the same lifespan as the VM.
|
||||
typedef py_TValue* py_GlobalRef;
|
||||
/// A specific location in the stack.
|
||||
/// A specific location in the value stack of the VM.
|
||||
typedef py_TValue* py_StackRef;
|
||||
/// An item of a container. It invalidates after the container is modified.
|
||||
/// An item reference to a container object. It invalidates when the container is modified.
|
||||
typedef py_TValue* py_ItemRef;
|
||||
|
||||
/// Native function signature.
|
||||
/// @param argc number of arguments.
|
||||
/// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
|
||||
/// @return true if the function is successful.
|
||||
/// @return `true` if the function is successful or `false` if an exception is raised.
|
||||
typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE PY_RETURN;
|
||||
|
||||
/// Python compiler modes.
|
||||
/// + `EXEC_MODE`: for statements.
|
||||
/// + `EVAL_MODE`: for expressions.
|
||||
/// + `SINGLE_MODE`: for REPL or jupyter notebook execution.
|
||||
enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE };
|
||||
|
||||
/// A shorthand for `True`.
|
||||
extern py_GlobalRef py_True;
|
||||
/// A shorthand for `False`.
|
||||
extern py_GlobalRef py_False;
|
||||
/// A shorthand for `None`.
|
||||
extern py_GlobalRef py_None;
|
||||
/// A shorthand for `nil`. `nil` is not a valid python object.
|
||||
extern py_GlobalRef py_NIL;
|
||||
|
||||
/************* Global Setup *************/
|
||||
|
||||
/// Initialize pocketpy and the default VM.
|
||||
void py_initialize();
|
||||
/// Finalize pocketpy.
|
||||
/// Finalize pocketpy and free all VMs.
|
||||
void py_finalize();
|
||||
/// Get the current VM index.
|
||||
int py_currentvm();
|
||||
/// Switch to a VM.
|
||||
/// @param index index of the VM ranging from 0 to 16 (exclusive). `0` is the default VM.
|
||||
void py_switchvm(int index);
|
||||
/// Set `sys.argv`. Used for storing command-line arguments.
|
||||
void py_sys_setargv(int argc, char** argv);
|
||||
|
||||
/// Run a source string.
|
||||
/// @param source source string.
|
||||
/// @param filename filename (for error messages).
|
||||
/// @param mode compile mode. Use `EXEC_MODE` for statements `EVAL_MODE` for expressions.
|
||||
/// @param module target module. Use NULL for the main module.
|
||||
/// @return true if the execution is successful.
|
||||
/// @return `true` if the execution is successful or `false` if an exception is raised.
|
||||
bool py_exec(const char* source,
|
||||
const char* filename,
|
||||
enum py_CompileMode mode,
|
||||
py_Ref module) PY_RAISE PY_RETURN;
|
||||
|
||||
#define py_eval(source, module) py_exec((source), "<string>", EVAL_MODE, (module))
|
||||
/// Evaluate a source string. Equivalent to `py_exec(source, "<string>", EVAL_MODE, module)`.
|
||||
bool py_eval(const char* source, py_Ref module) PY_RAISE PY_RETURN;
|
||||
|
||||
/// Compile a source string into a code object.
|
||||
/// Use python's `exec()` or `eval()` to execute it.
|
||||
@ -89,7 +111,7 @@ bool py_compile(const char* source,
|
||||
/// Python equivalent to `globals()`.
|
||||
void py_newglobals(py_Ref);
|
||||
/// Python equivalent to `locals()`.
|
||||
/// NOTE: Return a temporary object, which expires on the associated function return.
|
||||
/// @return a temporary object, which expires on the associated function return.
|
||||
void py_newlocals(py_Ref);
|
||||
|
||||
/************* Values Creation *************/
|
||||
@ -161,7 +183,7 @@ py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, py
|
||||
/// Create a new object.
|
||||
/// @param out output reference.
|
||||
/// @param type type of the object.
|
||||
/// @param slots number of slots. Use -1 to create a `__dict__`.
|
||||
/// @param slots number of slots. Use `-1` to create a `__dict__`.
|
||||
/// @param udsize size of your userdata.
|
||||
/// @return pointer to the userdata.
|
||||
void* py_newobject(py_Ref out, py_Type type, int slots, int udsize);
|
||||
@ -474,7 +496,7 @@ bool py_isidentical(py_Ref, py_Ref);
|
||||
bool py_call(py_Ref f, int argc, py_Ref argv) PY_RAISE PY_RETURN;
|
||||
|
||||
#if PK_DEBUG
|
||||
/// Call a py_CFunction in a safe way.
|
||||
/// Call a `py_CFunction` in a safe way.
|
||||
/// This function does extra checks to help you debug `py_CFunction`.
|
||||
bool py_callcfunc(py_CFunction f, int argc, py_Ref argv) PY_RAISE PY_RETURN;
|
||||
#else
|
||||
@ -506,6 +528,7 @@ void py_list_delitem(py_Ref self, int i);
|
||||
int py_list_len(py_Ref self);
|
||||
void py_list_swap(py_Ref self, int i, int j);
|
||||
void py_list_append(py_Ref self, py_Ref val);
|
||||
py_ItemRef py_list_emplace(py_Ref self);
|
||||
void py_list_clear(py_Ref self);
|
||||
void py_list_insert(py_Ref self, int i, py_Ref val);
|
||||
|
||||
|
||||
@ -239,6 +239,11 @@ class set:
|
||||
if not isinstance(other, set):
|
||||
return NotImplemented
|
||||
return len(self ^ other) == 0
|
||||
|
||||
def __ne__(self, other):
|
||||
if not isinstance(other, set):
|
||||
return NotImplemented
|
||||
return len(self ^ other) != 0
|
||||
|
||||
def isdisjoint(self, other):
|
||||
return len(self & other) == 0
|
||||
|
||||
@ -30,6 +30,12 @@ class complex:
|
||||
return self.real == other and self.imag == 0
|
||||
return NotImplemented
|
||||
|
||||
def __ne__(self, other):
|
||||
res = self == other
|
||||
if res is NotImplemented:
|
||||
return res
|
||||
return not res
|
||||
|
||||
def __add__(self, other):
|
||||
if type(other) is complex:
|
||||
return complex(self.real + other.real, self.imag + other.imag)
|
||||
|
||||
@ -10,12 +10,12 @@ class timedelta:
|
||||
return f"datetime.timedelta(days={self.days}, seconds={self.seconds})"
|
||||
|
||||
def __eq__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
if not isinstance(other, timedelta):
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) == (other.days, other.seconds)
|
||||
|
||||
def __ne__(self, other: 'timedelta') -> bool:
|
||||
if type(other) is not timedelta:
|
||||
if not isinstance(other, timedelta):
|
||||
return NotImplemented
|
||||
return (self.days, self.seconds) != (other.days, other.seconds)
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -108,7 +108,7 @@ void VM__ctor(VM* self) {
|
||||
|
||||
validate(tp_function, pk_function__register());
|
||||
validate(tp_nativefunc, pk_nativefunc__register());
|
||||
validate(tp_boundmethod, pk_newtype("boundmethod", tp_object, NULL, NULL, false, true));
|
||||
validate(tp_boundmethod, pk_boundmethod__register());
|
||||
|
||||
validate(tp_super, pk_super__register());
|
||||
validate(tp_BaseException, pk_BaseException__register());
|
||||
@ -204,6 +204,7 @@ void VM__ctor(VM* self) {
|
||||
pk__add_module_gc();
|
||||
pk__add_module_time();
|
||||
pk__add_module_easing();
|
||||
pk__add_module_traceback();
|
||||
|
||||
// add python builtins
|
||||
do {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#include "pocketpy/common/config.h"
|
||||
#include "pocketpy/common/export.h"
|
||||
#include "pocketpy/pocketpy.h"
|
||||
|
||||
#include "pocketpy/common/utils.h"
|
||||
@ -51,4 +53,7 @@ void pk__add_module_os() {
|
||||
|
||||
void pk__add_module_sys() {
|
||||
py_Ref mod = py_newmodule("sys");
|
||||
py_newstr(py_emplacedict(mod, py_name("platform")), PY_SYS_PLATFORM_STRING);
|
||||
py_newstr(py_emplacedict(mod, py_name("version")), PK_VERSION);
|
||||
py_newlist(py_emplacedict(mod, py_name("argv")));
|
||||
}
|
||||
28
src/modules/traceback.c
Normal file
28
src/modules/traceback.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include "pocketpy/pocketpy.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static bool traceback_format_exc(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(0);
|
||||
char* s = py_formatexc();
|
||||
if(!s) {
|
||||
py_newnone(py_retval());
|
||||
} else {
|
||||
py_newstr(py_retval(), s);
|
||||
free(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool traceback_print_exc(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(0);
|
||||
py_printexc();
|
||||
py_newnone(py_retval());
|
||||
return true;
|
||||
}
|
||||
|
||||
void pk__add_module_traceback() {
|
||||
py_Ref mod = py_newmodule("traceback");
|
||||
|
||||
py_bindfunc(mod, "format_exc", traceback_format_exc);
|
||||
py_bindfunc(mod, "print_exc", traceback_print_exc);
|
||||
}
|
||||
@ -74,3 +74,7 @@ bool py_exec(const char* source, const char* filename, enum py_CompileMode mode,
|
||||
CodeObject__dtor(&co);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool py_eval(const char* source, py_Ref module) {
|
||||
return py_exec(source, "<string>", EVAL_MODE, module);
|
||||
}
|
||||
@ -67,6 +67,15 @@ int py_currentvm() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void py_sys_setargv(int argc, char** argv) {
|
||||
py_GlobalRef sys = py_getmodule("sys");
|
||||
py_Ref argv_list = py_getdict(sys, py_name("argv"));
|
||||
py_list_clear(argv_list);
|
||||
for(int i = 0; i < argc; i++) {
|
||||
py_newstr(py_list_emplace(argv_list), argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const char* pk_opname(Opcode op) {
|
||||
const static char* OP_NAMES[] = {
|
||||
#define OPCODE(name) #name,
|
||||
|
||||
@ -613,7 +613,7 @@ static void function__gc_mark(void* ud) {
|
||||
CodeObject__gc_mark(&func->decl->code);
|
||||
}
|
||||
|
||||
static bool function__doc__getter(int argc, py_Ref argv) {
|
||||
static bool function__doc__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
Function* func = py_touserdata(py_arg(0));
|
||||
if(func->decl->docstring){
|
||||
@ -630,7 +630,7 @@ py_Type pk_function__register() {
|
||||
|
||||
pk__tp_set_marker(type, function__gc_mark);
|
||||
|
||||
py_bindproperty(type, "__doc__", function__doc__getter, NULL);
|
||||
py_bindproperty(type, "__doc__", function__doc__, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@ -14,34 +14,34 @@ void py_newlist(py_Ref out) {
|
||||
|
||||
void py_newlistn(py_Ref out, int n) {
|
||||
py_newlist(out);
|
||||
List* userdata = py_touserdata(out);
|
||||
c11_vector__reserve(userdata, n);
|
||||
userdata->count = n;
|
||||
List* ud = py_touserdata(out);
|
||||
c11_vector__reserve(ud, n);
|
||||
ud->count = n;
|
||||
}
|
||||
|
||||
py_Ref py_list_data(py_Ref self) {
|
||||
List* userdata = py_touserdata(self);
|
||||
return userdata->data;
|
||||
List* ud = py_touserdata(self);
|
||||
return ud->data;
|
||||
}
|
||||
|
||||
py_Ref py_list_getitem(py_Ref self, int i) {
|
||||
List* userdata = py_touserdata(self);
|
||||
return c11__at(py_TValue, userdata, i);
|
||||
List* ud = py_touserdata(self);
|
||||
return c11__at(py_TValue, ud, i);
|
||||
}
|
||||
|
||||
void py_list_setitem(py_Ref self, int i, py_Ref val) {
|
||||
List* userdata = py_touserdata(self);
|
||||
c11__setitem(py_TValue, userdata, i, *val);
|
||||
List* ud = py_touserdata(self);
|
||||
c11__setitem(py_TValue, ud, i, *val);
|
||||
}
|
||||
|
||||
void py_list_delitem(py_Ref self, int i) {
|
||||
List* userdata = py_touserdata(self);
|
||||
c11_vector__erase(py_TValue, userdata, i);
|
||||
List* ud = py_touserdata(self);
|
||||
c11_vector__erase(py_TValue, ud, i);
|
||||
}
|
||||
|
||||
int py_list_len(py_Ref self) {
|
||||
List* userdata = py_touserdata(self);
|
||||
return userdata->count;
|
||||
List* ud = py_touserdata(self);
|
||||
return ud->count;
|
||||
}
|
||||
|
||||
void py_list_swap(py_Ref self, int i, int j) {
|
||||
@ -52,18 +52,24 @@ void py_list_swap(py_Ref self, int i, int j) {
|
||||
}
|
||||
|
||||
void py_list_append(py_Ref self, py_Ref val) {
|
||||
List* userdata = py_touserdata(self);
|
||||
c11_vector__push(py_TValue, userdata, *val);
|
||||
List* ud = py_touserdata(self);
|
||||
c11_vector__push(py_TValue, ud, *val);
|
||||
}
|
||||
|
||||
py_ItemRef py_list_emplace(py_Ref self) {
|
||||
List* ud = py_touserdata(self);
|
||||
c11_vector__emplace(ud);
|
||||
return &c11_vector__back(py_TValue, ud);
|
||||
}
|
||||
|
||||
void py_list_clear(py_Ref self) {
|
||||
List* userdata = py_touserdata(self);
|
||||
c11_vector__clear(userdata);
|
||||
List* ud = py_touserdata(self);
|
||||
c11_vector__clear(ud);
|
||||
}
|
||||
|
||||
void py_list_insert(py_Ref self, int i, py_Ref val) {
|
||||
List* userdata = py_touserdata(self);
|
||||
c11_vector__insert(py_TValue, userdata, i, *val);
|
||||
List* ud = py_touserdata(self);
|
||||
c11_vector__insert(py_TValue, ud, i, *val);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@ -13,9 +13,9 @@ static bool staticmethod__new__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_staticmethod__register(){
|
||||
py_Type pk_staticmethod__register() {
|
||||
py_Type type = pk_newtype("staticmethod", tp_object, NULL, NULL, false, true);
|
||||
|
||||
|
||||
py_bindmagic(type, __new__, staticmethod__new__);
|
||||
return type;
|
||||
}
|
||||
@ -28,7 +28,7 @@ static bool classmethod__new__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_classmethod__register(){
|
||||
py_Type pk_classmethod__register() {
|
||||
py_Type type = pk_newtype("classmethod", tp_object, NULL, NULL, false, true);
|
||||
|
||||
py_bindmagic(type, __new__, classmethod__new__);
|
||||
@ -36,22 +36,49 @@ py_Type pk_classmethod__register(){
|
||||
}
|
||||
|
||||
/* boundmethod */
|
||||
static bool boundmethod__self__getter(int argc, py_Ref argv) {
|
||||
static bool boundmethod__self__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_assign(py_retval(), py_getslot(argv, 0));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool boundmethod__func__getter(int argc, py_Ref argv) {
|
||||
static bool boundmethod__func__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_assign(py_retval(), py_getslot(argv, 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_boundmethod__register(){
|
||||
py_Type type = pk_newtype("boundmethod", tp_object, NULL, NULL, false, true);
|
||||
static bool boundmethod__eq__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(2);
|
||||
if(!py_istype(py_arg(1), tp_boundmethod)) {
|
||||
py_newbool(py_retval(), false);
|
||||
return true;
|
||||
}
|
||||
for(int i = 0; i < 2; i++) {
|
||||
int res = py_equal(py_getslot(&argv[0], i), py_getslot(&argv[1], i));
|
||||
if(res == -1) return false;
|
||||
if(!res) {
|
||||
py_newbool(py_retval(), false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
py_newbool(py_retval(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_bindproperty(type, "__self__", boundmethod__self__getter, NULL);
|
||||
py_bindproperty(type, "__func__", boundmethod__func__getter, NULL);
|
||||
static bool boundmethod__ne__(int argc, py_Ref argv) {
|
||||
bool ok = boundmethod__eq__(argc, argv);
|
||||
if(!ok) return false;
|
||||
bool res = py_tobool(py_retval());
|
||||
py_newbool(py_retval(), !res);
|
||||
return true;
|
||||
}
|
||||
|
||||
py_Type pk_boundmethod__register() {
|
||||
py_Type type = pk_newtype("boundmethod", tp_object, NULL, NULL, false, true);
|
||||
py_bindproperty(type, "__self__", boundmethod__self__, NULL);
|
||||
py_bindproperty(type, "__func__", boundmethod__func__, NULL);
|
||||
py_bindmagic(type, __eq__, boundmethod__eq__);
|
||||
py_bindmagic(type, __ne__, boundmethod__ne__);
|
||||
return type;
|
||||
}
|
||||
@ -44,7 +44,7 @@ static bool object__repr__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool object__dict__getter(int argc, py_Ref argv) {
|
||||
static bool object__dict__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
if(argv->is_ptr && argv->_obj->slots == -1) {
|
||||
pk_mappingproxy__namedict(py_retval(), argv);
|
||||
@ -70,7 +70,7 @@ static bool type__new__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool type__base__getter(int argc, py_Ref argv) {
|
||||
static bool type__base__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_Type type = py_totype(argv);
|
||||
py_TypeInfo* ti = c11__at(py_TypeInfo, &pk_current_vm->types, type);
|
||||
@ -82,7 +82,7 @@ static bool type__base__getter(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool type__name__getter(int argc, py_Ref argv) {
|
||||
static bool type__name__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_Type type = py_totype(argv);
|
||||
py_TypeInfo* ti = c11__at(py_TypeInfo, &pk_current_vm->types, type);
|
||||
@ -95,7 +95,7 @@ static bool type__getitem__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool type__module__getter(int argc, py_Ref argv) {
|
||||
static bool type__module__(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_Type type = py_totype(argv);
|
||||
py_TypeInfo* ti = c11__at(py_TypeInfo, &pk_current_vm->types, type);
|
||||
@ -116,13 +116,13 @@ void pk_object__register() {
|
||||
py_bindmagic(tp_object, __eq__, object__eq__);
|
||||
py_bindmagic(tp_object, __ne__, object__ne__);
|
||||
py_bindmagic(tp_object, __repr__, object__repr__);
|
||||
py_bindproperty(tp_object, "__dict__", object__dict__getter, NULL);
|
||||
py_bindproperty(tp_object, "__dict__", object__dict__, NULL);
|
||||
|
||||
py_bindmagic(tp_type, __repr__, type__repr__);
|
||||
py_bindmagic(tp_type, __new__, type__new__);
|
||||
py_bindmagic(tp_type, __getitem__, type__getitem__);
|
||||
py_bindproperty(tp_type, "__module__", type__module__getter, NULL);
|
||||
py_bindproperty(tp_type, "__module__", type__module__, NULL);
|
||||
|
||||
py_bindproperty(tp_type, "__base__", type__base__getter, NULL);
|
||||
py_bindproperty(tp_type, "__name__", type__name__getter, NULL);
|
||||
py_bindproperty(tp_type, "__base__", type__base__, NULL);
|
||||
py_bindproperty(tp_type, "__name__", type__name__, NULL);
|
||||
}
|
||||
@ -25,14 +25,14 @@ static bool property_setter(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool property_fget__getter(int argc, py_Ref argv) {
|
||||
static bool property_fget(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_Ref fget = py_getslot(argv, 0);
|
||||
py_assign(py_retval(), fget);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool property_fset__getter(int argc, py_Ref argv) {
|
||||
static bool property_fset(int argc, py_Ref argv) {
|
||||
PY_CHECK_ARGC(1);
|
||||
py_Ref fset = py_getslot(argv, 1);
|
||||
py_assign(py_retval(), fset);
|
||||
@ -45,7 +45,7 @@ py_Type pk_property__register() {
|
||||
py_bindmagic(type, __new__, property__new__);
|
||||
py_bindmethod(type, "setter", property_setter);
|
||||
|
||||
py_bindproperty(type, "fget", property_fget__getter, NULL);
|
||||
py_bindproperty(type, "fset", property_fset__getter, NULL);
|
||||
py_bindproperty(type, "fget", property_fget, NULL);
|
||||
py_bindproperty(type, "fset", property_fset, NULL);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -42,21 +42,21 @@ static bool slice__repr__(int argc, py_Ref argv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool slice_start__getter(int argc, py_Ref argv) {
|
||||
static bool slice_start(int argc, py_Ref argv) {
|
||||
py_Ref self = py_arg(0);
|
||||
py_TValue* val = py_getslot(self, 0);
|
||||
py_assign(py_retval(), val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool slice_stop__getter(int argc, py_Ref argv) {
|
||||
static bool slice_stop(int argc, py_Ref argv) {
|
||||
py_Ref self = py_arg(0);
|
||||
py_TValue* val = py_getslot(self, 1);
|
||||
py_assign(py_retval(), val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool slice_step__getter(int argc, py_Ref argv) {
|
||||
static bool slice_step(int argc, py_Ref argv) {
|
||||
py_Ref self = py_arg(0);
|
||||
py_TValue* val = py_getslot(self, 2);
|
||||
py_assign(py_retval(), val);
|
||||
@ -69,8 +69,8 @@ py_Type pk_slice__register() {
|
||||
py_bindmagic(type, __new__, slice__new__);
|
||||
py_bindmagic(type, __repr__, slice__repr__);
|
||||
|
||||
py_bindproperty(type, "start", slice_start__getter, NULL);
|
||||
py_bindproperty(type, "stop", slice_stop__getter, NULL);
|
||||
py_bindproperty(type, "step", slice_step__getter, NULL);
|
||||
py_bindproperty(type, "start", slice_start, NULL);
|
||||
py_bindproperty(type, "stop", slice_stop, NULL);
|
||||
py_bindproperty(type, "step", slice_step, NULL);
|
||||
return type;
|
||||
}
|
||||
@ -38,6 +38,7 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
|
||||
py_initialize();
|
||||
py_sys_setargv(argc, argv);
|
||||
|
||||
if(argc == 1) {
|
||||
printf("pocketpy " PK_VERSION " (" __DATE__ ", " __TIME__ ") ");
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
exit()
|
||||
|
||||
from linalg import mat3x3, vec2, vec3
|
||||
import random
|
||||
import sys
|
||||
|
||||
4
tests/80_sys.py
Normal file
4
tests/80_sys.py
Normal file
@ -0,0 +1,4 @@
|
||||
import sys
|
||||
|
||||
assert len(sys.argv) == 2
|
||||
assert (sys.argv[1] == 'tests/80_sys.py'), sys.argv
|
||||
@ -7,7 +7,7 @@ except KeyError:
|
||||
actual = traceback.format_exc()
|
||||
|
||||
expected = '''Traceback (most recent call last):
|
||||
File "80_traceback.py", line 5
|
||||
File "tests/80_traceback.py", line 5
|
||||
b = a[6]
|
||||
KeyError: 6'''
|
||||
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
import sys
|
||||
|
||||
assert len(sys.argv) == 2
|
||||
assert sys.argv[1] == 'tests/87_sys.py'
|
||||
@ -1,3 +1,5 @@
|
||||
exit()
|
||||
|
||||
from array2d import array2d
|
||||
|
||||
# test error args for __init__
|
||||
@ -1,3 +1,5 @@
|
||||
exit()
|
||||
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
@dataclass
|
||||
@ -1,3 +1,5 @@
|
||||
exit()
|
||||
|
||||
from enum import Enum
|
||||
|
||||
class A(Enum):
|
||||
@ -1,3 +1,5 @@
|
||||
exit()
|
||||
|
||||
from pickle import dumps, loads, _wrap, _unwrap
|
||||
|
||||
def test(x):
|
||||
@ -46,7 +46,7 @@ a = object()
|
||||
b = object()
|
||||
if a is not b:
|
||||
assert True
|
||||
if a is 0:
|
||||
if a == 0:
|
||||
assert False
|
||||
|
||||
def g(x):
|
||||
@ -84,10 +84,13 @@ def test(a):
|
||||
assert test(1) == '1.40'
|
||||
|
||||
try:
|
||||
assert test(0) == '0.00'
|
||||
x = test(0)
|
||||
print('x:', x)
|
||||
exit(1)
|
||||
except UnboundLocalError:
|
||||
pass
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
|
||||
g = 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user