diff --git a/extra/python/ffi/ffi.factor b/extra/python/ffi/ffi.factor index 19b6b76cac..a9c394a6a7 100644 --- a/extra/python/ffi/ffi.factor +++ b/extra/python/ffi/ffi.factor @@ -17,6 +17,9 @@ IN: python.ffi "python" prepend find-library ] map-find drop cdecl add-library >> +! Functions that return borrowed references needs to be called like this: +! Py_Func dup Py_IncRef &Py_DecRef + LIBRARY: python C-TYPE: PyObject @@ -51,13 +54,15 @@ FUNCTION: int PyDict_SetItem ( PyObject* d, PyObject* k, PyObject* o ) ; FUNCTION: PyObject* PyDict_Items ( PyObject *d ) ; ! Tuples +! Borrowed reference FUNCTION: PyObject* PyTuple_GetItem ( PyObject* t, int pos ) ; FUNCTION: PyObject* PyTuple_New ( int len ) ; ! Steals the reference FUNCTION: int PyTuple_SetItem ( PyObject* t, int pos, PyObject* o ) ; FUNCTION: int PyTuple_Size ( PyObject* t ) ; -! Lists (sequences) +! Lists +! Borrowed reference FUNCTION: PyObject* PyList_GetItem ( PyObject* l, int pos ) ; FUNCTION: int PyList_Size ( PyObject* t ) ; @@ -75,6 +80,7 @@ FUNCTION: PyObject* PyObject_Call ( PyObject* callable, FUNCTION: PyObject* PyObject_GetAttrString ( PyObject* callable, c-string attr_name ) ; FUNCTION: PyObject* PyObject_Str ( PyObject* o ) ; +FUNCTION: int PyObject_IsTrue ( PyObject* o ) ; ! Strings FUNCTION: c-string PyString_AsString ( PyObject* string ) ; diff --git a/extra/python/python-tests.factor b/extra/python/python-tests.factor index 28529acbad..b757dbb790 100644 --- a/extra/python/python-tests.factor +++ b/extra/python/python-tests.factor @@ -6,7 +6,7 @@ USING: fry kernel math namespaces - python python.ffi python.stdlib.sys + python python.ffi python.stdlib.builtin python.stdlib.sys sequences strings tools.test ; IN: python.tests @@ -128,3 +128,17 @@ SYMBOLS: year month day ; ] [ "foo" py-dict-get-item-string getrefcount >factor ] tri - ] py-test + +[ -2 ] [ + "abcd" >py <1py-tuple> + [ 0 py-tuple-get-item getrefcount >factor ] + [ + [ 100 [ swap 0 py-tuple-get-item drop ] with times ] with-destructors + ] + [ 0 py-tuple-get-item getrefcount >factor ] tri - +] py-test + +! Tests for builtins +[ 10 ] [ 10 range >factor length ] py-test + +[ t ] [ "os" import "getpid" getattr callable >factor ] py-test diff --git a/extra/python/python.factor b/extra/python/python.factor index aff339bb75..c5467d415d 100644 --- a/extra/python/python.factor +++ b/extra/python/python.factor @@ -60,7 +60,7 @@ ERROR: python-error type message ; dup Py_IncRef PyTuple_SetItem check-return-code ; : py-tuple-get-item ( obj pos -- val ) - PyTuple_GetItem check-return ; + PyTuple_GetItem dup Py_IncRef check-return ; : py-tuple-size ( obj -- len ) PyTuple_Size ; @@ -89,7 +89,7 @@ ERROR: python-error type message ; PyList_Size ; : py-list-get-item ( obj pos -- val ) - PyList_GetItem check-return ; + PyList_GetItem dup Py_IncRef check-return ; ! Unicodes : py-ucs-size ( -- n ) @@ -135,6 +135,7 @@ DEFER: >factor : init-py-type-dispatch ( -- table ) H{ { "NoneType" [ drop f ] } + { "bool" [ PyObject_IsTrue 1 = ] } { "dict" [ PyDict_Items (check-return) >factor >hashtable ] } { "int" [ PyInt_AsLong ] } { "list" [ diff --git a/extra/python/stdlib/builtin/builtin.factor b/extra/python/stdlib/builtin/builtin.factor index 54dd556acb..cc070aa307 100644 --- a/extra/python/stdlib/builtin/builtin.factor +++ b/extra/python/stdlib/builtin/builtin.factor @@ -7,9 +7,20 @@ SYMBOL: builtin builtin [ "__builtin__" import ] initialize +: simple-call ( arg func-name -- return ) + builtin get swap getattr swap <1py-tuple> call-object ; + : repr ( alien/factor -- py-str ) - dup alien? [ >py ] unless - <1py-tuple> builtin get "repr" getattr swap call-object ; + dup alien? [ >py ] unless "repr" simple-call ; : range ( n -- py-list ) - builtin get "range" getattr swap 1array >py call-object ; + >py "range" simple-call ; + +: dir ( obj -- py-list ) + "dir" simple-call ; + +: type ( obj -- py-obj ) + "type" simple-call ; + +: callable ( obj -- py-obj ) + "callable" simple-call ;