Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
start_python.cpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
17#include "shambase/popen.hpp"
18#include "shambase/print.hpp"
23#include <pybind11/embed.h>
24#include <pybind11/stl.h>
25#include <cstdlib>
26#include <optional>
27#include <string>
28
34extern const char *configure_time_py_sys_path();
35
37extern const char *configure_time_py_executable();
38
43extern const char *run_ipython_src();
44
46std::optional<std::string> runtime_set_pypath = std::nullopt;
47
57std::string get_pypath() {
58
59 if (runtime_set_pypath.has_value()) {
60 return runtime_set_pypath.value();
61 }
63}
64
67
68import sys
69cur_path = os.path.realpath(current_path)
70
71# This is broken on MacOS and give shamrock instead i don't know why ... stupid python ...
72#sysyexec = os.path.realpath(sys.executable)
73# So the fix is to check that the resolved path starts with base_exec_prefix
74# see https://docs.python.org/3/library/sys.html#sys.base_prefix
75sysprefix = os.path.realpath(sys.base_exec_prefix)
76
77#if cur_path != sysyexec:
78if not cur_path.startswith(sysprefix):
79 print("Current python is not the expected version, you may be using mismatched Pythons.")
80 print("Current path : ",cur_path)
81 #print("Expected path : ",sysyexec)
82 print("Expected prefix : ",sysprefix)
83
84)";
85
86namespace shambindings {
87
88 void setpypath(std::string path) { runtime_set_pypath = path; }
89
90 void setpypath_from_binary(std::string binary_path) {
91
92 std::string cmd = binary_path + " -c \"import sys;print(sys.path, end= '')\"";
94 }
95
96 void modify_py_sys_path(bool do_print) {
97
98 if (do_print) {
100 "Shamrock configured with Python path : \n "
101 + std::string(configure_time_py_executable()));
102 }
103
104 std::string check_py
105 = std::string("current_path = \"") + configure_time_py_executable() + "\"\n";
107 py::exec(check_py);
108
109 std::string modify_path = std::string("paths = ") + get_pypath() + "\n";
110 modify_path += R"(import sys;sys.path = paths)";
111 py::exec(modify_path);
112
113 std::string pylib_path = shambindings::locate_pylib_path(do_print);
114 std::string modify_path_lib = std::string("sys.path.insert(0, \"") + pylib_path + "\")\n";
115 py::exec(modify_path_lib);
116 }
117
118 void set_sys_argv(int argc, char *argv[]) {
119 std::vector<std::string> cpp_argv(argv, argv + argc);
120 py::module_::import("sys").attr("argv") = py::cast(cpp_argv);
121 }
122
123 void start_ipython(bool do_print, int argc, char *argv[]) {
124
125 py::scoped_interpreter guard{};
126 modify_py_sys_path(do_print);
127 set_sys_argv(argc, argv);
128
129 if (do_print) {
130 shambase::println("--------------------------------------------");
131 shambase::println("-------------- ipython ---------------------");
132 shambase::println("--------------------------------------------");
133 }
134 py::exec(run_ipython_src());
135 if (do_print) {
136 shambase::println("--------------------------------------------");
137 shambase::println("------------ ipython end -------------------");
138 shambase::println("--------------------------------------------\n");
139 }
140 }
141
142 void run_py_file(std::string file_path, bool do_print, int argc, char *argv[]) {
143 py::scoped_interpreter guard{};
144 modify_py_sys_path(do_print);
145 set_sys_argv(argc, argv);
146
147 if (do_print) {
148 shambase::println("-----------------------------------");
149 shambase::println("running pyscript : " + file_path);
150 shambase::println("-----------------------------------");
151 }
152 py::eval_file(file_path);
153 if (do_print) {
154 shambase::println("-----------------------------------");
155 shambase::println("pyscript end");
156 shambase::println("-----------------------------------");
157 }
158 }
159} // namespace shambindings
void println(std::string_view sv)
Prints a string to the console followed by a newline.
Definition print.cpp:37
std::string popen_fetch_output(const char *command)
Run a command and return the output.
Definition popen.cpp:23
Pybind11 include and definitions.
std::optional< std::string > runtime_set_pypath
value use to set the value of sys.path if set by the user at runtime
const char * configure_time_py_sys_path()
path of the script to generate sys.path
std::string get_pypath()
Retrieves the Python path to be used for the application.
const char * configure_time_py_executable()
path of the python executable that was used to configure sys.path
const char * run_ipython_src()
Script to run ipython.
std::string check_python_is_excpeted_version
Script to check that the python distrib is the expected one.
void setpypath_from_binary(std::string binary_path)
set the value of sys.path before init from the supplied binary
void start_ipython(bool do_print, int argc, char *argv[])
Start shamrock embded ipython interpreter.
void modify_py_sys_path(bool do_print)
Modify Python sys.path to point to one detected during cmake invocation.
void set_sys_argv(int argc, char *argv[])
set the value of sys.argv
void setpypath(std::string path)
set the value of sys.path before init
void run_py_file(std::string file_path, bool do_print, int argc, char *argv[])
run python runscript