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