Using six.string_types for python3 compatible

For python3 compatible, using six.string_types instead of
basestring(). six.string_types represent basestring in
python2 and str in python3.

Change-Id: Ib4ba3d164f782601944023b99d6cc1ee2763ee85
This commit is contained in:
Ethan Lynn 2014-10-31 12:46:06 +08:00
parent 3a642f5da2
commit a53c73fc4a
24 changed files with 81 additions and 64 deletions

View File

@ -20,6 +20,7 @@ for them before loading them.
"""
import pkgutil
import six
import sys
import types
@ -45,7 +46,8 @@ def create_subpackage(path, parent_package_name, subpackage_name="plugins"):
package_name = _module_name(parent_package_name, subpackage_name)
package = types.ModuleType(package_name)
package.__path__ = [path] if isinstance(path, basestring) else list(path)
package.__path__ = ([path] if isinstance(path, six.string_types)
else list(path))
sys.modules[package_name] = package
return package

View File

@ -19,6 +19,7 @@ The IDs each comprise 12 (lower-case) alphanumeric characters.
import base64
import uuid
import six
from six.moves import xrange
from heat.common.i18n import _
@ -40,7 +41,7 @@ def get_id(source_uuid):
The supplied UUID must be a version 4 UUID object.
"""
if isinstance(source_uuid, basestring):
if isinstance(source_uuid, six.string_types):
source_uuid = uuid.UUID(source_uuid)
if source_uuid.version != 4:
raise ValueError(_('Invalid UUID version (%d)') % source_uuid.version)

View File

