Skip to content

Commit 7712a09

Browse files
ondrasbinet
authored andcommitted
gopy/bind: support both byte and Unicode strings as function parameters
1 parent b43954f commit 7712a09

6 files changed

Lines changed: 73 additions & 6 deletions

File tree

SUPPORT_MATRIX.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ _examples/simple | yes | yes | yes | yes | yes
2323
_examples/sliceptr | yes | yes | yes | yes | yes
2424
_examples/slices | no | yes | yes | yes | yes
2525
_examples/structs | yes | yes | yes | yes | yes
26+
_examples/unicode | yes | yes | yes | yes | yes
2627
_examples/vars | yes | yes | yes | yes | yes

_examples/unicode/encoding.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2018 The go-python Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package encoding
6+
7+
var gostring = "Go Unicode string 🐱"
8+
9+
func HandleString(s string) string {
10+
return s
11+
}
12+
13+
func GetString() string {
14+
return gostring
15+
}

_examples/unicode/test.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Copyright 2018 The go-python Authors. All rights reserved.
4+
# Use of this source code is governed by a BSD-style
5+
# license that can be found in the LICENSE file.
6+
7+
## py2/py3 compat
8+
from __future__ import print_function, unicode_literals
9+
10+
import encoding
11+
12+
bytestr = b"Python byte string"
13+
unicodestr = u"Python Unicode string 🐱"
14+
15+
bytestr_ret = encoding.HandleString(bytestr)
16+
unicodestr_ret = encoding.HandleString(unicodestr)
17+
18+
print("encoding.HandleString(bytestr) ->", bytestr_ret)
19+
print("encoding.HandleString(unicodestr) ->", unicodestr_ret)
20+
21+
gostring_ret = encoding.GetString()
22+
print("encoding.GetString() ->", gostring_ret)
23+

bind/gencffi.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ class _cffi_helper(object):
8787
8888
@staticmethod
8989
def cffi_cgopy_cnv_py2c_string(o):
90-
if _PY3:
91-
o = o.encode('ascii')
90+
if (_PY3 and isinstance(o, str)) or (not _PY3 and isinstance(o, unicode)):
91+
o = o.encode('utf8')
9292
s = ffi.new("char[]", o)
9393
return _cffi_helper.lib._cgopy_GoString(s)
9494

bind/gencpy.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,25 @@ cgopy_cnv_c2py_bool(GoUint8 *addr) {
103103
104104
static int
105105
cgopy_cnv_py2c_string(PyObject *o, GoString *addr) {
106-
const char *str = PyString_AsString(o);
107-
if (str == NULL) {
108-
return 0;
106+
if (PyUnicode_Check(o)) {
107+
o = PyUnicode_AsUTF8String(o);
108+
if (o == NULL) {
109+
return 0;
110+
}
111+
const char *str = PyString_AsString(o);
112+
if (str == NULL) {
113+
Py_DECREF(o);
114+
return 0;
115+
}
116+
*addr = _cgopy_GoString((char*)str);
117+
Py_DECREF(o);
118+
} else {
119+
const char *str = PyString_AsString(o);
120+
if (str == NULL) {
121+
return 0;
122+
}
123+
*addr = _cgopy_GoString((char*)str);
109124
}
110-
*addr = _cgopy_GoString((char*)str);
111125
return 1;
112126
}
113127

main_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ var features = map[string][]string{
213213
"_examples/maps": []string{"py2-cffi", "py3-cffi", "pypy2-cffi", "pypy3-cffi"},
214214
"_examples/gostrings": []string{"py2", "py2-cffi", "py3-cffi", "pypy2-cffi", "pypy3-cffi"},
215215
"_examples/rename": []string{"py2", "py2-cffi", "py3-cffi", "pypy2-cffi", "pypy3-cffi"},
216+
"_examples/unicode": []string{"py2", "py2-cffi", "py3-cffi", "pypy2-cffi", "pypy3-cffi"},
216217
}
217218

218219
func TestHi(t *testing.T) {
@@ -881,6 +882,19 @@ sliceptr.StrVector{"1", "2", "3", "4"}
881882
})
882883
}
883884

885+
func TestUnicode(t *testing.T) {
886+
t.Parallel()
887+
path := "_examples/unicode"
888+
testPkg(t, pkg{
889+
path: path,
890+
lang: []string{"py2", "py2-cffi", "py3-cffi", "pypy2-cffi", "pypy3-cffi"},
891+
want: []byte(`encoding.HandleString(bytestr) -> Python byte string
892+
encoding.HandleString(unicodestr) -> Python Unicode string 🐱
893+
encoding.GetString() -> Go Unicode string 🐱
894+
`),
895+
})
896+
}
897+
884898
// Generate / verify SUPPORT_MATRIX.md from features map.
885899
func TestCheckSupportMatrix(t *testing.T) {
886900
var buf bytes.Buffer

0 commit comments

Comments
 (0)