diff --git a/blaze/compatibility.py b/blaze/compatibility.py index bd0939324..dd1e8e9be 100644 --- a/blaze/compatibility.py +++ b/blaze/compatibility.py @@ -4,6 +4,7 @@ from types import MethodType import pandas.util.testing as tm +from toolz import identity PY3 = sys.version_info[0] == 3 PY2 = sys.version_info[0] == 2 @@ -135,3 +136,10 @@ def assert_series_equal(left, right, check_names=True, **kwargs): if check_names: assert left.name == right.name return tm.assert_series_equal(left, right, **kwargs) + + +if PY2: + def u8(cs): + return cs.decode('utf-8') +else: + u8 = identity diff --git a/blaze/server/serialization/json_dumps.py b/blaze/server/serialization/json_dumps.py index af3f88dbc..c66fa2905 100644 --- a/blaze/server/serialization/json_dumps.py +++ b/blaze/server/serialization/json_dumps.py @@ -27,27 +27,27 @@ def json_dumps(dt): if not dt.tzname(): s += u'Z' - return {'__!datetime': s} + return {u'__!datetime': s} @dispatch(frozenset) def json_dumps(ds): - return {'__!frozenset': list(ds)} + return {u'__!frozenset': list(ds)} @dispatch(datetime.timedelta) def json_dumps(ds): - return {'__!timedelta': ds.total_seconds()} + return {u'__!timedelta': ds.total_seconds()} @dispatch(Mono) def json_dumps(m): - return {'__!mono': unicode(m)} + return {u'__!mono': unicode(m)} @dispatch(DataShape) def json_dumps(ds): - return {'__!datashape': unicode(ds)} + return {u'__!datashape': unicode(ds)} @dispatch(object) diff --git a/blaze/server/serialization/json_dumps_trusted.py b/blaze/server/serialization/json_dumps_trusted.py index 39bca9021..f349949b1 100644 --- a/blaze/server/serialization/json_dumps_trusted.py +++ b/blaze/server/serialization/json_dumps_trusted.py @@ -3,6 +3,7 @@ from collections import Callable from blaze.dispatch import dispatch +from blaze.compatibility import u8 from functools import partial from .json_dumps import json_dumps @@ -17,8 +18,8 @@ def json_dumps_trusted(f): # let the server serialize any callable - this is only used for testing # at present - do the error handling when json comes from client so in # object_hook, catch anything that is not pandas_numpy - fcn = ".".join([f.__module__, f.__name__]) - return {'__!callable': fcn} + fcn = u8(".".join([f.__module__, f.__name__])) + return {u'__!callable': fcn} for tps, func in json_dumps.funcs.items(): diff --git a/blaze/server/server.py b/blaze/server/server.py index 59f193a70..14b84b292 100644 --- a/blaze/server/server.py +++ b/blaze/server/server.py @@ -21,11 +21,11 @@ from flask import Blueprint, Flask, Response from flask_cors import cross_origin from werkzeug.http import parse_options_header -from toolz import valmap, compose, identity +from toolz import valmap, compose import blaze from blaze import compute, resource -from blaze.compatibility import ExitStack, PY2 +from blaze.compatibility import ExitStack, u8 from blaze.compute import compute_up from .serialization import json, all_formats from ..interactive import _Data @@ -401,13 +401,6 @@ def shape(): return pprint(discover(_get_data()), width=0) -if PY2: - def _u8(cs): - return cs.decode('utf-8') -else: - _u8 = identity - - def to_tree(expr, names=None): """ Represent Blaze expression with core data structures @@ -466,12 +459,12 @@ def to_tree(expr, names=None): if isinstance(expr, expr_utils._slice): return to_tree(expr.as_slice(), names=names) elif isinstance(expr, _Data): - return to_tree(symbol(_u8(expr._name), expr.dshape), names) + return to_tree(symbol(u8(expr._name), expr.dshape), names) elif isinstance(expr, Expr): - return {u'op': _u8(type(expr).__name__), + return {u'op': u8(type(expr).__name__), u'args': [to_tree(arg, names) for arg in expr._args]} elif isinstance(expr, str): - return _u8(expr) + return u8(expr) else: return expr diff --git a/docs/source/whatsnew/0.11.1.txt b/docs/source/whatsnew/0.11.1.txt index bd05c164b..bf91ace40 100644 --- a/docs/source/whatsnew/0.11.1.txt +++ b/docs/source/whatsnew/0.11.1.txt @@ -41,6 +41,9 @@ Bug Fixes * Fixed a testing regression introduced by the latest pymysql version (:issue:`1571`). +* Fixed unicode conversion issues when using a Python 3 blaze server and a + Python 2 client (:issue:`1572`), (:issue:`1566`). + Miscellaneous ~~~~~~~~~~~~~