@ -14,6 +14,7 @@
'''Implementation of SQLAlchemy backend.'''
from datetime import datetime
from datetime import timedelta
import six
import sys
from oslo.config import cfg
@ -322,7 +323,7 @@ def _get_sort_keys(sort_keys, mapping):
:param mapping: a mapping from keys to DB column names
:returns: filtered list of sort keys
'''
if isinstance(sort_keys, basestring):
if isinstance(sort_keys, six.string_types):
sort_keys = [sort_keys]
return [mapping[key] for key in sort_keys or [] if key in mapping]

View File

@ -12,6 +12,7 @@
# under the License.
import collections
import six
import warnings
from heat.common.i18n import _
@ -190,7 +191,7 @@ def select_from_attribute(attribute_value, path):
collections.Sequence)):
raise TypeError(_("Can't traverse attribute path"))
if not isinstance(key, (basestring, int)):
if not isinstance(key, (six.string_types, int)):
raise TypeError(_('Path components in attributes must be strings'))
return collection[key]

View File

@ -235,7 +235,7 @@ class Select(function.Function):
# Handle by returning an empty string
return ''
if isinstance(strings, basestring):
if isinstance(strings, six.string_types):
# might be serialized json.
try:
strings = json.loads(strings)
@ -245,13 +245,13 @@ class Select(function.Function):
raise ValueError(_('"%(fn_name)s": %(err)s') % fmt_data)
if isinstance(strings, collections.Mapping):
if not isinstance(index, basestring):
if not isinstance(index, six.string_types):
raise TypeError(_('Index to "%s" must be a string') %
self.fn_name)
return strings.get(index, '')
if (isinstance(strings, collections.Sequence) and
not isinstance(strings, basestring)):
not isinstance(strings, six.string_types)):
if not isinstance(index, (int, long)):
raise TypeError(_('Index to "%s" must be an integer') %
self.fn_name)
@ -288,7 +288,7 @@ class Join(function.Function):
fmt_data = {'fn_name': self.fn_name,
'example': example}
if isinstance(self.args, (basestring, collections.Mapping)):
if isinstance(self.args, (six.string_types, collections.Mapping)):
raise TypeError(_('Incorrect arguments to "%(fn_name)s" '
'should be: %(example)s') % fmt_data)
@ -302,19 +302,19 @@ class Join(function.Function):
strings = function.resolve(self._strings)
if strings is None:
strings = []
if (isinstance(strings, basestring) or
if (isinstance(strings, six.string_types) or
not isinstance(strings, collections.Sequence)):
raise TypeError(_('"%s" must operate on a list') % self.fn_name)
delim = function.resolve(self._delim)
if not isinstance(delim, basestring):
if not isinstance(delim, six.string_types):
raise TypeError(_('"%s" delimiter must be a string') %
self.fn_name)
def ensure_string(s):
if s is None:
return ''
if not isinstance(s, basestring):
if not isinstance(s, six.string_types):
raise TypeError(
_('Items to join must be strings %s') % (repr(s)[:200]))
return s
@ -342,7 +342,7 @@ class Split(function.Function):
fmt_data = {'fn_name': self.fn_name,
'example': example}
if isinstance(self.args, (basestring, collections.Mapping)):
if isinstance(self.args, (six.string_types, collections.Mapping)):
raise TypeError(_('Incorrect arguments to "%(fn_name)s" '
'should be: %(example)s') % fmt_data)
@ -355,10 +355,10 @@ class Split(function.Function):
def result(self):
strings = function.resolve(self._strings)
if not isinstance(self._delim, basestring):
if not isinstance(self._delim, six.string_types):
raise TypeError(_("Delimiter for %s must be string") %
self.fn_name)
if not isinstance(strings, basestring):
if not isinstance(strings, six.string_types):
raise TypeError(_("String to split must be string; got %s") %
type(strings))
@ -401,7 +401,7 @@ class Replace(function.Function):
fmt_data = {'fn_name': self.fn_name,
'example': example}
if isinstance(self.args, (basestring, collections.Mapping)):
if isinstance(self.args, (six.string_types, collections.Mapping)):
raise TypeError(_('Incorrect arguments to "%(fn_name)s" '
'should be: %(example)s') % fmt_data)
@ -417,7 +417,7 @@ class Replace(function.Function):
template = function.resolve(self._string)
mapping = function.resolve(self._mapping)
if not isinstance(template, basestring):
if not isinstance(template, six.string_types):
raise TypeError(_('"%s" template must be a string') % self.fn_name)
if not isinstance(mapping, collections.Mapping):
@ -426,14 +426,15 @@ class Replace(function.Function):
def replace(string, change):
placeholder, value = change
if not isinstance(placeholder, basestring):
if not isinstance(placeholder, six.string_types):
raise TypeError(_('"%s" param placeholders must be strings') %
self.fn_name)
if value is None:
value = ''
if not isinstance(value, (basestring, int, long, float, bool)):
if not isinstance(value,
(six.string_types, int, long, float, bool)):
raise TypeError(_('"%s" params must be strings or numbers') %
self.fn_name)
@ -457,7 +458,7 @@ class Base64(function.Function):
def result(self):
resolved = function.resolve(self.args)
if not isinstance(resolved, basestring):
if not isinstance(resolved, six.string_types):
raise TypeError(_('"%s" argument must be a string') % self.fn_name)
return resolved
@ -495,10 +496,10 @@ class MemberListToMap(function.Function):
'''
raise TypeError(_('Wrong Arguments try: "%s"') % correct)
if not isinstance(self._keyname, basestring):
if not isinstance(self._keyname, six.string_types):
raise TypeError(_('%s Key Name must be a string') % self.fn_name)
if not isinstance(self._valuename, basestring):
if not isinstance(self._valuename, six.string_types):
raise TypeError(_('%s Value Name must be a string') % self.fn_name)
def result(self):
@ -508,7 +509,7 @@ class MemberListToMap(function.Function):
raise TypeError(_('Member list must be a list'))
def item(s):
if not isinstance(s, basestring):
if not isinstance(s, six.string_types):
raise TypeError(_("Member list items must be strings"))
return s.split('=', 1)

View File

@ -94,7 +94,9 @@ class CfnTemplate(template.Template):
else:
return default
resource_type = get_check_type(RES_TYPE, basestring, 'string')
resource_type = get_check_type(RES_TYPE,
six.string_types,
'string')
if resource_type is None:
args = {'name': name, 'type_key': RES_TYPE}
msg = _('Resource %(name)s is missing "%(type_key)s"') % args
@ -114,11 +116,11 @@ class CfnTemplate(template.Template):
collections.Sequence,
'list or string',
default=[])
if isinstance(depends, basestring):
if isinstance(depends, six.string_types):
depends = [depends]
deletion_policy = get_check_type(RES_DELETION_POLICY,
basestring,
six.string_types,
'string')
update_policy = get_check_type(RES_UPDATE_POLICY,
@ -127,7 +129,7 @@ class CfnTemplate(template.Template):
'object')
description = get_check_type(RES_DESCRIPTION,
basestring,
six.string_types,
'string',
default='')

