A method prints incoming messages directly to Python's stdout using Python's C API. This is necessary in Jupyter notebooks and colabs where messages to the C stdout don't go to the notebook cell outputs, but calls to Python's stdout do.
| 3473 | // and colabs where messages to the C stdout don't go to the notebook |
| 3474 | // cell outputs, but calls to Python's stdout do. |
| 3475 | void PrintToPythonStdout(const char* msg) { |
| 3476 | if (Py_IsInitialized()) { |
| 3477 | PyGILState_STATE py_threadstate; |
| 3478 | py_threadstate = PyGILState_Ensure(); |
| 3479 | |
| 3480 | string string_msg = msg; |
| 3481 | // PySys_WriteStdout truncates strings over 1000 bytes, so |
| 3482 | // we write the message in chunks small enough to not be truncated. |
| 3483 | int CHUNK_SIZE = 900; |
| 3484 | auto len = string_msg.length(); |
| 3485 | for (size_t i = 0; i < len; i += CHUNK_SIZE) { |
| 3486 | PySys_WriteStdout("%s", string_msg.substr(i, CHUNK_SIZE).c_str()); |
| 3487 | } |
| 3488 | |
| 3489 | // Force flushing to make sure print newlines aren't interleaved in |
| 3490 | // some colab environments |
| 3491 | PyRun_SimpleString("import sys; sys.stdout.flush()"); |
| 3492 | |
| 3493 | PyGILState_Release(py_threadstate); |
| 3494 | } |
| 3495 | } |
| 3496 | |
| 3497 | // Register PrintToPythonStdout as a log listener, to allow |
| 3498 | // printing in colabs and jupyter notebooks to work. |