diff --git a/bitcoinrpc/authproxy.py b/bitcoinrpc/authproxy.py index 6d84fd3..5896db1 100644 --- a/bitcoinrpc/authproxy.py +++ b/bitcoinrpc/authproxy.py @@ -72,10 +72,22 @@ def __repr__(self): return '<%s \'%s\'>' % (self.__class__.__name__, self) -def EncodeDecimal(o): - if isinstance(o, decimal.Decimal): - return float(round(o, 8)) - raise TypeError(repr(o) + " is not JSON serializable") +class DecimalEncoder(float): + def __init__(self, o): + self.o = o + def __repr__(self): + return str(self.o) + +class JSONEncoderWithDecimalCls(json.JSONEncoder): + def default(self, o): + if isinstance(o, decimal.Decimal): + return DecimalEncoder(o) + return json.JSONEncoder.default(self, o) + +JSONEncoderWithDecimal = JSONEncoderWithDecimalCls() + +def jsondumps(o): + return ''.join(JSONEncoderWithDecimal.iterencode(o)) class AuthServiceProxy(object): __id_count = 0 @@ -124,11 +136,11 @@ def __call__(self, *args): AuthServiceProxy.__id_count += 1 log.debug("-%s-> %s %s"%(AuthServiceProxy.__id_count, self.__service_name, - json.dumps(args, default=EncodeDecimal))) - postdata = json.dumps({'version': '1.1', + jsondumps(args))) + postdata = jsondumps({'version': '1.1', 'method': self.__service_name, 'params': args, - 'id': AuthServiceProxy.__id_count}, default=EncodeDecimal) + 'id': AuthServiceProxy.__id_count}) self.__conn.request('POST', self.__url.path, postdata, {'Host': self.__url.hostname, 'User-Agent': USER_AGENT, @@ -157,7 +169,7 @@ def batch_(self, rpc_calls): m = rpc_call.pop(0) batch_data.append({"jsonrpc":"2.0", "method":m, "params":rpc_call, "id":AuthServiceProxy.__id_count}) - postdata = json.dumps(batch_data, default=EncodeDecimal) + postdata = jsondumps(batch_data) log.debug("--> "+postdata) self.__conn.request('POST', self.__url.path, postdata, {'Host': self.__url.hostname, @@ -185,7 +197,7 @@ def _get_response(self): responsedata = http_response.read().decode('utf8') response = json.loads(responsedata, parse_float=decimal.Decimal) if "error" in response and response["error"] is None: - log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal))) + log.debug("<-%s- %s"%(response["id"], jsondumps(response["result"]))) else: log.debug("<-- "+responsedata) return response