[Kimchi-devel] [PATCH] [Wok] Isolate string utils in order to avoid cyclic import

Daniel Henrique Barboza dhbarboza82 at gmail.com
Thu Aug 4 18:53:30 UTC 2016


Just saw patches in the Ginger ML that are supposed to be applied
together with this one

I'll retest with all 3 patches.

On 08/04/2016 03:40 PM, Daniel Henrique Barboza wrote:
> This patch breaks Kimchi and Ginger because you moved functions
> from wok.utils and those plug-ins were referencing them:
>
> Failed to import plugin plugins.kimchi.Kimchi, error: Class 
> plugins.kimchi.Kimchi can not be imported, error: cannot import name 
> encode_value
> Failed to import plugin plugins.ginger.Ginger, error: Class 
> plugins.ginger.Ginger can not be imported, error: cannot import name 
> encode_value
>
> The unit tests of all 3 plug-ins breaks too.
>
> On 08/04/2016 02:42 PM, Lucio Correia wrote:
>> These functions are basic ones but were not able to be
>> imported from message.py since other functions in utils
>> were causing cyclic imports. Isolate it to avoid that
>> problem.
>>
>> Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
>> ---
>>   src/wok/control/base.py |   3 +-
>>   src/wok/reqlogger.py    |   3 +-
>>   src/wok/stringutils.py  | 154 
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>   src/wok/utils.py        | 136 
>> +-----------------------------------------
>>   4 files changed, 159 insertions(+), 137 deletions(-)
>>   create mode 100644 src/wok/stringutils.py
>>
>> IMPORTANT: apply this along with ginger and gingerbase patches.
>>
>> diff --git a/src/wok/control/base.py b/src/wok/control/base.py
>> index 69541b1..6dfc977 100644
>> --- a/src/wok/control/base.py
>> +++ b/src/wok/control/base.py
>> @@ -33,7 +33,8 @@ from wok.control.utils import validate_params
>>   from wok.exception import InvalidOperation, UnauthorizedError, 
>> WokException
>>   from wok.message import WokMessage
>>   from wok.reqlogger import RequestRecord
>> -from wok.utils import get_plugin_from_request, utf8_dict, wok_log, 
>> encode_value
>> +from wok.stringutils import encode_value, utf8_dict
>> +from wok.utils import get_plugin_from_request, wok_log
>>       # Default request log messages
>> diff --git a/src/wok/reqlogger.py b/src/wok/reqlogger.py
>> index 8fadbcf..fd02382 100644
>> --- a/src/wok/reqlogger.py
>> +++ b/src/wok/reqlogger.py
>> @@ -30,7 +30,8 @@ from tempfile import NamedTemporaryFile
>>     from wok.config import config, get_log_download_path
>>   from wok.exception import InvalidParameter, OperationFailed
>> -from wok.utils import ascii_dict, remove_old_files
>> +from wok.stringutils import ascii_dict
>> +from wok.utils import remove_old_files
>>       # Log search setup
>> diff --git a/src/wok/stringutils.py b/src/wok/stringutils.py
>> new file mode 100644
>> index 0000000..8f0160b
>> --- /dev/null
>> +++ b/src/wok/stringutils.py
>> @@ -0,0 +1,154 @@
>> +#
>> +# Project Wok
>> +#
>> +# Copyright IBM Corp, 2016
>> +#
>> +# This library is free software; you can redistribute it and/or
>> +# modify it under the terms of the GNU Lesser General Public
>> +# License as published by the Free Software Foundation; either
>> +# version 2.1 of the License, or (at your option) any later version.
>> +#
>> +# This library is distributed in the hope that it will be useful,
>> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> +# Lesser General Public License for more details.
>> +#
>> +# You should have received a copy of the GNU Lesser General Public
>> +# License along with this library; if not, write to the Free Software
>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
>> 02110-1301 USA
>> +
>> +import copy
>> +import locale
>> +
>> +
>> +def ascii_dict(base, overlay=None):
>> +    result = copy.deepcopy(base)
>> +    result.update(overlay or {})
>> +
>> +    for key, value in result.iteritems():
>> +        if isinstance(value, unicode):
>> +            result[key] = str(value.decode('utf-8'))
>> +
>> +    return result
>> +
>> +
>> +def utf8_dict(base, overlay=None):
>> +    result = copy.deepcopy(base)
>> +    result.update(overlay or {})
>> +
>> +    for key, value in result.iteritems():
>> +        if isinstance(value, unicode):
>> +            result[key] = value.encode('utf-8')
>> +
>> +    return result
>> +
>> +
>> +def encode_value(val):
>> +    """
>> +        Convert the value to string.
>> +        If its unicode, use encode otherwise str.
>> +    """
>> +    if isinstance(val, unicode):
>> +        return val.encode('utf-8')
>> +    return str(val)
>> +
>> +
>> +def decode_value(val):
>> +    """
>> +        Converts value to unicode,
>> +        if its not an instance of unicode.
>> +        For doing so convert the val to string,
>> +        if its not instance of basestring.
>> +    """
>> +    if not isinstance(val, basestring):
>> +        val = str(val)
>> +    if not isinstance(val, unicode):
>> +        val = val.decode('utf-8')
>> +    return val
>> +
>> +
>> +def formatMeasurement(number, settings):
>> +    '''
>> +    Refer to "Units of information" (
>> +    http://en.wikipedia.org/wiki/Units_of_information
>> +    ) for more information about measurement units.
>> +
>> +   @param number The number to be normalized.
>> +   @param settings
>> +        base Measurement base, accepts 2 or 10. defaults to 2.
>> +        unit The unit of the measurement, e.g., B, Bytes/s, bps, etc.
>> +        fixed The number of digits after the decimal point.
>> +        locale The locale for formating the number if not passed
>> +        format is done as per current locale.
>> +   @returns [object]
>> +       v The number part of the measurement.
>> +       s The suffix part of the measurement including multiple and 
>> unit.
>> +          e.g., kB/s means 1000B/s, KiB/s for 1024B/s.
>> +    '''
>> +    unitBaseMapping = {2: [{"us": 'Ki', "v": 1024},
>> +                           {"us": 'Mi', "v": 1048576},
>> +                           {"us": 'Gi', "v": 1073741824},
>> +                           {"us": 'Ti', "v": 1099511627776},
>> +                           {"us": 'Pi', "v": 1125899906842624}],
>> +                       10: [{"us": 'k', "v": 1000},
>> +                            {"us": 'M', "v": 1000000},
>> +                            {"us": 'G', "v": 1000000000},
>> +                            {"us": 'T', "v": 1000000000000},
>> +                            {"us": 'P', "v": 1000000000000000}]}
>> +
>> +    if(not number):
>> +        return number
>> +    settings = settings or {}
>> +    unit = settings['unit'] if 'unit' in settings else 'B'
>> +    base = settings['base'] if 'base' in settings else 2
>> +
>> +    new_locale = settings['locale'] if 'locale' in settings else ''
>> +
>> +    if(base != 2 and base != 10):
>> +        return encode_value(number) + unit
>> +
>> +    fixed = settings['fixed']
>> +
>> +    unitMapping = unitBaseMapping[base]
>> +    for mapping in reversed(unitMapping):
>> +        suffix = mapping['us']
>> +        startingValue = mapping['v']
>> +        if(number < startingValue):
>> +            continue
>> +
>> +        formatted = float(number) / startingValue
>> +        formatted = formatNumber(formatted, fixed, new_locale)
>> +        return formatted + suffix + unit
>> +
>> +    formatted_number = formatNumber(number, fixed, new_locale)
>> +    return formatted_number+unit
>> +
>> +
>> +def formatNumber(number, fixed, format_locale):
>> +    '''
>> +    Format the number based on format_locale passed.
>> +    '''
>> +
>> +    # get the current locale
>> +    current_locale = locale.getlocale()
>> +    new_locale = ''
>> +    # set passed locale and set new_locale to same value.
>> +    if format_locale:
>> +        new_locale = locale.setlocale(locale.LC_ALL, format_locale)
>> +
>> +    # Based on type of number use the correct formatter
>> +    if isinstance(number, float):
>> +        if fixed:
>> +            formatted = locale.format('%' + '.%df' % fixed, number, 
>> True)
>> +        else:
>> +            formatted = locale.format('%f', number, True)
>> +    if isinstance(number, int):
>> +        formatted = locale.format('%d', number, True)
>> +    # After formatting is done as per locale, reset the locale if 
>> changed.
>> +    if (new_locale and not current_locale[0] and not 
>> current_locale[1]):
>> +        locale.setlocale(locale.LC_ALL, 'C')
>> +    elif (new_locale):
>> +        locale.setlocale(locale.LC_ALL, current_locale[0] + "." +
>> +                         current_locale[1])
>> +
>> +    return formatted
>> diff --git a/src/wok/utils.py b/src/wok/utils.py
>> index c78a77a..d6bdf0a 100644
>> --- a/src/wok/utils.py
>> +++ b/src/wok/utils.py
>> @@ -21,7 +21,6 @@
>>   #
>>     import cherrypy
>> -import copy
>>   import glob
>>   import grp
>>   import os
>> @@ -33,7 +32,6 @@ import subprocess
>>   import sys
>>   import traceback
>>   import xml.etree.ElementTree as ET
>> -import locale
>>     from cherrypy.lib.reprconf import Parser
>>   from datetime import datetime, timedelta
>> @@ -43,6 +41,7 @@ from threading import Timer
>>   from wok.asynctask import AsyncTask
>>   from wok.config import paths, PluginPaths
>>   from wok.exception import InvalidParameter, TimeoutExpired
>> +from wok.stringutils import decode_value
>>       wok_log = cherrypy.log.error_log
>> @@ -137,28 +136,6 @@ def get_plugin_from_request():
>>       return 'wok'
>>     -def ascii_dict(base, overlay=None):
>> -    result = copy.deepcopy(base)
>> -    result.update(overlay or {})
>> -
>> -    for key, value in result.iteritems():
>> -        if isinstance(value, unicode):
>> -            result[key] = str(value.decode('utf-8'))
>> -
>> -    return result
>> -
>> -
>> -def utf8_dict(base, overlay=None):
>> -    result = copy.deepcopy(base)
>> -    result.update(overlay or {})
>> -
>> -    for key, value in result.iteritems():
>> -        if isinstance(value, unicode):
>> -            result[key] = value.encode('utf-8')
>> -
>> -    return result
>> -
>> -
>>   def import_class(class_path):
>>       module_name, class_name = class_path.rsplit('.', 1)
>>       try:
>> @@ -610,114 +587,3 @@ def upgrade_objectstore_schema(objstore=None, 
>> field=None):
>>           wok_log.error("Cannot upgrade objectstore schema: %s" % 
>> e.args[0])
>>           return False
>>       return True
>> -
>> -
>> -def encode_value(val):
>> -    """
>> -        Convert the value to string.
>> -        If its unicode, use encode otherwise str.
>> -    """
>> -    if isinstance(val, unicode):
>> -        return val.encode('utf-8')
>> -    return str(val)
>> -
>> -
>> -def decode_value(val):
>> -    """
>> -        Converts value to unicode,
>> -        if its not an instance of unicode.
>> -        For doing so convert the val to string,
>> -        if its not instance of basestring.
>> -    """
>> -    if not isinstance(val, basestring):
>> -        val = str(val)
>> -    if not isinstance(val, unicode):
>> -        val = val.decode('utf-8')
>> -    return val
>> -
>> -
>> -def formatMeasurement(number, settings):
>> -    '''
>> -    Refer to "Units of information" (
>> -    http://en.wikipedia.org/wiki/Units_of_information
>> -    ) for more information about measurement units.
>> -
>> -   @param number The number to be normalized.
>> -   @param settings
>> -        base Measurement base, accepts 2 or 10. defaults to 2.
>> -        unit The unit of the measurement, e.g., B, Bytes/s, bps, etc.
>> -        fixed The number of digits after the decimal point.
>> -        locale The locale for formating the number if not passed
>> -        format is done as per current locale.
>> -   @returns [object]
>> -       v The number part of the measurement.
>> -       s The suffix part of the measurement including multiple and 
>> unit.
>> -          e.g., kB/s means 1000B/s, KiB/s for 1024B/s.
>> -    '''
>> -    unitBaseMapping = {2: [{"us": 'Ki', "v": 1024},
>> -                           {"us": 'Mi', "v": 1048576},
>> -                           {"us": 'Gi', "v": 1073741824},
>> -                           {"us": 'Ti', "v": 1099511627776},
>> -                           {"us": 'Pi', "v": 1125899906842624}],
>> -                       10: [{"us": 'k', "v": 1000},
>> -                            {"us": 'M', "v": 1000000},
>> -                            {"us": 'G', "v": 1000000000},
>> -                            {"us": 'T', "v": 1000000000000},
>> -                            {"us": 'P', "v": 1000000000000000}]}
>> -
>> -    if(not number):
>> -        return number
>> -    settings = settings or {}
>> -    unit = settings['unit'] if 'unit' in settings else 'B'
>> -    base = settings['base'] if 'base' in settings else 2
>> -
>> -    new_locale = settings['locale'] if 'locale' in settings else ''
>> -
>> -    if(base != 2 and base != 10):
>> -        return encode_value(number) + unit
>> -
>> -    fixed = settings['fixed']
>> -
>> -    unitMapping = unitBaseMapping[base]
>> -    for mapping in reversed(unitMapping):
>> -        suffix = mapping['us']
>> -        startingValue = mapping['v']
>> -        if(number < startingValue):
>> -            continue
>> -
>> -        formatted = float(number) / startingValue
>> -        formatted = formatNumber(formatted, fixed, new_locale)
>> -        return formatted + suffix + unit
>> -
>> -    formatted_number = formatNumber(number, fixed, new_locale)
>> -    return formatted_number+unit
>> -
>> -
>> -def formatNumber(number, fixed, format_locale):
>> -    '''
>> -    Format the number based on format_locale passed.
>> -    '''
>> -
>> -    # get the current locale
>> -    current_locale = locale.getlocale()
>> -    new_locale = ''
>> -    # set passed locale and set new_locale to same value.
>> -    if format_locale:
>> -        new_locale = locale.setlocale(locale.LC_ALL, format_locale)
>> -
>> -    # Based on type of number use the correct formatter
>> -    if isinstance(number, float):
>> -        if fixed:
>> -            formatted = locale.format('%' + '.%df' % fixed, number, 
>> True)
>> -        else:
>> -            formatted = locale.format('%f', number, True)
>> -    if isinstance(number, int):
>> -        formatted = locale.format('%d', number, True)
>> -    # After formatting is done as per locale, reset the locale if 
>> changed.
>> -    if (new_locale and not current_locale[0] and not 
>> current_locale[1]):
>> -        locale.setlocale(locale.LC_ALL, 'C')
>> -    elif (new_locale):
>> -        locale.setlocale(locale.LC_ALL, current_locale[0] + "." +
>> -                         current_locale[1])
>> -
>> -    return formatted
>




More information about the Kimchi-devel mailing list