Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protocol: follow strict datatype in TJsonProtocol, fixes #71 #85

Merged
merged 4 commits into from
Sep 24, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 37 additions & 33 deletions thriftpy2/protocol/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,57 @@
import json
import struct

from thriftpy2._compat import u
from thriftpy2.thrift import TType

from .exc import TProtocolException

INTEGER = (TType.BYTE, TType.I16, TType.I32, TType.I64)
FLOAT = (TType.DOUBLE,)

VERSION = 1


def json_value(ttype, val, spec=None):
if ttype in INTEGER or ttype in FLOAT or ttype == TType.STRING:
return val

if ttype == TType.BOOL:
return True if val else False

if ttype == TType.STRUCT:
return struct_to_json(val)

if ttype in (TType.SET, TType.LIST):
return list_to_json(val, spec)

if ttype == TType.MAP:
return map_to_json(val, spec)
TTYPE_TO_JSONFUNC_MAP = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethe Do you think with there is negative performance impact if we move to map from branching?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is not much impact here.

TType.BYTE: (int, (val, )),
TType.I16: (int, (val, )),
TType.I32: (int, (val, )),
TType.I64: (int, (val, )),
TType.DOUBLE: (float, (val, )),
TType.STRING: (u, (val, )),
TType.BOOL: (bool, (val, )),
TType.STRUCT: (struct_to_json, (val, )),
TType.SET: (list_to_json, (val, spec)),
TType.LIST: (list_to_json, (val, spec)),
TType.MAP: (map_to_json, (val, spec)),
}
func, args = TTYPE_TO_JSONFUNC_MAP.get(ttype)
if func:
return func(*args)


def obj_value(ttype, val, spec=None):
if ttype in INTEGER:
return int(val)

if ttype in FLOAT:
return float(val)

if ttype in (TType.STRING, TType.BOOL):
return val

TTYPE_TO_OBJFUNC_MAP = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

TType.BYTE: (int, (val, )),
TType.I16: (int, (val, )),
TType.I32: (int, (val, )),
TType.I64: (int, (val, )),
TType.DOUBLE: (float, (val, )),
TType.STRING: (u, (val, )),
TType.BOOL: (bool, (val, )),
TType.SET: (list_to_obj, (val, spec)),
TType.LIST: (list_to_obj, (val, spec)),
TType.MAP: (map_to_obj, (val, spec)),
}
func, args = TTYPE_TO_OBJFUNC_MAP.get(ttype)
if func:
return func(*args)

# Special case: since `spec` needs to get called if TType is STRUCT,
# if we initialize inside `TTYPE_TO_OBJFUNC_MAP` it will get called
# everytime the function gets called and incur in exception as
# `TypeError: 'NoneType' object is not callable`.
if ttype == TType.STRUCT:
return struct_to_obj(val, spec())
iamsudip marked this conversation as resolved.
Show resolved Hide resolved

if ttype in (TType.SET, TType.LIST):
return list_to_obj(val, spec)

if ttype == TType.MAP:
return map_to_obj(val, spec)


def map_to_obj(val, spec):
res = {}
if isinstance(spec[0], int):
Expand Down