1919
2020#include " xeus/xinterpreter.hpp"
2121#include " xeus/xsystem.hpp"
22+ #include " xeus/xhelper.hpp"
2223
2324#include " pybind11/functional.h"
2425
@@ -120,7 +121,6 @@ namespace xpyt
120121 nl::json user_expressions)
121122 {
122123 py::gil_scoped_acquire acquire;
123- nl::json kernel_res;
124124
125125 // Reset traceback
126126 m_ipython_shell.attr (" last_error" ) = py::none ();
@@ -130,6 +130,10 @@ namespace xpyt
130130 auto input_guard = input_redirection (config.allow_stdin );
131131
132132 bool exception_occurred = false ;
133+ std::string ename;
134+ std::string evalue;
135+ std::vector<std::string> traceback;
136+
133137 try
134138 {
135139 m_ipython_shell.attr (" run_cell" )(code, " store_history" _a=config.store_history , " silent" _a=config.silent );
@@ -141,8 +145,6 @@ namespace xpyt
141145 {
142146 publish_execution_error (" RuntimeError" , error_msg, std::vector<std::string>());
143147 }
144- kernel_res[" ename" ] = " std::runtime_error" ;
145- kernel_res[" evalue" ] = error_msg;
146148 exception_occurred = true ;
147149 }
148150 catch (py::error_already_set& e)
@@ -153,10 +155,9 @@ namespace xpyt
153155 publish_execution_error (error.m_ename , error.m_evalue , error.m_traceback );
154156 }
155157
156- kernel_res[" status" ] = " error" ;
157- kernel_res[" ename" ] = error.m_ename ;
158- kernel_res[" evalue" ] = error.m_evalue ;
159- kernel_res[" traceback" ] = error.m_traceback ;
158+ ename = error.m_ename ;
159+ evalue = error.m_evalue ;
160+ traceback = error.m_traceback ;
160161 exception_occurred = true ;
161162 }
162163 catch (...)
@@ -165,27 +166,25 @@ namespace xpyt
165166 {
166167 publish_execution_error (" unknown_error" , " " , std::vector<std::string>());
167168 }
168- kernel_res[ " ename" ] = " UnknownError" ;
169- kernel_res[ " evalue" ] = " " ;
169+ ename = " UnknownError" ;
170+ evalue = " " ;
170171 exception_occurred = true ;
171172 }
172173
173174 // Get payload
174- kernel_res[ " payload" ] = m_ipython_shell.attr (" payload_manager" ).attr (" read_payload" )();
175+ nl::json payload = m_ipython_shell.attr (" payload_manager" ).attr (" read_payload" )();
175176 m_ipython_shell.attr (" payload_manager" ).attr (" clear_payload" )();
176177
177178 if (exception_occurred)
178179 {
179- kernel_res[" status" ] = " error" ;
180- kernel_res[" traceback" ] = std::vector<std::string>();
181- cb (kernel_res);
180+ cb (xeus::create_error_reply (ename, evalue, traceback));
182181 return ;
183182 }
184183
185184 if (m_ipython_shell.attr (" last_error" ).is_none ())
186185 {
187- kernel_res[ " status " ] = " ok " ;
188- kernel_res[ " user_expressions " ] = m_ipython_shell. attr ( " user_expressions " )(user_expressions );
186+ nl::json user_exprs = m_ipython_shell. attr ( " user_expressions " )(user_expressions) ;
187+ cb ( xeus::create_successful_reply (payload, user_exprs) );
189188 }
190189 else
191190 {
@@ -198,38 +197,30 @@ namespace xpyt
198197 publish_execution_error (error.m_ename , error.m_evalue , error.m_traceback );
199198 }
200199
201- kernel_res[" status" ] = " error" ;
202- kernel_res[" ename" ] = error.m_ename ;
203- kernel_res[" evalue" ] = error.m_evalue ;
204- kernel_res[" traceback" ] = error.m_traceback ;
200+ cb (xeus::create_error_reply (error.m_ename , error.m_evalue , error.m_traceback ));
205201 }
206- cb (kernel_res);
207202 }
208203
209204 nl::json interpreter::complete_request_impl (
210205 const std::string& code,
211206 int cursor_pos)
212207 {
213208 py::gil_scoped_acquire acquire;
214- nl::json kernel_res;
215209
216210 py::list completion = m_ipython_shell.attr (" complete_code" )(code, cursor_pos);
217211
218- kernel_res[" matches" ] = completion[0 ];
219- kernel_res[" cursor_start" ] = completion[1 ];
220- kernel_res[" cursor_end" ] = completion[2 ];
221- kernel_res[" metadata" ] = nl::json::object ();
222- kernel_res[" status" ] = " ok" ;
212+ nl::json matches = completion[0 ];
213+ int cursor_start = completion[1 ].cast <int >();
214+ int cursor_end = completion[2 ].cast <int >();
223215
224- return kernel_res ;
216+ return xeus::create_complete_reply (matches, cursor_start, cursor_end, nl::json::object ()) ;
225217 }
226218
227219 nl::json interpreter::inspect_request_impl (const std::string& code,
228220 int cursor_pos,
229221 int detail_level)
230222 {
231223 py::gil_scoped_acquire acquire;
232- nl::json kernel_res;
233224 nl::json data = nl::json::object ();
234225 bool found = false ;
235226
@@ -249,17 +240,12 @@ namespace xpyt
249240 // pass
250241 }
251242
252- kernel_res[" data" ] = data;
253- kernel_res[" metadata" ] = nl::json::object ();
254- kernel_res[" found" ] = found;
255- kernel_res[" status" ] = " ok" ;
256- return kernel_res;
243+ return xeus::create_inspect_reply (found, data, nl::json::object ());
257244 }
258245
259246 nl::json interpreter::is_complete_request_impl (const std::string& code)
260247 {
261248 py::gil_scoped_acquire acquire;
262- nl::json kernel_res;
263249
264250 py::object transformer_manager = py::getattr (m_ipython_shell, " input_transformer_manager" , py::none ());
265251 if (transformer_manager.is_none ())
@@ -268,29 +254,27 @@ namespace xpyt
268254 }
269255
270256 py::list result = transformer_manager.attr (" check_complete" )(code);
271- auto status = result[0 ].cast <std::string>();
257+ std::string status = result[0 ].cast <std::string>();
258+ std::string indent;
272259
273- kernel_res[" status" ] = status;
274- if (status.compare (" incomplete" ) == 0 )
260+ if (status == " incomplete" )
275261 {
276- kernel_res[ " indent" ] = std::string (result[1 ].cast <std::size_t >(), ' ' );
262+ indent = std::string (result[1 ].cast <std::size_t >(), ' ' );
277263 }
278- return kernel_res;
264+
265+ return xeus::create_is_complete_reply (status, indent);
279266 }
280267
281268 nl::json interpreter::kernel_info_request_impl ()
282269 {
283- nl::json result;
284- result[" implementation" ] = " xeus-python" ;
285- result[" implementation_version" ] = XPYT_VERSION;
286270
287271 /* The jupyter-console banner for xeus-python is the following:
288272 __ _____ _ _ ___
289273 \ \/ / _ \ | | / __|
290274 > < __/ |_| \__ \
291275 /_/\_\___|\__,_|___/
292276
293- xeus-python: a Jupyter lernel for Python
277+ xeus-python: a Jupyter kernel for Python
294278 */
295279
296280 std::string banner = " "
@@ -309,22 +293,28 @@ namespace xpyt
309293 " We recommend using a general-purpose package manager instead, such as Conda/Mamba."
310294 " \n " );
311295#endif
312- result[" banner" ] = banner;
313- result[" debugger" ] = (PY_MAJOR_VERSION != 3 ) || (PY_MAJOR_VERSION != 13 );
314296
315- result[" language_info" ][" name" ] = " python" ;
316- result[" language_info" ][" version" ] = PY_VERSION;
317- result[" language_info" ][" mimetype" ] = " text/x-python" ;
318- result[" language_info" ][" file_extension" ] = " .py" ;
319-
320- result[" help_links" ] = nl::json::array ();
321- result[" help_links" ][0 ] = nl::json::object ({
297+ nl::json help_links = nl::json::array ();
298+ help_links.push_back ({
322299 {" text" , " Xeus-Python Reference" },
323300 {" url" , " https://xeus-python.readthedocs.io" }
324301 });
325302
326- result[" status" ] = " ok" ;
327- return result;
303+ return xeus::create_info_reply (
304+ " 5.3" , // protocol_version
305+ " xeus-python" , // implementation
306+ XPYT_VERSION, // implementation_version
307+ " python" , // language_name
308+ PY_VERSION, // language_version
309+ " text/x-python" , // language_mimetype
310+ " .py" , // language_file_extension
311+ " ipython" + std::to_string (PY_MAJOR_VERSION), // pygments_lexer
312+ R"( {"name": "ipython", "version": )" + std::to_string (PY_MAJOR_VERSION) + " }" , // language_codemirror_mode
313+ " python" , // language_nbconvert_exporter
314+ banner, // banner
315+ (PY_MAJOR_VERSION != 3 ) || (PY_MINOR_VERSION != 13 ), // debugger
316+ help_links // help_links
317+ );
328318 }
329319
330320 void interpreter::shutdown_request_impl ()
@@ -335,15 +325,14 @@ namespace xpyt
335325 {
336326 py::gil_scoped_acquire acquire;
337327 std::string code = content.value (" code" , " " );
338- nl::json reply;
339328
340329 // Reset traceback
341330 m_ipython_shell.attr (" last_error" ) = py::none ();
342331
343332 try
344333 {
345334 exec (py::str (code));
346- reply[ " status " ] = " ok " ;
335+ return xeus::create_successful_reply () ;
347336 }
348337 catch (py::error_already_set& e)
349338 {
@@ -358,13 +347,8 @@ namespace xpyt
358347 error.m_traceback .resize (1 );
359348 error.m_traceback [0 ] = code;
360349
361- reply[" status" ] = " error" ;
362- reply[" ename" ] = error.m_ename ;
363- reply[" evalue" ] = error.m_evalue ;
364- reply[" traceback" ] = error.m_traceback ;
350+ return xeus::create_error_reply (error.m_ename , error.m_evalue , error.m_traceback );
365351 }
366-
367- return reply;
368352 }
369353
370354 void interpreter::set_request_context (xeus::xrequest_context context)
0 commit comments