33
44import logging
55import threading
6+ import sys
67
78try :
89 import orjson as json
@@ -83,7 +84,15 @@ class JsonRpcStreamWriter:
8384 def __init__ (self , wfile , ** json_dumps_args ):
8485 self ._wfile = wfile
8586 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' , (',' , ':' ))
8796
8897 def close (self ):
8998 with self ._wfile_lock :
@@ -96,16 +105,16 @@ def write(self, message):
96105 try :
97106 body = json .dumps (message , ** self ._json_dumps_args )
98107
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' )
101110
102111 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 }
107116
108- self ._wfile .write (response . encode ( 'utf-8' ) )
117+ self ._wfile .write (response )
109118 self ._wfile .flush ()
110119 except Exception : # pylint: disable=broad-except
111120 log .exception ("Failed to write message to output file %s" , message )
0 commit comments