Python handler: Pass a python object to content handled application. R=etiennej@chromium.org Review URL: https://codereview.chromium.org/942013003
diff --git a/mojo/public/python/mojo_application/application_runner.py b/mojo/public/python/mojo_application/application_runner.py index 94f472c..e43a518 100644 --- a/mojo/public/python/mojo_application/application_runner.py +++ b/mojo/public/python/mojo_application/application_runner.py
@@ -11,8 +11,7 @@ def RunMojoApplication(application_delegate, app_request_handle): loop = mojo_system.RunLoop() - application = ApplicationImpl(application_delegate, - mojo_system.Handle(app_request_handle)) + application = ApplicationImpl(application_delegate, app_request_handle) application.manager.AddOnErrorCallback(loop.Quit) loop.Run()
diff --git a/mojo/public/python/src/common.cc b/mojo/public/python/src/common.cc index e2a832a..d14d718 100644 --- a/mojo/public/python/src/common.cc +++ b/mojo/public/python/src/common.cc
@@ -41,7 +41,12 @@ ScopedPyRef::ScopedPyRef(PyObject* object, ScopedPyRefAcquire) : object_(object) { - Py_XINCREF(object_); + if (object_) + Py_XINCREF(object_); +} + +ScopedPyRef::ScopedPyRef(const ScopedPyRef& other) + : ScopedPyRef(other, kAcquire) { } PyObject* ScopedPyRef::Release() { @@ -57,8 +62,14 @@ } } -ScopedPyRef::operator PyObject*() const { - return object_; +ScopedPyRef& ScopedPyRef::operator=(const ScopedPyRef& other) { + if (other) + Py_XINCREF(other); + PyObject* old = object_; + object_ = other; + if (old) + Py_DECREF(old); + return *this; } PythonClosure::PythonClosure(PyObject* callable, const mojo::Closure& quit)
diff --git a/mojo/public/python/src/common.h b/mojo/public/python/src/common.h index 4eae72e..2ada2a4 100644 --- a/mojo/public/python/src/common.h +++ b/mojo/public/python/src/common.h
@@ -37,18 +37,19 @@ public: explicit ScopedPyRef(PyObject* object); ScopedPyRef(PyObject* object, ScopedPyRefAcquire); + ScopedPyRef(const ScopedPyRef& other); ~ScopedPyRef(); // Releases ownership of the python object contained by this instance. PyObject* Release(); - operator PyObject*() const; + operator PyObject*() const { return object_; } + + ScopedPyRef& operator=(const ScopedPyRef& other); private: PyObject* object_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ScopedPyRef); };
diff --git a/services/python/content_handler/content_handler_main.cc b/services/python/content_handler/content_handler_main.cc index f9199ad..39e8b0e 100644 --- a/services/python/content_handler/content_handler_main.cc +++ b/services/python/content_handler/content_handler_main.cc
@@ -9,6 +9,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/i18n/icu_util.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "mojo/application/application_runner_chromium.h" #include "mojo/application/content_handler_factory.h" #include "mojo/common/common_type_converters.h" @@ -85,16 +86,22 @@ return temp_dir; } - bool RunPythonCommand(std::string command, PyObject* globals) { - ScopedPyRef result( - PyRun_String(command.c_str(), Py_file_input, globals, NULL)); + ScopedPyRef RunString(std::string command, PyObject* globals, int mode) { + ScopedPyRef result(PyRun_String(command.c_str(), mode, globals, nullptr)); - if (result == nullptr) { + if (!result) { LOG(ERROR) << "Error while running command: '" << command << "'"; PyErr_Print(); - return false; } - return true; + return result; + } + + bool Exec(std::string command, PyObject* globals) { + return RunString(command, globals, Py_file_input); + } + + ScopedPyRef Eval(std::string command, PyObject* globals) { + return RunString(command, globals, Py_eval_input); } // Sets up the Python interpreter and loads mojo system modules. This method @@ -113,8 +120,8 @@ PyObject *m, *d; m = PyImport_AddModule("__main__"); - if (m == NULL) - return NULL; + if (!m) + return nullptr; d = PyModule_GetDict(m); // Enable debug information if requested. @@ -123,16 +130,16 @@ "import logging;" "logging.basicConfig();" "logging.getLogger().setLevel(logging.DEBUG)"; - if (!RunPythonCommand(enable_logging, d)) - return NULL; + if (!Exec(enable_logging, d)) + return nullptr; } // Inject the application path into the python search path so that imports // from the application work as expected. std::string search_path_py_command = "import sys; sys.path.append('" + application_path + "');"; - if (!RunPythonCommand(search_path_py_command, d)) - return NULL; + if (!Exec(search_path_py_command, d)) + return nullptr; return d; } @@ -158,7 +165,7 @@ // yet. ScopedPyRef result(PyRun_File(entry_file, entry_path.value().c_str(), Py_file_input, d, d)); - if (result == nullptr) { + if (!result) { LOG(ERROR) << "Error while loading script"; PyErr_Print(); return; @@ -167,7 +174,7 @@ // Find MojoMain. ScopedPyRef py_function(PyMapping_GetItemString(d, kMojoMain)); - if (py_function == NULL) { + if (!py_function) { LOG(ERROR) << "Locals size: " << PyMapping_Size(d); LOG(ERROR) << "MojoMain not found"; PyErr_Print(); @@ -177,7 +184,13 @@ if (PyCallable_Check(py_function)) { MojoHandle application_request_handle = application_request.PassMessagePipe().release().value(); - ScopedPyRef py_input(PyInt_FromLong(application_request_handle)); + std::string handle_command = base::StringPrintf( + "mojo_system.Handle(%u)", application_request_handle); + ScopedPyRef py_input(Eval(handle_command, d)); + if (!py_input) { + MojoClose(application_request_handle); + return; + } ScopedPyRef py_arguments(PyTuple_New(1)); // py_input reference is stolen by py_arguments PyTuple_SetItem(py_arguments, 0, py_input.Release());