Skip to content

Commit

Permalink
added support for py3
Browse files Browse the repository at this point in the history
  • Loading branch information
iraikov committed Oct 26, 2019
1 parent ee8125a commit 1aedab1
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 75 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ table below. All other Python data types are represented as pointers.

## Installation

The setup script of pyffi attempts to autodetect the location of
the Python header files and libraries for Python versions 2.3-2.7. The
autodetection routine checks some standard installation locations for
Linux, Mac OS X, and Windows. If autodetection fails, you may also
specify the header and library locations as follows:
The setup script of pyffi attempts to autodetect the location of the
Python header files and libraries for Python versions 2.6-2.7 or
3.5-3.7. The autodetection routine checks some standard installation
locations for Linux, Mac OS X, and Windows. If autodetection fails,
you may also specify the header and library locations as follows:

```
PYTHON_CFLAGS=-I/usr/include/python2.6 PYTHON_LFLAGS=-L/usr/lib PYTHON_LIBS=-lpython2.6 chicken-install pyffi
PYTHON_CFLAGS=-I/usr/include/python3.6 PYTHON_LFLAGS=-L/usr/lib PYTHON_LIBS=-lpython3.6 chicken-install pyffi
```

## Procedures
Expand Down
6 changes: 6 additions & 0 deletions build.scm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
(or (python-test ("<Python.h>"
"-I/System/Library/Frameworks/Python.framework/Headers"
"-framework Python"))
(python-test ("<Python.h>" "-I/usr/include/python3.7m" "-lpython3.7m"))
(python-test ("<Python.h>" "-I/usr/include/python3.7" "-lpython3.7"))
(python-test ("<Python.h>" "-I/usr/include/python3.6m" "-lpython3.6m"))
(python-test ("<Python.h>" "-I/usr/include/python3.6" "-lpython3.6"))
(python-test ("<Python.h>" "-I/usr/include/python3.5m" "-lpython3.5m"))
(python-test ("<Python.h>" "-I/usr/include/python3.5" "-lpython3.5"))
(python-test ("<Python.h>" "-I/usr/include/python2.7" "-lpython2.7"))
(python-test ("<Python.h>" "-I/usr/include/python2.6" "-lpython2.6"))
(python-test ("<Python.h>" "" "-lpython27"))
Expand Down
172 changes: 103 additions & 69 deletions pyffi.scm
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
;; Python -> Scheme
(define (py-object-from value)
(if (not value) (raise-python-exception))
(let ((typ-name (PyObject_Type_asString value)))
(let ((typ-name (pyffi_PyObject_Type_toCString value)))
(let ((typ-key (alist-ref typ-name *py-types* string=?)))
(if typ-key
(translate-from-foreign value typ-key)
Expand All @@ -112,14 +112,13 @@
value)))))

(define (py-object-type value)
(PyObject_Type_asString value))
(pyffi_PyObject_Type_toCString value))

;; Embed, but do not parse
#>

#include <Python.h>


