Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion.
All new code requires tests to ensure against regressions.
If pull request breaks tests it would not be merged.
Description of the Change
This PR adds methods needed for parsing JSON RPC responses from a received JSON string. In order to accomplish that the following changes have been made:
new exception class: JSONRPCInvalidResponseException (just like JSONRPCInvalidRequestException);
new class: JSONRPCResponse - JSON RPC version agnostic parser, based on JSONRPCRequest. It exposes two class methods: from_json and from_data - the former just deserializes JSON string and the latter relays parsing to version-specific class. The mechanism is the exact copy of the one used in JSONRPCRequest;
updated JSONRPC10Response and JSONRPC20Response classes:
updated error setters - verify whether result field is None prior to assigning the error object (raise ValueError if it is not), delete result key in case of JSONRPC20Response (result and error fields are mutually exclusive), attempt to construct error object before assigning the value;
added result and error deleters to JSONRPC20Response;
added from_json and from_data class methods - the mechanism reflects the one found in JSONRPC10Request and JSONRPC20Request.
To ensure proper implementation new tests have been added:
test_jsonrpc1.py:
test_from_json_invalid_response_result - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing result field;
test_from_json_invalid_response_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing error field;
test_from_json_invalid_response_id - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing id field;
test_from_json_invalid_response_both_result_and_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with both result and error fields other than None;
test_from_json_invalid_response_extra_data - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with extra fields;
test_from_json_response_result - tests whether parsing is correct for a specified result field;
test_from_json_response_error - tests whether parsing is correct for a specified error field
test_from_json_string_not_dict - tests whether the parser raises a ValueError if supplied JSON string does not represent a dictionary.
test_jsonrpc2.py:
test_from_json_invalid_response_jsonrpc - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing jsonrpc field;
test_from_json_invalid_response_id - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with missing id field;
test_from_json_invalid_response_no_result_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with neither result nor error fields specified;
test_from_json_invalid_response_result_and_error - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with both result and error fields specified;
test_from_json_invalid_response_extra_data - tests whether the parser raises an JSONRPCInvalidResponseException if supplied with JSON string with extra fields;
test_from_json_response_result_null - tests whether the parsing is correct for a None as a result;
test_from_json_response_result - tests whether the parsing is correct for a list as a result;
test_from_json_response_error - tests whether the parsing is correct for an error response.
Benefits
This change provides a symmetrical interface for both JSONRPCRequest and JSONRPCResponse. This provides an easy and consistent way to implement symmetrical interfaces, in which either side of an connection acts as a server-client hybrid, e.g. server that sends notifications to connected clients.
Possible Drawbacks
Should be none. All tests are passing (except for the Python 3.3 environment, but that is an upstream issue), however it may be reasonable to closely inspect whether error.setter update (in JSONRPC10Response and JSONRPC20Response) did not break anything.
Requirements
Description of the Change
This PR adds methods needed for parsing JSON RPC responses from a received JSON string. In order to accomplish that the following changes have been made:
JSONRPCInvalidResponseException
(just likeJSONRPCInvalidRequestException
);JSONRPCResponse
- JSON RPC version agnostic parser, based onJSONRPCRequest
. It exposes two class methods:from_json
andfrom_data
- the former just deserializes JSON string and the latter relays parsing to version-specific class. The mechanism is the exact copy of the one used inJSONRPCRequest
;JSONRPC10Response
andJSONRPC20Response
classes:error
setters - verify whetherresult
field is None prior to assigning the error object (raiseValueError
if it is not), deleteresult
key in case ofJSONRPC20Response
(result
anderror
fields are mutually exclusive), attempt to construct error object before assigning the value;result
anderror
deleters toJSONRPC20Response
;from_json
andfrom_data
class methods - the mechanism reflects the one found inJSONRPC10Request
andJSONRPC20Request
.To ensure proper implementation new tests have been added:
test_jsonrpc1.py
:test_from_json_invalid_response_result
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with missingresult
field;test_from_json_invalid_response_error
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with missingerror
field;test_from_json_invalid_response_id
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with missingid
field;test_from_json_invalid_response_both_result_and_error
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with bothresult
anderror
fields other thanNone
;test_from_json_invalid_response_extra_data
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with extra fields;test_from_json_response_result
- tests whether parsing is correct for a specifiedresult
field;test_from_json_response_error
- tests whether parsing is correct for a specifiederror
fieldtest_from_json_string_not_dict
- tests whether the parser raises aValueError
if supplied JSON string does not represent a dictionary.test_jsonrpc2.py
:test_from_json_invalid_response_jsonrpc
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with missingjsonrpc
field;test_from_json_invalid_response_id
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with missingid
field;test_from_json_invalid_response_no_result_error
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with neitherresult
norerror
fields specified;test_from_json_invalid_response_result_and_error
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with bothresult
anderror
fields specified;test_from_json_invalid_response_extra_data
- tests whether the parser raises anJSONRPCInvalidResponseException
if supplied with JSON string with extra fields;test_from_json_response_result_null
- tests whether the parsing is correct for aNone
as aresult
;test_from_json_response_result
- tests whether the parsing is correct for alist
as aresult
;test_from_json_response_error
- tests whether the parsing is correct for an error response.Benefits
This change provides a symmetrical interface for both
JSONRPCRequest
andJSONRPCResponse
. This provides an easy and consistent way to implement symmetrical interfaces, in which either side of an connection acts as a server-client hybrid, e.g. server that sends notifications to connected clients.Possible Drawbacks
Should be none. All tests are passing (except for the Python 3.3 environment, but that is an upstream issue), however it may be reasonable to closely inspect whether
error.setter
update (inJSONRPC10Response
andJSONRPC20Response
) did not break anything.