View File

@ -438,7 +438,7 @@ class AllowedValues(Constraint):
def __init__(self, allowed, description=None):
super(AllowedValues, self).__init__(description)
if (not isinstance(allowed, collections.Sequence) or
isinstance(allowed, basestring)):
isinstance(allowed, six.string_types)):
raise exception.InvalidSchemaError(
message=_('AllowedValues must be a list'))
self.allowed = tuple(allowed)
@ -483,7 +483,7 @@ class AllowedPattern(Constraint):
def __init__(self, pattern, description=None):
super(AllowedPattern, self).__init__(description)
if not isinstance(pattern, basestring):
if not isinstance(pattern, six.string_types):
raise exception.InvalidSchemaError(
message=_('AllowedPattern must be a string'))
self.pattern = pattern

View File

@ -47,7 +47,7 @@ class ResourceInfo(object):
if name.endswith(('.yaml', '.template')):
# a template url for the resource "Type"
return TemplateResourceInfo(registry, path, value)
elif not isinstance(value, basestring):
elif not isinstance(value, six.string_types):
return ClassResourceInfo(registry, path, value)
elif value.endswith(('.yaml', '.template')):
# a registered template
@ -304,7 +304,7 @@ class ResourceRegistry(object):
msg = _('Non-empty resource type is required '
'for resource "%s"') % resource_name
raise exception.StackValidationFailed(message=msg)
elif not isinstance(resource_type, basestring):
elif not isinstance(resource_type, six.string_types):
msg = _('Resource "%s" type is not a string') % resource_name
raise exception.StackValidationFailed(message=msg)

View File

@ -118,7 +118,7 @@ def resolve(snippet):
if isinstance(snippet, collections.Mapping):
return dict((k, resolve(v)) for k, v in snippet.items())
elif (not isinstance(snippet, basestring) and
elif (not isinstance(snippet, six.string_types) and
isinstance(snippet, collections.Iterable)):
return [resolve(v) for v in snippet]
@ -131,7 +131,7 @@ def validate(snippet):
elif isinstance(snippet, collections.Mapping):
for v in snippet.values():
validate(v)
elif (not isinstance(snippet, basestring) and
elif (not isinstance(snippet, six.string_types) and
isinstance(snippet, collections.Iterable)):
for v in snippet:
validate(v)
@ -156,7 +156,7 @@ def dependencies(snippet, path=''):
mkpath(key)) for key, value in snippet.items())
return itertools.chain.from_iterable(deps)
elif (not isinstance(snippet, basestring) and
elif (not isinstance(snippet, six.string_types) and
isinstance(snippet, collections.Iterable)):
def mkpath(idx):
return ''.join([path, '[%d]' % idx])

View File

@ -12,6 +12,7 @@
# under the License.
import collections
import six
from heat.common import exception
from heat.common.i18n import _
@ -48,7 +49,7 @@ class GetParam(function.Function):
raise ValueError(_('Function "%s" must have arguments') %
self.fn_name)
if isinstance(args, basestring):
if isinstance(args, six.string_types):
param_name = args
path_components = []
elif isinstance(args, collections.Sequence):
@ -58,7 +59,7 @@ class GetParam(function.Function):
raise TypeError(_('Argument to "%s" must be string or list') %
self.fn_name)
if not isinstance(param_name, basestring):
if not isinstance(param_name, six.string_types):
raise TypeError(_('Parameter name in "%s" must be string') %
self.fn_name)
@ -72,7 +73,7 @@ class GetParam(function.Function):
collections.Sequence)):
raise TypeError(_('"%s" can\'t traverse path') % self.fn_name)
if not isinstance(key, (basestring, int)):
if not isinstance(key, (six.string_types, int)):
raise TypeError(_('Path components in "%s" '
'must be strings') % self.fn_name)
@ -99,7 +100,7 @@ class GetAttThenSelect(cfn_funcs.GetAtt):
def _parse_args(self):
if (not isinstance(self.args, collections.Sequence) or
isinstance(self.args, basestring)):
isinstance(self.args, six.string_types)):
raise TypeError(_('Argument to "%s" must be a list') %
self.fn_name)
@ -202,7 +203,7 @@ class GetFile(function.Function):
def result(self):
args = function.resolve(self.args)
if not (isinstance(args, basestring)):
if not (isinstance(args, six.string_types)):
raise TypeError(_('Argument to "%s" must be a string') %
self.fn_name)

