45 lines
1.1 KiB
Python
45 lines
1.1 KiB
Python
|
from collections import OrderedDict
|
||
|
|
||
|
import six
|
||
|
|
||
|
|
||
|
def _attr_key(attr):
|
||
|
"""Returns appropriate key for sorting attribute names
|
||
|
|
||
|
Attribute names are a tuple of ``(namespace, name)`` where namespace can be
|
||
|
``None`` or a string. These can't be compared in Python 3, so we conver the
|
||
|
``None`` to an empty string.
|
||
|
|
||
|
"""
|
||
|
key = (attr[0][0] or ''), attr[0][1]
|
||
|
return key
|
||
|
|
||
|
|
||
|
def alphabetize_attributes(attrs):
|
||
|
"""Takes a dict of attributes (or None) and returns them alphabetized"""
|
||
|
if not attrs:
|
||
|
return attrs
|
||
|
|
||
|
return OrderedDict(
|
||
|
[(k, v) for k, v in sorted(attrs.items(), key=_attr_key)]
|
||
|
)
|
||
|
|
||
|
|
||
|
def force_unicode(text):
|
||
|
"""Takes a text (Python 2: str/unicode; Python 3: unicode) and converts to unicode
|
||
|
|
||
|
:arg str/unicode text: the text in question
|
||
|
|
||
|
:returns: text as unicode
|
||
|
|
||
|
:raises UnicodeDecodeError: if the text was a Python 2 str and isn't in
|
||
|
utf-8
|
||
|
|
||
|
"""
|
||
|
# If it's already unicode, then return it
|
||
|
if isinstance(text, six.text_type):
|
||
|
return text
|
||
|
|
||
|
# If not, convert it
|
||
|
return six.text_type(text, 'utf-8', 'strict')
|