#if ((PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION <= 3))
void Py_IncRef (PyObject *x)
{
Expand All @@ -146,37 +145,6 @@ PyObject *pyffi_PyImport_ImportModuleEx (char *name, PyObject *g, PyObject *l, P
}


#ifndef Py_UNICODE_WIDE
int *pyffi_PyUnicode_AsUnicode (PyObject *x)
{
return PyUnicodeUCS2_AsUnicode (x);
}
PyObject *pyffi_PyUnicode_FromUnicode (const int *s, int n)
{
return PyUnicodeUCS2_FromUnicode (s, n);
}
int pyffi_PyUnicode_GetSize (PyObject *x)
{
return PyUnicodeUCS2_GetSize (x);
}
#else
int *pyffi_PyUnicode_AsUnicode (PyObject *x)
{
int * result;
result = PyUnicodeUCS4_AsUnicode (x);

return result;
}
PyObject *pyffi_PyUnicode_FromUnicode (const int *s, int n)
{
return PyUnicodeUCS4_FromUnicode (s, n);
}
int pyffi_PyUnicode_GetSize (PyObject *x)
{
return PyUnicodeUCS4_GetSize (x);
}
#endif

C_word PyBool_asBool(PyObject *x)
{
if (x == (Py_True)) return C_SCHEME_TRUE;
Expand All @@ -195,6 +163,11 @@ int pyffi_PyUnicode_ref (int *x, int i)
return result;
}

#if PY_MAJOR_VERSION >= 3
#define PyInt_AsLong PyLong_AsLong
#define PyInt_FromLong PyLong_FromLong
#endif

<#


Expand Down Expand Up @@ -233,7 +206,6 @@ PyObject *PyImport_Import (pyobject );
PyObject *PyImport_ImportModule (const char *name);
PyObject *PyImport_AddModule (const char *name);


long PyInt_AsLong (PyObject *);
PyObject *PyInt_FromLong (long);

Expand All @@ -251,10 +223,6 @@ pyobject PyObject_GetAttrString (PyObject *, const char *);
int PyObject_SetAttrString (PyObject *, const char *, pyobject);
pyobject PyObject_Str (PyObject *);


char *PyString_AsString (PyObject *);
PyObject *PyString_FromString (const char *);

PyObject *PyTuple_New (int);
int PyTuple_Size (PyObject *);
pyobject PyTuple_GetItem (PyObject *, int);
Expand All @@ -278,23 +246,69 @@ PyObject *pyffi_PyImport_ImportModuleEx (char *, PyObject *, PyObject *, pyobjec

pyobject pyffi_PyRun_String (const char *str, int s, PyObject *g, PyObject *l);

int *pyffi_PyUnicode_AsUnicode (PyObject *);
PyObject *pyffi_PyUnicode_FromUnicode (const int *, int);
int pyffi_PyUnicode_GetSize (PyObject *);


PyObject *PyModule_GetDict_asPtr (PyObject *x)
{
return PyModule_GetDict (x);
}

char *PyString_asString(pyobject op)
PyObject* pyffi_PyString_fromCString(const char *string)
{
#if PY_MAJOR_VERSION >= 3
return PyUnicode_FromString(string);
#else
return PyBytes_FromString(string);
#endif

}

char *pyffi_PyString_toCString(pyobject op)
{
printf ("PyString_AsString\n");
return (((PyStringObject *)(op))->ob_sval);
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8(op);
#else
return PyBytes_AsString(op);
#endif

}

char *PyObject_Type_asString (pyobject x)
char *pyffi_PyString_toCStringAndSize(pyobject op, Py_ssize_t *size)
{
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8AndSize(op, size);
#else

return PyBytes_AsStringAndSize(op, size);
#endif

}

PyObject* pyffi_PyUnicode_fromCString(const char *string)
{
return PyUnicode_FromString(string);
}

char *pyffi_PyUnicode_toCString(pyobject op)
{
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8(op);
#else
return PyUnicode_AS_DATA(op);
#endif

}

char *pyffi_PyUnicode_toCStringAndSize(pyobject op, Py_ssize_t *size)
{
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8AndSize(op, size);
#else
size[0] = PyUnicode_GET_SIZE(op);
return PyUnicode_AS_DATA(op);
#endif

}

char *pyffi_PyObject_Type_toCString (pyobject x)
{
PyObject *typ, *str;

Expand All @@ -303,10 +317,15 @@ char *PyObject_Type_asString (pyobject x)

Py_DecRef (typ);

return (((PyStringObject *)(str))->ob_sval);
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8(str);
#else
return PyBytes_AsString(str);
#endif

}

char *PyErr_Occurred_asString (void)
char *pyffi_PyErr_Occurred_toCString (void)
{
PyObject *exc, *str;

Expand All @@ -315,8 +334,13 @@ char *PyErr_Occurred_asString (void)

Py_DecRef (exc);

return (((PyStringObject *)(str))->ob_sval);
}
#if PY_MAJOR_VERSION >= 3
return PyUnicode_AsUTF8(str);
#else
return PyBytes_AsString(str);
#endif

}

int PyBuffer_Size(Py_buffer *buf)
{
Expand All @@ -330,13 +354,13 @@ EOF
(define (pyerror-exn x) (make-property-condition 'pyerror 'message x))

(define (raise-python-exception)
(let* ((desc (PyErr_Occurred_asString)))
(let* ((desc (pyffi_PyErr_Occurred_toCString)))
(PyErr_Clear)
(print-error-message desc)
(signal (pyerror-exn desc))))

(define (python-exception-string)
(let* ((desc (PyErr_Occurred_asString)))
(let* ((desc (pyffi_PyErr_Occurred_toCString)))
desc))

(define-pytype py-int PyInt_FromLong PyInt_AsLong)
Expand Down Expand Up @@ -394,20 +418,20 @@ EOF

(define (utf8-string->py-unicode value)
;; Given a Scheme UTF8 string, converts it into Python Unicode string
(let ((str (list->s32vector (map char->integer (utf8-string->list value)))))
(let ((res (pyffi_PyUnicode_FromUnicode str (s32vector-length str))))
res)))
(let ((res (pyffi_PyUnicode_fromCString value)))
res))

(define (py-unicode->utf8-string value)
;; Given a Python Unicode string, converts it into Scheme UTF8 string
(let ((buf (pyffi_PyUnicode_AsUnicode value))
(len (pyffi_PyUnicode_GetSize value)))
(let loop ((i 0) (lst (list)))
(if (< i len)
(loop (+ 1 i) (cons (pyffi_PyUnicode_ref buf i) lst))
(list->string (map integer->char (reverse lst)))))))

(define-pytype py-ascii PyString_FromString PyString_AsString)
(let* ((len-vector (make-u32vector 1))
(buf (pyffi_PyUnicode_toCStringAndSize value len-vector))
(len (u32vector-ref len-vector 0)))
(let loop ((i 0) (lst (list)))
(if (< i len)
(loop (+ 1 i) (cons (pyffi_PyUnicode_ref buf i) lst))
(list->string (map integer->char (reverse lst)))))))

(define-pytype py-ascii pyffi_PyString_fromCString pyffi_PyString_toCString)
(define-pytype py-unicode utf8-string->py-unicode py-unicode->utf8-string)

(define-pytype py-dict
Expand Down Expand Up @@ -460,6 +484,19 @@ EOF

(define *py-types*
`(
("<class 'bool'>" . ,py-bool)
("<class 'bool'>" . ,py-bool)
("<class 'int'>" . ,py-int)
("<class 'float'>" . ,py-float)
("<class 'list'>" . ,py-list)
("<class 'str'>" . ,py-ascii)
("<class 'unicode'>" . ,py-unicode)
("<class 'dict'>" . ,py-dict)
("<class 'instance'>" . ,py-instance)
("<class 'tuple'>" . ,py-tuple)
("<class 'buffer'>" . ,py-buffer)

("<type 'bool'>" . ,py-bool)
("<type 'bool'>" . ,py-bool)
("<type 'int'>" . ,py-int)
("<type 'float'>" . ,py-float)
Expand All @@ -486,10 +523,7 @@ EOF
(Py_Initialize)
(*py-main-module* (PyImport_AddModule "__main__"))
(*py-main-module-dict* (PyModule_GetDict_asPtr (*py-main-module*)))
(Py_IncRef (*py-main-module-dict*))
(let ((tmp (pyffi_PyRun_String "from __builtin__ import *" +py-single-input+
(*py-main-module-dict*) #f)))
(Py_DecRef tmp)))
(Py_IncRef (*py-main-module-dict*)))

(define (py-stop)
(Py_DecRef (*py-main-module-dict*))
Expand Down
1 change: 1 addition & 0 deletions tests/run.scm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(import pyffi)

(py-start)
(py-eval "print(open)")
(py-import "sys")
(assert (string? (py-eval "sys.version")))
(print "Python version: " (py-eval "sys.version"))

0 comments on commit 1aedab1

Please sign in to comment.