@@ -66,6 +66,8 @@ namespace xpyt
6666 register_request_handler (" attach" , std::bind (&debugger::attach_request, this , _1), true );
6767 register_request_handler (" configurationDone" , std::bind (&debugger::configuration_done_request, this , _1), true );
6868 register_request_handler (" copyToGlobals" , std::bind (&debugger::copy_to_globals_request, this , _1), true );
69+ register_request_handler (" modules" , std::bind (&debugger::modules, this , _1), false );
70+
6971 }
7072
7173 debugger::~debugger ()
@@ -369,4 +371,44 @@ namespace xpyt
369371 return std::unique_ptr<xeus::xdebugger>(new debugger (context,
370372 config, user_name, session_id, debugger_config));
371373 }
374+
375+ nl::json debugger::modules (const nl::json& message)
376+ {
377+ py::gil_scoped_acquire acquire;
378+ py::module sys = py::module::import (" sys" );
379+ py::list modules = sys.attr (" modules" ).attr (" values" )();
380+
381+ int start_module = message.value (" startModule" , 0 );
382+ int module_count = message.value (" moduleCount" , static_cast <int >(py::len (modules)));
383+
384+ nl::json mods = nl::json::array ();
385+ for (int i = start_module; i < module_count && i < static_cast <int >(py::len (modules)); ++i)
386+ {
387+ py::object module = modules[i];
388+ py::object spec = getattr (module , " __spec__" , py::none ());
389+ py::object origin = py::none ();
390+ if (!spec.is_none ())
391+ origin = getattr (spec, " origin" , py::none ());
392+
393+ if (!origin.is_none ())
394+ {
395+ std::string filename = py::str (origin);
396+ if (filename.size () > 3 && filename.substr (filename.size () - 3 ) == " .py" )
397+ {
398+ mods.push_back ({
399+ {" id" , i},
400+ {" name" , py::str (module .attr (" __name__" ))},
401+ {" path" , filename}
402+ });
403+ }
404+ }
405+ }
406+
407+ return {
408+ {" body" , {
409+ {" modules" , mods},
410+ {" totalModules" , py::len (modules)}
411+ }}
412+ };
413+ }
372414}
0 commit comments