Import strutils from oslo, and convert to it.

The only change of behaviour here (according to the former glance
unit tests) is that 'T' now means True not False. I suspect that's
ok.

Change-Id: Icf98f913a3f78a1fe2f38a82a25a071c2da03739
This commit is contained in:
Michael Still 2013-05-17 10:05:14 +10:00
parent f09c52c8b0
commit 9356ea634d
7 changed files with 157 additions and 39 deletions

View File

@ -44,6 +44,7 @@ from glance.common import utils
from glance.common import wsgi
from glance import notifier
import glance.openstack.common.log as logging
from glance.openstack.common import strutils
import glance.registry.client.v1.api as registry
from glance.store import (get_from_backend,
get_size_from_backend,
@ -634,7 +635,7 @@ class Controller(controller.BaseController):
# properties NOT to be purged. However we also disable purging of
# properties if an image file is being uploaded...
purge_props = req.headers.get('x-glance-registry-purge-props', True)
purge_props = (utils.bool_from_string(purge_props) and
purge_props = (strutils.bool_from_string(purge_props) and
image_data is None)
if image_data is not None and orig_status != 'queued':

View File

@ -41,6 +41,7 @@ from webob import exc
from glance.common import exception
import glance.openstack.common.log as logging
from glance.openstack.common import strutils
CONF = cfg.CONF
@ -245,22 +246,10 @@ def get_image_meta_from_headers(response):
raise exception.Invalid
for key in ('is_public', 'deleted', 'protected'):
if key in result:
result[key] = bool_from_string(result[key])
result[key] = strutils.bool_from_string(result[key])
return result
def bool_from_string(subject):
"""Interpret a string as a boolean-like value."""
if isinstance(subject, bool):
return subject
elif isinstance(subject, int):
return subject == 1
if hasattr(subject, 'startswith'): # str or unicode...
if subject.strip().lower() in ('true', 'on', '1', 'yes', 'y'):
return True
return False
def safe_mkdirs(path):
try:
os.makedirs(path)

View File

@ -0,0 +1,150 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011 OpenStack Foundation.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
System-level utilities and helper functions.
"""
import sys
from glance.openstack.common.gettextutils import _
TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
def int_from_bool_as_string(subject):
"""
Interpret a string as a boolean and return either 1 or 0.
Any string value in:
('True', 'true', 'On', 'on', '1')
is interpreted as a boolean True.
Useful for JSON-decoded stuff and config file parsing
"""
return bool_from_string(subject) and 1 or 0
def bool_from_string(subject, strict=False):
"""
Interpret a string as a boolean.
A case-insensitive match is performed such that strings matching 't',
'true', 'on', 'y', 'yes', or '1' are considered True and, when
`strict=False`, anything else is considered False.
Useful for JSON-decoded stuff and config file parsing.
If `strict=True`, unrecognized values, including None, will raise a
ValueError which is useful when parsing values passed in from an API call.
Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
"""
if not isinstance(subject, basestring):
subject = str(subject)
lowered = subject.strip().lower()
if lowered in TRUE_STRINGS:
return True
elif lowered in FALSE_STRINGS:
return False
elif strict:
acceptable = ', '.join(
"'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
msg = _("Unrecognized value '%(val)s', acceptable values are:"
" %(acceptable)s") % {'val': subject,
'acceptable': acceptable}
raise ValueError(msg)
else:
return False
def safe_decode(text, incoming=None, errors='strict'):
"""
Decodes incoming str using `incoming` if they're
not already unicode.
:param incoming: Text's current encoding
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: text or a unicode `incoming` encoded
representation of it.
:raises TypeError: If text is not an isntance of basestring
"""
if not isinstance(text, basestring):
raise TypeError("%s can't be decoded" % type(text))
if isinstance(text, unicode):
return text
if not incoming:
incoming = (sys.stdin.encoding or
sys.getdefaultencoding())
try:
return text.decode(incoming, errors)
except UnicodeDecodeError:
# Note(flaper87) If we get here, it means that
# sys.stdin.encoding / sys.getdefaultencoding
# didn't return a suitable encoding to decode
# text. This happens mostly when global LANG
# var is not set correctly and there's no
# default encoding. In this case, most likely
# python will use ASCII or ANSI encoders as
# default encodings but they won't be capable
# of decoding non-ASCII characters.
#
# Also, UTF-8 is being used since it's an ASCII
# extension.
return text.decode('utf-8', errors)
def safe_encode(text, incoming=None,
encoding='utf-8', errors='strict'):
"""
Encodes incoming str/unicode using `encoding`. If
incoming is not specified, text is expected to
be encoded with current python's default encoding.
(`sys.getdefaultencoding`)
:param incoming: Text's current encoding
:param encoding: Expected encoding for text (Default UTF-8)
:param errors: Errors handling policy. See here for valid
values http://docs.python.org/2/library/codecs.html
:returns: text or a bytestring `encoding` encoded
representation of it.
:raises TypeError: If text is not an isntance of basestring
"""
if not isinstance(text, basestring):
raise TypeError("%s can't be encoded" % type(text))
if not incoming:
incoming = (sys.stdin.encoding or
sys.getdefaultencoding())
if isinstance(text, unicode):
return text.encode(encoding, errors)
elif text and encoding != incoming:
# Decode text before encoding it with `encoding`
text = safe_decode(text, incoming, errors)
return text.encode(encoding, errors)
return text

View File

@ -27,6 +27,7 @@ from glance.common import utils
from glance.common import wsgi
import glance.db
import glance.openstack.common.log as logging
from glance.openstack.common import strutils
from glance.openstack.common import timeutils
from glance.openstack.common import uuidutils
@ -273,7 +274,7 @@ class Controller(object):
deleted = req.params.get('deleted')
if deleted is None:
return None
return utils.bool_from_string(deleted)
return strutils.bool_from_string(deleted)
def show(self, req, id):
"""Return data about the given image id."""

View File

@ -118,13 +118,6 @@ class TestUtils(test_utils.BaseTestCase):
self.assertRaises(exception.ImageSizeLimitExceeded, _consume_all_read)
def test_bool_from_string(self):
actual = utils.bool_from_string('true')
self.assertEqual(True, actual)
actual = utils.bool_from_string(1)
self.assertEqual(True, actual)
def test_get_meta_from_headers(self):
resp = webob.Response()
resp.headers = {"x-image-meta-*": 'test'}

View File

@ -24,23 +24,6 @@ from glance.tests import utils as test_utils
class UtilsTestCase(test_utils.BaseTestCase):
def test_bool_from_string(self):
true_values = ['True', True, 'true', 'TRUE', '1', 1, 'on',
'ON', 'y', 'yes', 'Y', 'YES']
i = 0
for value in true_values:
self.assertTrue(utils.bool_from_string(value),
"Got False for value: %r (%d)" % (value, i))
i = i + 1
false_values = ['False', False, 'false', 'T', 'F', 'FALSE',
'0', 0, 9, 'off', 'OFF', 'no', 'n', 'NO', 'N']
for value in false_values:
self.assertFalse(utils.bool_from_string(value),
"Got True for value: %r" % value)
def test_encryption(self):
# Check that original plaintext and unencrypted ciphertext match
# Check keys of the three allowed lengths

View File

@ -10,6 +10,7 @@ module=log
module=notifier
module=policy
module=setup
module=strutils
module=timeutils
module=uuidutils
module=version