@@ -67,10 +67,20 @@ static PyModule *s_builtin_module = nullptr;
6767
6868namespace {
6969
70- PyResult<PyObject *> print (const PyTuple *args, const PyDict *kwargs, Interpreter &)
70+ PyResult<PyObject *> print (const PyTuple *args, const PyDict *kwargs, Interpreter &interpreter )
7171{
7272 std::string separator = " " ;
7373 std::string end = " \n " ;
74+ // TODO: handle error case?
75+ PyObject *file =
76+ PyObject::from (interpreter.get_imported_module (PyString::create (" sys" ).unwrap ())
77+ ->symbol_table ()
78+ ->map ()
79+ .at (String{ " stdout" }))
80+ .unwrap ();
81+ // sys.stdout may be None when FILE* stdout isn't connected
82+ if (!file || file == py_none ()) { return Ok (py_none ()); }
83+ bool flush = true ;
7484 if (kwargs) {
7585 static const Value separator_keyword = String{ " sep" };
7686 static const Value end_keyword = String{ " end" };
@@ -98,6 +108,9 @@ PyResult<PyObject *> print(const PyTuple *args, const PyDict *kwargs, Interprete
98108 end = std::get<String>(maybe_str).s ;
99109 }
100110 }
111+ auto file_write_ = file->get_method (PyString::create (" write" ).unwrap ());
112+ if (file_write_.is_err ()) { return file_write_; }
113+ auto file_write = file_write_.unwrap ();
101114 auto strfunc = [](const PyResult<PyObject *> &arg) -> PyResult<PyString *> {
102115 if (arg.is_err ()) return Err (arg.unwrap_err ());
103116 return arg.unwrap ()->str ();
@@ -106,7 +119,11 @@ PyResult<PyObject *> print(const PyTuple *args, const PyDict *kwargs, Interprete
106119 auto arg_it = args->begin ();
107120 auto arg_it_end = args->end ();
108121 if (arg_it == arg_it_end) {
109- std::cout << std::endl;
122+ if (flush) {
123+ auto file_flush_ = file->get_method (PyString::create (" flush" ).unwrap ());
124+ if (file_flush_.is_err ()) { return file_flush_; }
125+ return file_flush_.unwrap ()->call (nullptr , nullptr );
126+ }
110127 return Ok (py_none ());
111128 }
112129 --arg_it_end;
@@ -117,7 +134,10 @@ PyResult<PyObject *> print(const PyTuple *args, const PyDict *kwargs, Interprete
117134 if (reprobj_.is_err ()) { return reprobj_; }
118135 auto reprobj = reprobj_.unwrap ();
119136 spdlog::debug (" repr result: {}" , reprobj->value ());
120- std::cout << reprobj->value () << separator;
137+ if (auto result = file_write->call (PyTuple::create (reprobj).unwrap (), nullptr );
138+ result.is_err ()) {
139+ return result;
140+ }
121141 std::advance (arg_it, 1 );
122142 }
123143
@@ -126,8 +146,23 @@ PyResult<PyObject *> print(const PyTuple *args, const PyDict *kwargs, Interprete
126146 if (reprobj_.is_err ()) { return reprobj_; }
127147 auto reprobj = reprobj_.unwrap ();
128148 spdlog::debug (" repr result: {}" , reprobj->value ());
129- std::cout << reprobj->value () << end;
149+ if (auto result = file_write->call (PyTuple::create (reprobj).unwrap (), nullptr );
150+ result.is_err ()) {
151+ return result;
152+ }
130153
154+ if (!end.empty ()) {
155+ if (auto result =
156+ file_write->call (PyTuple::create (PyString::create (end).unwrap ()).unwrap (), nullptr );
157+ result.is_err ()) {
158+ return result;
159+ }
160+ }
161+ if (flush) {
162+ auto file_flush_ = file->get_method (PyString::create (" flush" ).unwrap ());
163+ if (file_flush_.is_err ()) { return file_flush_; }
164+ return file_flush_.unwrap ()->call (nullptr , nullptr );
165+ }
131166 return Ok (py_none ());
132167}
133168
0 commit comments