From patchwork Mon Dec 21 20:47:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell Bryant X-Patchwork-Id: 559714 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (unknown [IPv6:2600:3c00::f03c:91ff:fe6e:bdf7]) by ozlabs.org (Postfix) with ESMTP id 7CD40140BB2 for ; Tue, 22 Dec 2015 07:51:11 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 4D664106E9; Mon, 21 Dec 2015 12:48:26 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id D7C5610666 for ; Mon, 21 Dec 2015 12:48:23 -0800 (PST) Received: from bar3.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id 6FF84161B1B for ; Mon, 21 Dec 2015 13:48:23 -0700 (MST) X-ASG-Debug-ID: 1450730902-03dd7b579c420550001-byXFYA Received: from mx3-pf3.cudamail.com ([192.168.14.3]) by bar3.cudamail.com with ESMTP id vfCWTle32yrLFyJP (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 21 Dec 2015 13:48:23 -0700 (MST) X-Barracuda-Envelope-From: russell@ovn.org X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.3 Received: from unknown (HELO mx1.redhat.com) (209.132.183.28) by mx3-pf3.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 21 Dec 2015 21:03:54 -0000 Received-SPF: neutral (mx3-pf3.cudamail.com: 209.132.183.28 is neither permitted nor denied by SPF record at ovn.org) X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-Barracuda-RBL-IP: 209.132.183.28 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 24D8868E0F; Mon, 21 Dec 2015 20:48:22 +0000 (UTC) Received: from x1c.redhat.com ([10.3.112.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tBLKm0df002018; Mon, 21 Dec 2015 15:48:21 -0500 X-CudaMail-Envelope-Sender: russell@ovn.org From: Russell Bryant To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-V3-1220053442 X-CudaMail-DTE: 122115 X-CudaMail-Originating-IP: 209.132.183.28 Date: Mon, 21 Dec 2015 15:47:18 -0500 X-ASG-Orig-Subj: [##CM-V3-1220053442##][PATCH 18/55] python: Drop unicode type. Message-Id: <1450730875-18083-19-git-send-email-russell@ovn.org> In-Reply-To: <1450730875-18083-1-git-send-email-russell@ovn.org> References: <1450730875-18083-1-git-send-email-russell@ovn.org> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: UNKNOWN[192.168.14.3] X-Barracuda-Start-Time: 1450730903 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH 18/55] python: Drop unicode type. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" Python 2 had str and unicode. Python 3 only has str, which is always a unicode string. Drop use of unicode with the help of six.text_type (unicode in py2 and str in py3) and six.string_types ([str, unicode] in py2 and [str] in py3). Signed-off-by: Russell Bryant --- python/ovs/db/data.py | 6 +++--- python/ovs/db/parser.py | 14 +++++++++----- python/ovs/db/schema.py | 15 ++++++++------- python/ovs/db/types.py | 24 +++++++++++++++--------- python/ovs/json.py | 25 ++++++++++++++++--------- python/ovs/jsonrpc.py | 6 ++++-- python/ovs/ovsuuid.py | 5 +++-- python/ovs/unixctl/server.py | 3 ++- 8 files changed, 60 insertions(+), 38 deletions(-) diff --git a/python/ovs/db/data.py b/python/ovs/db/data.py index 9cbf425..c2915e1 100644 --- a/python/ovs/db/data.py +++ b/python/ovs/db/data.py @@ -117,7 +117,7 @@ class Atom(object): and isinstance(json, real_types)) or (type_ == ovs.db.types.BooleanType and isinstance(json, bool)) or (type_ == ovs.db.types.StringType - and isinstance(json, (str, unicode)))): + and isinstance(json, six.string_types))): atom = Atom(type_, json) elif type_ == ovs.db.types.UuidType: atom = Atom(type_, ovs.ovsuuid.from_json(json, symtab)) @@ -129,7 +129,7 @@ class Atom(object): @staticmethod def from_python(base, value): value = ovs.db.parser.float_to_int(value) - if type(value) in base.type.python_types: + if isinstance(value, base.type.python_types): atom = Atom(base.type, value) else: raise error.Error("expected %s, got %s" % (base.type, type(value))) @@ -247,7 +247,7 @@ class Atom(object): t = ovs.db.types.RealType elif isinstance(x, bool): t = ovs.db.types.BooleanType - elif isinstance(x, (str, unicode)): + elif isinstance(x, six.string_types): t = ovs.db.types.StringType elif isinstance(x, uuid): t = ovs.db.types.UuidType diff --git a/python/ovs/db/parser.py b/python/ovs/db/parser.py index 293dd98..d48a790 100644 --- a/python/ovs/db/parser.py +++ b/python/ovs/db/parser.py @@ -33,7 +33,10 @@ class Parser(object): member = float_to_int(self.json[name]) if is_identifier(member) and "id" in types: return member - if len(types) and type(member) not in types: + try: + if len(types) and not isinstance(member, tuple(types)): + self.__raise_error("Type mismatch for member '%s'." % name) + except TypeError: self.__raise_error("Type mismatch for member '%s'." % name) return member else: @@ -78,7 +81,7 @@ id_re = re.compile("[_a-zA-Z][_a-zA-Z0-9]*$") def is_identifier(s): - return type(s) in [str, unicode] and id_re.match(s) + return isinstance(s, six.string_types) and id_re.match(s) def json_type_to_string(type_): @@ -95,15 +98,16 @@ def json_type_to_string(type_): return "array" elif issubclass(type_, number_types): return "number" - elif issubclass(type_, (str, unicode)): + elif issubclass(type_, six.string_types): return "string" else: return "" def unwrap_json(json, name, types, desc): - if (type(json) not in (list, tuple) or len(json) != 2 or json[0] != name or - type(json[1]) not in types): + if (not isinstance(json, (list, tuple)) + or len(json) != 2 or json[0] != name + or not isinstance(json[1], tuple(types))): raise error.Error('expected ["%s", <%s>]' % (name, desc), json) return json[1] diff --git a/python/ovs/db/schema.py b/python/ovs/db/schema.py index 399129e..1c492f8 100644 --- a/python/ovs/db/schema.py +++ b/python/ovs/db/schema.py @@ -67,8 +67,8 @@ class DbSchema(object): def from_json(json): parser = ovs.db.parser.Parser(json, "database schema") name = parser.get("name", ['id']) - version = parser.get_optional("version", [str, unicode]) - parser.get_optional("cksum", [str, unicode]) + version = parser.get_optional("version", six.string_types) + parser.get_optional("cksum", six.string_types) tablesJson = parser.get("tables", [dict]) parser.finish() @@ -133,8 +133,8 @@ class IdlSchema(DbSchema): @staticmethod def from_json(json): parser = ovs.db.parser.Parser(json, "IDL schema") - idlPrefix = parser.get("idlPrefix", [str, unicode]) - idlHeader = parser.get("idlHeader", [str, unicode]) + idlPrefix = parser.get("idlPrefix", six.string_types) + idlHeader = parser.get("idlHeader", six.string_types) subjson = dict(json) del subjson["idlPrefix"] @@ -152,7 +152,7 @@ def column_set_from_json(json, columns): raise error.Error("array of distinct column names expected", json) else: for column_name in json: - if type(column_name) not in [str, unicode]: + if not isinstance(column_name, six.string_types): raise error.Error("array of distinct column names expected", json) elif column_name not in columns: @@ -260,8 +260,9 @@ class ColumnSchema(object): parser = ovs.db.parser.Parser(json, "schema for column %s" % name) mutable = parser.get_optional("mutable", [bool], True) ephemeral = parser.get_optional("ephemeral", [bool], False) - type_ = ovs.db.types.Type.from_json(parser.get("type", - [dict, str, unicode])) + _types = list(six.string_types) + _types.extend([dict]) + type_ = ovs.db.types.Type.from_json(parser.get("type", _types)) parser.finish() return ColumnSchema(name, mutable, not ephemeral, type_) diff --git a/python/ovs/db/types.py b/python/ovs/db/types.py index d7ce00a..f4d1f90 100644 --- a/python/ovs/db/types.py +++ b/python/ovs/db/types.py @@ -39,7 +39,7 @@ class AtomicType(object): @staticmethod def from_json(json): - if type(json) not in [str, unicode]: + if not isinstance(json, six.string_types): raise error.Error("atomic-type expected", json) else: return AtomicType.from_string(json) @@ -64,7 +64,7 @@ VoidType = AtomicType("void", None, ()) IntegerType = AtomicType("integer", 0, six.integer_types) RealType = AtomicType("real", 0.0, REAL_PYTHON_TYPES) BooleanType = AtomicType("boolean", False, (bool,)) -StringType = AtomicType("string", "", (str, unicode)) +StringType = AtomicType("string", "", six.string_types) UuidType = AtomicType("uuid", ovs.ovsuuid.zero(), (uuid.UUID,)) ATOMIC_TYPES = [VoidType, IntegerType, RealType, BooleanType, StringType, @@ -166,11 +166,12 @@ class BaseType(object): @staticmethod def from_json(json): - if type(json) in [str, unicode]: + if isinstance(json, six.string_types): return BaseType(AtomicType.from_json(json)) parser = ovs.db.parser.Parser(json, "ovsdb type") - atomic_type = AtomicType.from_json(parser.get("type", [str, unicode])) + atomic_type = AtomicType.from_json(parser.get("type", + six.string_types)) base = BaseType(atomic_type) @@ -199,7 +200,8 @@ class BaseType(object): elif base.type == UuidType: base.ref_table_name = parser.get_optional("refTable", ['id']) if base.ref_table_name: - base.ref_type = parser.get_optional("refType", [str, unicode], + base.ref_type = parser.get_optional("refType", + six.string_types, "strong") if base.ref_type not in ['strong', 'weak']: raise error.Error('refType must be "strong" or "weak" ' @@ -487,14 +489,18 @@ class Type(object): @staticmethod def from_json(json): - if type(json) in [str, unicode]: + if isinstance(json, six.string_types): return Type(BaseType.from_json(json)) parser = ovs.db.parser.Parser(json, "ovsdb type") - key_json = parser.get("key", [dict, str, unicode]) - value_json = parser.get_optional("value", [dict, str, unicode]) + _types = list(six.string_types) + _types.extend([dict]) + key_json = parser.get("key", _types) + value_json = parser.get_optional("value", _types) min_json = parser.get_optional("min", [int]) - max_json = parser.get_optional("max", [int, str, unicode]) + _types = list(six.string_types) + _types.extend([int]) + max_json = parser.get_optional("max", _types) parser.finish() key = BaseType.from_json(key_json) diff --git a/python/ovs/json.py b/python/ovs/json.py index 042f366..c1dcd63 100644 --- a/python/ovs/json.py +++ b/python/ovs/json.py @@ -61,10 +61,13 @@ class _Serializer(object): self.stream.write(u"%d" % obj) elif isinstance(obj, float): self.stream.write("%.15g" % obj) - elif isinstance(obj, unicode): + elif isinstance(obj, six.text_type): + # unicode() on Python 2, or str() in Python 3 (always unicode) self.__serialize_string(obj) elif isinstance(obj, str): - self.__serialize_string(unicode(obj)) + # This is for Python 2, where this comes out to unicode(str()). + # For Python 3, it's str(str()), but it's harmless. + self.__serialize_string(six.text_type(obj)) elif isinstance(obj, dict): self.stream.write(u"{") @@ -79,7 +82,7 @@ class _Serializer(object): if i > 0: self.stream.write(u",") self.__indent_line() - self.__serialize_string(unicode(key)) + self.__serialize_string(six.text_type(key)) self.stream.write(u":") if self.pretty: self.stream.write(u' ') @@ -144,12 +147,16 @@ def from_file(name): def from_string(s): - try: - s = unicode(s, 'utf-8') - except UnicodeDecodeError as e: - seq = ' '.join(["0x%2x" % ord(c) - for c in e.object[e.start:e.end] if ord(c) >= 0x80]) - return ("not a valid UTF-8 string: invalid UTF-8 sequence %s" % seq) + if not isinstance(s, six.text_type): + # We assume the input is a string. We will only hit this case for a + # str in Python 2 which is not unicode, so we need to go ahead and + # decode it. + try: + s = six.text_type(s, 'utf-8') + except UnicodeDecodeError as e: + seq = ' '.join(["0x%2x" % ord(c) + for c in e.object[e.start:e.end] if ord(c) >= 0x80]) + return "not a valid UTF-8 string: invalid UTF-8 sequence %s" % seq p = Parser(check_trailer=True) p.feed(s) return p.finish() diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py index 99aa27c..f576b25 100644 --- a/python/ovs/jsonrpc.py +++ b/python/ovs/jsonrpc.py @@ -15,6 +15,8 @@ import errno import os +import six + import ovs.json import ovs.poller import ovs.reconnect @@ -115,7 +117,7 @@ class Message(object): if "method" in json: method = json.pop("method") - if type(method) not in [str, unicode]: + if not isinstance(method, six.string_types): return "method is not a JSON string" else: method = None @@ -318,7 +320,7 @@ class Connection(object): def __process_msg(self): json = self.parser.finish() self.parser = None - if type(json) in [str, unicode]: + if isinstance(json, six.string_types): # XXX rate-limit vlog.warn("%s: error parsing stream: %s" % (self.name, json)) self.error(errno.EPROTO) diff --git a/python/ovs/ovsuuid.py b/python/ovs/ovsuuid.py index f2d48ea..a8f0d14 100644 --- a/python/ovs/ovsuuid.py +++ b/python/ovs/ovsuuid.py @@ -15,6 +15,7 @@ import re import uuid +import six from six.moves import range from ovs.db import error @@ -40,7 +41,7 @@ def from_string(s): def from_json(json, symtab=None): try: - s = ovs.db.parser.unwrap_json(json, "uuid", [str, unicode], "string") + s = ovs.db.parser.unwrap_json(json, "uuid", six.string_types, "string") if not uuidRE.match(s): raise error.Error("\"%s\" is not a valid UUID" % s, json) return uuid.UUID(s) @@ -49,7 +50,7 @@ def from_json(json, symtab=None): raise e try: name = ovs.db.parser.unwrap_json(json, "named-uuid", - [str, unicode], "string") + six.string_types, "string") except error.Error: raise e diff --git a/python/ovs/unixctl/server.py b/python/ovs/unixctl/server.py index 9744cf2..4ea19a1 100644 --- a/python/ovs/unixctl/server.py +++ b/python/ovs/unixctl/server.py @@ -17,6 +17,7 @@ import errno import os import types +import six from six.moves import range import ovs.dirs @@ -125,7 +126,7 @@ class UnixctlConnection(object): break if error is None: - unicode_params = [unicode(p) for p in params] + unicode_params = [six.text_type(p) for p in params] command.callback(self, unicode_params, command.aux) if error: