From 2f1dd560812b610f2a0bf4447edc368cb680d88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20B=C3=A9langer?= Date: Wed, 14 Sep 2022 21:26:50 -0400 Subject: [PATCH 1/5] Missing DECREF after temp capsule creation. --- python.scm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python.scm b/python.scm index d2020ad..8d8ea13 100644 --- a/python.scm +++ b/python.scm @@ -1600,6 +1600,8 @@ GIL_ACQUIRE(); PyObject *capsule = PyObject_GetAttrString(src, \"obj_capsule\"); void *rc = PyCapsule_GetPointer(capsule, NULL); +PYOBJECTPTR_DECREF(capsule, \"SchemeObject->object\"); + dst = ___EXT(___data_rc)(rc); GIL_RELEASE(); From 4b097ea6b938cd4b1e9500f09eaee8005723038f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20B=C3=A9langer?= Date: Wed, 14 Sep 2022 21:27:23 -0400 Subject: [PATCH 2/5] Fix handling of generic calls (bad paren). --- python.scm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python.scm b/python.scm index 8d8ea13..c80af72 100644 --- a/python.scm +++ b/python.scm @@ -2008,10 +2008,10 @@ ___return(dst); (cons (keyword->string arg) kw-keys) (cons (car rest) kw-vals)) (error "Keyword argument has no value" args)) - (loop (cdr args) (cons (car args) *args) kw-keys kw-vals)) - (if (null? kw-keys) - (sfpc-call callable (list->vector (reverse *args))) - (sfpc-call-with-kw callable (list->vector (reverse *args)) kw-keys kw-vals)))))) + (loop rest (cons arg *args) kw-keys kw-vals))) + (if (null? kw-keys) + (sfpc-call callable (list->vector (reverse *args))) + (sfpc-call-with-kw callable (list->vector (reverse *args)) kw-keys kw-vals))))) (cond ((eq? arg1 (macro-absent-obj)) (sfpc-call callable '#())) From f3ddd2fd06fbdc3e015bc0f73a622a9d6476ba7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20B=C3=A9langer?= Date: Wed, 14 Sep 2022 21:27:51 -0400 Subject: [PATCH 3/5] Use less recent API additions. --- python.scm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python.scm b/python.scm index c80af72..94c4d0d 100644 --- a/python.scm +++ b/python.scm @@ -2187,11 +2187,11 @@ ___return(dst); ;; TODO: Handle **kwargs in Python call (define (PyObject_CallFunctionObjArgs* callable args) (if (not (pair? args)) - (PyObject_CallNoArgs callable) + (PyObject_CallFunctionObjArgs0 callable) (let ((arg1 (car args)) (rest (cdr args))) (if (not (pair? rest)) - (PyObject_CallOneArg callable arg1) + (PyObject_CallFunctionObjArgs1 callable arg1) (let ((arg2 (car rest)) (rest (cdr rest))) (if (not (pair? rest)) From d485e72c26ff11c6c2867b3abfbeb200f14fd4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20B=C3=A9langer?= Date: Wed, 14 Sep 2022 21:28:32 -0400 Subject: [PATCH 4/5] Use Gambit C FFI for proper refcount handling. --- python.scm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python.scm b/python.scm index 94c4d0d..3eeb950 100644 --- a/python.scm +++ b/python.scm @@ -3056,7 +3056,10 @@ end-of-c-declare (define python-exec (sfpc-send-recv (get-scheme-fpc-state!) (vector op-get-exec))) -(define python-SchemeProcedure (python-eval "_SchemeProcedure")) +(define python-SchemeProcedure + (let ((_SchemeProcedure (python-eval "foreign(_SchemeProcedure)"))) + (lambda (obj) + (PyObject_CallFunctionObjArgs1 _SchemeProcedure (object->SchemeObject obj))))) ((python-eval "__import__('sys').path.append") (path-expand "site-packages" python-venv-lib-dir)) From 9e202de431897a370a427a2d0a3691365e886819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20B=C3=A9langer?= Date: Wed, 14 Sep 2022 21:29:12 -0400 Subject: [PATCH 5/5] Add tuple to list conversion test. --- test/leaks.scm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/leaks.scm b/test/leaks.scm index 501de15..3edeecb 100644 --- a/test/leaks.scm +++ b/test/leaks.scm @@ -127,6 +127,15 @@ (test 'vector->PyObject*/list f) (test 'PyObject*/list->vector (lambda () (PyObject*/list->vector obj)))) +(let* ((elem0 (exact-integer->PyObject*/int 0)) + (elem1 (exact-integer->PyObject*/int 1)) + (elem2 (exact-integer->PyObject*/int 2)) + (x (list elem0 elem1 elem2)) + (f (lambda () (list->PyObject*/tuple x))) + (obj (f))) + (test 'list->PyObject*/tuple f) + (test 'PyObject*/tuple->list (lambda () (PyObject*/tuple->list obj)))) + (let* ((elem0 (exact-integer->PyObject*/int 0)) (elem1 (exact-integer->PyObject*/int 1)) (elem2 (exact-integer->PyObject*/int 2))