3
3
4
4
import logging
5
5
import threading
6
+ import sys
6
7
7
8
try :
8
9
import orjson as json
@@ -83,7 +84,15 @@ class JsonRpcStreamWriter:
83
84
def __init__ (self , wfile , ** json_dumps_args ):
84
85
self ._wfile = wfile
85
86
self ._wfile_lock = threading .Lock ()
86
- self ._json_dumps_args = json_dumps_args
87
+
88
+ if 'orjson' in sys .modules and json_dumps_args .pop ('sort_keys' ):
89
+ # orjson needs different option handling
90
+ self ._json_dumps_args = {'option' : json .OPT_SORT_KEYS }
91
+ self ._json_dumps_args .update (** json_dumps_args )
92
+ else :
93
+ self ._json_dumps_args = json_dumps_args
94
+ # omit unnecessary whitespace for consistency with orjson
95
+ self ._json_dumps_args .setdefault ('separators' , (',' , ':' ))
87
96
88
97
def close (self ):
89
98
with self ._wfile_lock :
@@ -96,16 +105,16 @@ def write(self, message):
96
105
try :
97
106
body = json .dumps (message , ** self ._json_dumps_args )
98
107
99
- # Ensure we get the byte length, not the character length
100
- content_length = len ( body ) if isinstance (body , bytes ) else len ( body .encode ('utf-8' ) )
108
+ # orjson gives bytes, builtin json gives str. ensure we have bytes
109
+ body_bytes = body if isinstance (body , bytes ) else body .encode ('utf-8' )
101
110
102
111
response = (
103
- f "Content-Length: { content_length } \r \n "
104
- f "Content-Type: application/vscode-jsonrpc; charset=utf8\r \n \r \n "
105
- f" { body } "
106
- )
112
+ b "Content-Length: %(length)i \r \n "
113
+ b "Content-Type: application/vscode-jsonrpc; charset=utf8\r \n \r \n "
114
+ b"%( body)s "
115
+ ) % { b'length' : len ( body_bytes ), b'body' : body_bytes }
107
116
108
- self ._wfile .write (response . encode ( 'utf-8' ) )
117
+ self ._wfile .write (response )
109
118
self ._wfile .flush ()
110
119
except Exception : # pylint: disable=broad-except
111
120
log .exception ("Failed to write message to output file %s" , message )
0 commit comments