diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a964f80..73d66fb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,14 +19,11 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-20.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-20.04, ubuntu-22.04, macos-12, macos-13] steps: - uses: actions/checkout@v4 - - name: Get number of CPU cores - uses: SimenB/github-actions-cpu-cores@v1 - - name: Install micromamba uses: mamba-org/setup-micromamba@v1 with: @@ -46,7 +43,7 @@ jobs: working-directory: build - name: Install - run: make -j ${{ steps.cpu-cores.outputs.count }} install + run: make -j ${{ runner.os == 'macOS' && 3 || 4 }} install working-directory: build - name: Test diff --git a/CMakeLists.txt b/CMakeLists.txt index f33d82d..d5746d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ #The full license is in the file LICENSE, distributed with this software. ############################################################################# -cmake_minimum_required(VERSION 3.4.3) +cmake_minimum_required(VERSION 3.24) project(xeus-nelson) set(XEUS_NELSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -62,12 +62,9 @@ endif () # Dependencies # ============ -set(xtl_REQUIRED_VERSION 0.7.0) -set(xeus_REQUIRED_VERSION 3.2.0) +set(xeus_REQUIRED_VERSION 5.0.0) +set(xeus_zmq_REQUIRED_VERSION 3.0.0) -if (NOT TARGET xtl) - find_package(xtl ${xtl_REQUIRED_VERSION} REQUIRED) -endif () if (NOT TARGET xeus AND NOT TARGET xeus-static) find_package(xeus ${xeus_REQUIRED_VERSION} REQUIRED) endif () @@ -185,7 +182,6 @@ macro(xnelson_create_target target_name linkage output_name) ${target_name} PUBLIC ${XEUS_NELSON_XEUS_TARGET} - xtl nlsCore nlsEngine nlsText_completion @@ -233,7 +229,7 @@ endif () # ======= if (XEUS_NELSON_BUILD_EXECUTABLE) - find_package(xeus-zmq 1.0.2 REQUIRED) + find_package(xeus-zmq 3.0.0 REQUIRED) add_executable(xnelson ${XEUS_NELSON_MAIN_SRC}) xnelson_set_common_options(xnelson) xnelson_set_kernel_options(xnelson) diff --git a/README.md b/README.md index 9d09f9c..b1569a3 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ mamba install`xeus-nelson` notebook -c conda-forge Or you can install it from the sources, you will first need to install dependencies ```bash -mamba install cmake cxx-compiler xeus-zmq nlohmann_json cppzmq xtl nelson-core jupyterlab -c conda-forge +mamba install cmake cxx-compiler xeus-zmq nlohmann_json nelson-core jupyterlab -c conda-forge ``` Then you can compile the sources (replace `$CONDA_PREFIX` with a custom installation @@ -64,11 +64,20 @@ http://xeus-nelson.readthedocs.io `xeus-nelson` depends on - [xeus-zmq](https://github.com/jupyter-xeus/xeus-zmq) -- [xtl](https://github.com/xtensor-stack/xtl) - [nlohmann_json](https://github.com/nlohmann/json) -- [cppzmq](https://github.com/zeromq/cppzmq) - [nelson-core](https://github.com/Nelson-numerical-software/nelson-minimalist-core) +| `xeus-nelson` | `xeus-zmq` | `nlohmann_json` | `nelson-core` | +|---------------|----------------|-----------------|----------------| +| main | >=3.0,<4.0 | >=3.11.3 | >=0.3,<0.4 | +| 0.5.x | >=3.0,<4.0 | >=3.11.3 | >=0.3,<0.4 | + +Prior vo version 0.2, `xeus-nelson` was also depending on [xtl](https://github.com/xtensor-stack/xtl) & [cppzmq](https://github.com/zeromq/cppzmq): + +| `xeus-nelson` | `xeus-zmq` | `xtl` | `cppzmq` | `nlohmann_json` | `nelson-core` | +|---------------|------------------|-----------------|----------|-----------------|----------------| +| 0.4.x | >=1.0.0,<2.0 | >=0.7.0,<0.8 | ~4.4.1 | >=3.11.2 | >=0.3,<0.4 | + ## Contributing See [CONTRIBUTING.md](./CONTRIBUTING.md) to know how to contribute and set up a diff --git a/environment-dev.yml b/environment-dev.yml index 0bbdc96..85ecb90 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -7,13 +7,12 @@ dependencies: - ninja - cxx-compiler # Host dependencies - - xeus-zmq >=1.3.0,<2.0 - - nlohmann_json - - cppzmq - - xtl + - xeus>=5.0.0 + - xeus-zmq>=3.0,<4.0 + - nlohmann_json=3.11.3 - nelson-core >=0.3,<0.4 # Test dependencies - pytest - - jupyter_kernel_test>=0.4.3 + - jupyter_kernel_test>=0.5,<0.6 - nbval - pytest-rerunfailures diff --git a/environment-wasm-host.yml b/environment-wasm-host.yml index 7317a25..fc3ca85 100644 --- a/environment-wasm-host.yml +++ b/environment-wasm-host.yml @@ -6,5 +6,4 @@ dependencies: - nelson >=0.3,<0.4 - nlohmann_json - xeus-lite - - xeus >=3.2.0,<4.0 - - xtl >=0.7,<0.8 + - xeus diff --git a/include/xeus-nelson/xinterpreter.hpp b/include/xeus-nelson/xinterpreter.hpp index 3025128..a24786b 100644 --- a/include/xeus-nelson/xinterpreter.hpp +++ b/include/xeus-nelson/xinterpreter.hpp @@ -53,12 +53,13 @@ namespace xeus_nelson void configure_impl() override; - nl::json execute_request_impl(int execution_counter, - const std::string& code, - bool silent, - bool store_history, - nl::json user_expressions, - bool allow_stdin) override; + void execute_request_impl( + send_reply_callback cb, + int execution_counter, + const std::string& code, + xeus::execute_request_config config, + nl::json user_expressions + ) override; nl::json complete_request_impl(const std::string& code, int cursor_pos) override; diff --git a/src/main.cpp b/src/main.cpp index b772db0..5d5b0a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,8 +6,6 @@ * The full license is in the file LICENSE, distributed with this software. ****************************************************************************/ - - #include #include #include @@ -23,13 +21,14 @@ #include "xeus/xkernel.hpp" #include "xeus/xkernel_configuration.hpp" -#include "xeus-zmq/xserver_zmq.hpp" +#include +#include "xeus-zmq/xserver_zmq.hpp" +#include "xeus-zmq/xzmq_context.hpp" #include "xeus-nelson/xinterpreter.hpp" #include "xeus-nelson/xeus_nelson_config.hpp" - #ifdef __GNUC__ void handler(int sig) { @@ -45,42 +44,19 @@ void handler(int sig) } #endif -bool should_print_version(int argc, char* argv[]) +std::unique_ptr make_file_logger(xeus::xlogger::level log_level) { - for (int i = 0; i < argc; ++i) - { - if (std::string(argv[i]) == "--version") - { - return true; - } - } - return false; + auto logfile = std::getenv("JUPYTER_LOGFILE"); + if (logfile == nullptr) + { + return nullptr; + } + return xeus::make_file_logger(log_level, logfile); } -std::string extract_filename(int argc, char* argv[]) -{ - std::string res = ""; - for (int i = 0; i < argc; ++i) - { - if ((std::string(argv[i]) == "-f") && (i + 1 < argc)) - { - res = argv[i + 1]; - for (int j = i; j < argc - 2; ++j) - { - argv[j] = argv[j + 2]; - } - argc -= 2; - break; - } - } - return res; -} - - - int main(int argc, char* argv[]) { - if (should_print_version(argc, argv)) + if (xeus::should_print_version(argc, argv)) { std::clog << "xnelson " << XEUS_NELSON_VERSION << std::endl; return 0; @@ -102,24 +78,29 @@ int main(int argc, char* argv[]) signal(SIGSEGV, handler); #endif - auto context = xeus::make_context(); + std::unique_ptr context = xeus::make_zmq_context(); // Instantiating the xeus xinterpreter using interpreter_ptr = std::unique_ptr; interpreter_ptr interpreter = interpreter_ptr(new xeus_nelson::interpreter()); + auto hist = xeus::make_in_memory_history_manager(); + auto logger = xeus::make_console_logger(xeus::xlogger::full, make_file_logger(xeus::xlogger::full)); - std::string connection_filename = extract_filename(argc, argv); + std::string connection_filename = xeus::extract_filename(argc, argv); if (!connection_filename.empty()) { - xeus::xconfiguration config = xeus::load_configuration(connection_filename); + + std::cout << "Instantiating kernel" << std::endl; xeus::xkernel kernel(config, xeus::get_user_name(), std::move(context), std::move(interpreter), - xeus::make_xserver_zmq); + xeus::make_xserver_default, + std::move(hist), + std::move(logger)); std::cout << "Starting xnelson kernel...\n\n" @@ -134,26 +115,11 @@ int main(int argc, char* argv[]) xeus::xkernel kernel(xeus::get_user_name(), std::move(context), std::move(interpreter), - xeus::make_xserver_zmq); + xeus::make_xserver_default); + std::cout << "Getting config" << std::endl; const auto& config = kernel.get_config(); - std::cout << - "Starting xnelson kernel...\n\n" - "If you want to connect to this kernel from an other client, just copy" - " and paste the following content inside of a `kernel.json` file. And then run for example:\n\n" - "# jupyter console --existing kernel.json\n\n" - "kernel.json\n```\n{\n" - " \"transport\": \"" + config.m_transport + "\",\n" - " \"ip\": \"" + config.m_ip + "\",\n" - " \"control_port\": " + config.m_control_port + ",\n" - " \"shell_port\": " + config.m_shell_port + ",\n" - " \"stdin_port\": " + config.m_stdin_port + ",\n" - " \"iopub_port\": " + config.m_iopub_port + ",\n" - " \"hb_port\": " + config.m_hb_port + ",\n" - " \"signature_scheme\": \"" + config.m_signature_scheme + "\",\n" - " \"key\": \"" + config.m_key + "\"\n" - "}\n```" - << std::endl; + std::cout << xeus::get_start_message(config) << std::endl; kernel.start(); } diff --git a/src/xinterpreter.cpp b/src/xinterpreter.cpp index 5543695..ee9bc69 100644 --- a/src/xinterpreter.cpp +++ b/src/xinterpreter.cpp @@ -41,23 +41,24 @@ namespace xeus_nelson Nelson::destroyMainEvaluator(); } - nl::json interpreter::execute_request_impl(int execution_counter, // Typically the cell number - const std::string & code, // Code to execute - bool silent, - bool /*store_history*/, - nl::json /*user_expressions*/, - bool /*allow_stdin*/) + void interpreter::execute_request_impl( + send_reply_callback cb, + int execution_count, + const std::string& code, + xeus::execute_request_config config, + nl::json /*user_expressions*/ + ) { if (m_evaluator == nullptr) { const std::string evalue = "Nelson interpreter not initialized"; std::vector traceback({"Interpreter error: " + evalue}); - if(!silent) + if(!config.silent) { publish_execution_error("Interpreter error", evalue, traceback); } // Compose error_reply message - return xeus::create_error_reply("Interpreter error", evalue, traceback); + cb(xeus::create_error_reply("Interpreter error", evalue, traceback)); } try @@ -71,39 +72,39 @@ namespace xeus_nelson { const std::string evalue = ""; std::vector traceback({trimmed_output}); - if (!silent) + if (!config.silent) { publish_execution_error("Interpreter error", evalue, traceback); } // Compose error_reply message - return xeus::create_error_reply("Interpreter error", evalue, traceback); + cb(xeus::create_error_reply("Interpreter error", evalue, traceback)); } else { - if (!silent && !trimmed_output.empty()) + if (!config.silent && !trimmed_output.empty()) { nl::json pub_data; pub_data["text/plain"] = trimmed_output; // Publish the execution result - publish_execution_result(execution_counter, std::move(pub_data), nl::json::object()); + publish_execution_result(execution_count, std::move(pub_data), nl::json::object()); } // TODO payload to set correctly or deprecated and not used anymore? //const nl::json& payload = nl::json::array(); // Compose successful_reply message - return xeus::create_successful_reply(nl::json::array(), nl::json::object()); + cb(xeus::create_successful_reply(nl::json::array(), nl::json::object())); } } catch (Nelson::Exception& e) { const auto evalue = Nelson::wstring_to_utf8(e.getMessage()); std::vector traceback({"Interpreter error: " + evalue}); - if (!silent) + if (!config.silent) { publish_execution_error("Interpreter error", evalue, traceback); } // Compose error_reply message - return xeus::create_error_reply("Interpreter error", evalue, traceback); + cb(xeus::create_error_reply("Interpreter error", evalue, traceback)); } } diff --git a/xeus-nelsonConfig.cmake.in b/xeus-nelsonConfig.cmake.in index 5ca31b0..fd2b65e 100644 --- a/xeus-nelsonConfig.cmake.in +++ b/xeus-nelsonConfig.cmake.in @@ -22,9 +22,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR};${CMAKE_MODULE_PATH}") @XEUS_NELSON_CONFIG_CODE@ include(CMakeFindDependencyMacro) -find_dependency(xtl @xtl_REQUIRED_VERSION@) find_dependency(xeus-zmq @xeus-zmq_REQUIRED_VERSION@) -find_dependency(cppzmq @cppzmq_REQUIRED_VERSION@) if (NOT TARGET xeus-nelson AND NOT TARGET xeus-nelson-static)