2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-21 14:49:41 +00:00

python: make python idl unicode-tolerant

Ensure that JSON is utf-8 encoded and that bytes sent/received on
the stream sockets are in utf-8 form. Add a test case to verify
that unicode data can be sent/received successfully using Python
IDL module.

Co-authored-by: Terry Wilson <twilson@redhat.com>
Signed-off-by: Terry Wilson <twilson@redhat.com>
Signed-off-by: Lance Richardson <lrichard@redhat.com>
Signed-off-by: Russell Bryant <russell@ovn.org>
This commit is contained in:
Lance Richardson
2017-08-09 15:38:43 -04:00
committed by Russell Bryant
parent f88ee3a599
commit e7164d96bc
5 changed files with 30 additions and 7 deletions

View File

@@ -29,8 +29,13 @@ except ImportError:
__pychecker__ = 'no-stringiter'
SPACES_PER_LEVEL = 2
dumper = functools.partial(json.dumps, separators=(",", ":"),
ensure_ascii=False)
_dumper = functools.partial(json.dumps, separators=(",", ":"))
if six.PY2:
def dumper(*args, **kwargs):
return _dumper(*args, **kwargs).decode('raw-unicode-escape')
else:
dumper = _dumper
def to_stream(obj, stream, pretty=False, sort_keys=True):

View File

@@ -268,8 +268,7 @@ class Connection(object):
# Python 3 has separate types for strings and bytes. We
# received bytes from a socket. We expect it to be string
# data, so we convert it here as soon as possible.
if (data and not error
and not isinstance(data, six.string_types)):
if data and not error:
try:
data = data.decode('utf-8')
except UnicodeError:

View File

@@ -386,8 +386,10 @@ class Stream(object):
try:
# Python 3 has separate types for strings and bytes. We must have
# bytes here.
if six.PY3 and not isinstance(buf, six.binary_type):
buf = six.binary_type(buf, 'utf-8')
if six.PY3 and not isinstance(buf, bytes):
buf = bytes(buf, 'utf-8')
elif six.PY2:
buf = buf.encode('utf-8')
return self.socket.send(buf)
except socket.error as e:
return -ovs.socket_util.get_exception_errno(e)

View File

@@ -315,6 +315,19 @@ OVSDB_CHECK_IDL([simple idl, writing via IDL],
005: done
]])
OVSDB_CHECK_IDL([simple idl, writing via IDL with unicode],
[['["idltest",
{"op": "insert",
"table": "simple",
"row": {"s": "(╯°□°)╯︵ ┻━┻"}}]']],
[['set 0 b 1, insert 1, set 1 s "¯\_(ツ)_/¯"']],
[[000: i=0 r=0 b=false s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
001: commit, status=success
002: i=0 r=0 b=true s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
002: i=1 r=0 b=false s="¯\_(ツ)_/¯" u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
003: done
]])
OVSDB_CHECK_IDL([simple idl, handling verification failure],
[['["idltest",
{"op": "insert",

View File

@@ -334,7 +334,11 @@ def idl_set(idl, commands, step):
if args[1] == "b":
s.b = args[2] == "1"
elif args[1] == "s":
s.s = args[2]
if six.PY2:
s.s = args[2].decode('utf-8')
else:
s.s = args[2].encode('utf-8', 'surrogateescape') \
.decode('utf-8', 'replace')
elif args[1] == "u":
s.u = uuid.UUID(args[2])
elif args[1] == "r":