View File

@ -195,7 +195,9 @@ class HOTemplate20130523(template.Template):
else:
return default
resource_type = get_check_type(RES_TYPE, basestring, 'string')
resource_type = get_check_type(RES_TYPE,
six.string_types,
'string')
if resource_type is None:
args = {'name': name, 'type_key': RES_TYPE}
msg = _('Resource %(name)s is missing "%(type_key)s"') % args
@ -215,11 +217,11 @@ class HOTemplate20130523(template.Template):
collections.Sequence,
'list or string',
default=[])
if isinstance(depends, basestring):
if isinstance(depends, six.string_types):
depends = [depends]
deletion_policy = get_check_type(RES_DELETION_POLICY,
basestring,
six.string_types,
'string')
update_policy = get_check_type(RES_UPDATE_POLICY,

View File

@ -372,7 +372,7 @@ class JsonParam(Parameter):
def parse(self, value):
try:
val = value
if not isinstance(val, basestring):
if not isinstance(val, six.string_types):
val = json.dumps(val)
if val:
return json.loads(val)

View File

@ -75,7 +75,7 @@ class PluginMapping(object):
passed to the mapping functions.
'''
if isinstance(names, basestring):
if isinstance(names, six.string_types):
names = [names]
self.names = ['%s_mapping' % name for name in names]

View File

@ -243,7 +243,7 @@ class Property(object):
def _get_string(self, value):
if value is None:
value = self.has_default() and self.default() or ''
if not isinstance(value, basestring):
if not isinstance(value, six.string_types):
if isinstance(value, (bool, int)):
value = six.text_type(value)
else:
@ -278,7 +278,7 @@ class Property(object):
if value is None:
value = self.has_default() and self.default() or []
if (not isinstance(value, collections.Sequence) or
isinstance(value, basestring)):
isinstance(value, six.string_types)):
raise TypeError(_('"%s" is not a list') % repr(value))
return [v[1] for v in self._get_children(enumerate(value),

View File

@ -1022,7 +1022,7 @@ class Resource(object):
def get_string_details():
if details is None:
return 'No signal details provided'
if isinstance(details, basestring):
if isinstance(details, six.string_types):
return details
if isinstance(details, dict):
if all(k in details for k in ('previous', 'current',

View File

@ -473,7 +473,7 @@ class Instance(resource.Resource):
unsorted_nics = []
for entry in network_interfaces:
nic = (entry
if not isinstance(entry, basestring)
if not isinstance(entry, six.string_types)
else {'NetworkInterfaceId': entry,
'DeviceIndex': len(unsorted_nics)})
unsorted_nics.append(nic)

View File

@ -307,7 +307,7 @@ class ResourceGroup(stack_resource.StackResource):
def _handle_repl_val(self, res_name, val):
repl_var = self.properties[self.INDEX_VAR]
recurse = lambda x: self._handle_repl_val(res_name, x)
if isinstance(val, basestring):
if isinstance(val, six.string_types):
return val.replace(repl_var, res_name)
elif isinstance(val, collections.Mapping):
return dict(zip(val, map(recurse, val.values())))

View File

@ -131,10 +131,10 @@ class StructuredDeployment(sd.SoftwareDeployment):
if len(snippet) == 1:
fn_name, args = next(six.iteritems(snippet))
if fn_name == input_key:
if isinstance(args, basestring):
if isinstance(args, six.string_types):
return inputs.get(args)
return dict((k, parse(v)) for k, v in six.iteritems(snippet))
elif (not isinstance(snippet, basestring) and
elif (not isinstance(snippet, six.string_types) and
isinstance(snippet, collections.Iterable)):
return [parse(v) for v in snippet]
else:

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.common.i18n import _
from heat.common.i18n import _LI
@ -77,7 +79,7 @@ class User(stack_user.StackUser):
# If a non-string (e.g embedded IAM dict policy) is passed, we
# ignore the policy (don't reject it because we previously ignored
# and we don't want to break templates which previously worked
if not isinstance(policy, basestring):
if not isinstance(policy, six.string_types):
LOG.debug("Ignoring policy %s, must be string "
"resource name" % policy)
continue
@ -116,7 +118,7 @@ class User(stack_user.StackUser):
def access_allowed(self, resource_name):
policies = (self.properties[self.POLICIES] or [])
for policy in policies:
if not isinstance(policy, basestring):
if not isinstance(policy, six.string_types):
LOG.debug("Ignoring policy %s, must be string "
"resource name" % policy)
continue

View File

@ -14,6 +14,7 @@ import collections
import copy
import itertools
import operator
import six
from heat.common import exception
@ -66,7 +67,7 @@ class ResourceDefinitionCore(object):
self._hash = hash(self.resource_type)
self._rendering = None
assert isinstance(description, basestring)
assert isinstance(description, six.string_types)
if properties is not None:
assert isinstance(properties, (collections.Mapping,
@ -80,7 +81,7 @@ class ResourceDefinitionCore(object):
assert isinstance(depends, (collections.Sequence,
function.Function))
assert not isinstance(depends, basestring)
assert not isinstance(depends, six.string_types)
self._hash ^= _hash_data(depends)
if deletion_policy is not None:
@ -392,7 +393,7 @@ def _hash_data(data):
if isinstance(data, function.Function):
data = copy.deepcopy(data)
if not isinstance(data, basestring):
if not isinstance(data, six.string_types):
if isinstance(data, collections.Sequence):
return hash(tuple(_hash_data(d) for d in data))

View File

@ -34,7 +34,7 @@ _template_classes = None
def get_version(template_data, available_versions):
version_keys = set(key for key, version in available_versions)
candidate_keys = set(k for k, v in six.iteritems(template_data) if
isinstance(v, basestring))
isinstance(v, six.string_types))
keys_present = version_keys & candidate_keys
@ -211,7 +211,7 @@ def parse(functions, stack, snippet):
if Func is not None:
return Func(stack, fn_name, recurse(args))
return dict((k, recurse(v)) for k, v in six.iteritems(snippet))
elif (not isinstance(snippet, basestring) and
elif (not isinstance(snippet, six.string_types) and
isinstance(snippet, collections.Iterable)):
return [recurse(v) for v in snippet]
else:

View File

@ -387,15 +387,15 @@ class SchemaTest(testtools.TestCase):
'''Test Schema.to_schema_type method for type String.'''
schema = constraints.Schema('String')
res = schema.to_schema_type('one')
self.assertIsInstance(res, basestring)
self.assertIsInstance(res, six.string_types)
res = schema.to_schema_type('1')
self.assertIsInstance(res, basestring)
self.assertIsInstance(res, six.string_types)
res = schema.to_schema_type(1)
self.assertIsInstance(res, basestring)
self.assertIsInstance(res, six.string_types)
res = schema.to_schema_type(True)
self.assertIsInstance(res, basestring)
self.assertIsInstance(res, six.string_types)
res = schema.to_schema_type(None)
self.assertIsInstance(res, basestring)
self.assertIsInstance(res, six.string_types)
def test_to_schema_type_boolean(self):
'''Test Schema.to_schema_type method for type Boolean.'''

View File

@ -13,6 +13,7 @@
import copy
import re
import six
import mock
import mox
@ -223,7 +224,7 @@ class LoadBalancerTest(common.HeatTestCase):
def assertRegexpMatches(self, text, expected_regexp, msg=None):
"""Fail the test unless the text matches the regular expression."""
if isinstance(expected_regexp, basestring):
if isinstance(expected_regexp, six.string_types):
expected_regexp = re.compile(expected_regexp)
if not expected_regexp.search(text):
msg = msg or "Regexp didn't match"

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.tests import common
from heat.common import exception
@ -62,7 +64,7 @@ class ResourceDefinitionTest(common.HeatTestCase):
rd = self.make_me_one_with_everything()
metadata = rd.metadata()
self.assertEqual({'Baz': 'quux'}, metadata)
self.assertIsInstance(metadata['Baz'], basestring)
self.assertIsInstance(metadata['Baz'], six.string_types)
def test_dependencies_default(self):
rd = rsrc_defn.ResourceDefinition('rsrc', 'SomeType')