Skip to content

Instantly share code, notes, and snippets.

@zhongwm
Created March 29, 2020 05:09
Show Gist options
  • Save zhongwm/0648ad710225e58d23ebd1fe33a6c1fc to your computer and use it in GitHub Desktop.
Save zhongwm/0648ad710225e58d23ebd1fe33a6c1fc to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8
from __future__ import (print_function, )
import six
from six import ensure_binary, text_type, ensure_text
import json
__all__ = ['json_str_or_bytes_repr_as_safe_text']
def json_str_or_bytes_repr_as_safe_text(v):
# type: (unicode) -> unicode
"""Stackstorm action pack - python 2&3 notes.
Either installed as python2 or python3 pack, if action result is a ``dict``, then all key value
should of type str(raw bytes string as of python2, unicode string as of python3, but both case
typed as str, in simple words, python3: str type, python2: str type).
But awkward situation is string with CJK characters of action result dict values, when action
was installed in python3 pack for some reason st2 engine didn't treat them as utf-8 but as ascii
therefore did'nt get encoded to python3 str(unicode) , as a consequence, the action result dict
just got transformed to string or such action is taken failed. This situation makes it really
annoying implementing python 2&3 compatible action with CJK charsets.
This function accept a unicode object representing repr(str object) or json string. and return
it as a python2 str object or python3 object.
_debug(u'你好'.encode('utf-8')) # <class 'str'>你好
_debug(json_str_or_bytes_repr_as_safe_text('你好')) # <class 'str'>你好
_debug(json_str_or_bytes_repr_as_safe_text(u'你好'.encode('utf-8'))) # <class 'str'>你好
_debug(json_str_or_bytes_repr_as_safe_text(json.dumps(u'你好'))) # <class 'str'>你好
_debug(json_str_or_bytes_repr_as_safe_text(json.dumps(u'你好')[1:-1])) # <class 'str'>你好
"""
try:
open('a', 'wb')
bv = ensure_binary(v, 'utf-8')
if not v:
return ''
if bv[:2] == b'b\\':
eval('tv = {}'.format(v))
return ensure_text(tv, 'utf-8')
elif b'\\u' in bv:
# is json
# ensure wrapped in double quotes
if (chr(bv[0]) if six.PY3 else bv[0]) != chr(34):
bv = b'"' + bv + b'"'
loaded_json = json.loads(bv)
if type(loaded_json) != text_type:
return v
else:
return loaded_json
else:
return ensure_text(v)
except:
return v
def _debug(x):
print(type(x), x)
if __name__ == '__main__':
_debug(u'你好'.encode('utf-8'))
_debug(json_str_or_bytes_repr_as_safe_text('你好'))
_debug(json_str_or_bytes_repr_as_safe_text(u'你好'.encode('utf-8')))
_debug(json_str_or_bytes_repr_as_safe_text(json.dumps(u'你好')))
_debug(json_str_or_bytes_repr_as_safe_text(json.dumps(u'你好')[1:-1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment