changeset 357:ebd83497ebda

Add utility functions to look up Python modules, functions, and types * oct-py-util.cc, oct-py-util.h (pytave::py_builtins_module, pytave::py_find_function, pytave::py_find_type, pytave::py_import_module, pytave::py_isinstance): New functions to get handles to Python modules, functions, and types, and to check if an object is an instance of a type.
author Mike Miller <mtmiller@octave.org>
date Tue, 23 Aug 2016 17:37:08 -0700
parents 6cd581661176
children d41fc23d4b9f
files oct-py-util.cc oct-py-util.h
diffstat 2 files changed, 132 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/oct-py-util.cc	Mon Aug 22 17:33:20 2016 -0700
+++ b/oct-py-util.cc	Tue Aug 23 17:37:08 2016 -0700
@@ -96,6 +96,87 @@
     }
 }
 
+PyObject *
+py_builtins_module ()
+{
+#if PY_VERSION_HEX >= 0x03000000
+  return py_import_module ("builtins");
+#else
+  return py_import_module ("__builtin__");
+#endif
+}
+
+PyObject *
+py_find_function (PyObject *module, const std::string& name)
+{
+  if (module && PyModule_Check (module))
+    {
+      PyObject *obj = PyObject_GetAttrString (module, name.c_str ());
+      if (obj && ! PyCallable_Check (obj))
+        {
+          Py_CLEAR (obj);
+        }
+
+      return obj;
+    }
+
+  return 0;
+}
+
+PyObject *
+py_find_function (const std::string& module, const std::string& name)
+{
+  PyObject *mod = py_import_module (module);
+  PyObject *func =  py_find_function (mod, name);
+  Py_XDECREF (mod);
+  return func;
+}
+
+PyObject *
+py_find_function (const std::string& name)
+{
+  std::string::size_type idx = name.rfind (".");
+  if (idx == std::string::npos)
+    {
+      PyObject *func = py_find_function ("__main__", name);
+      if (! func)
+        func = py_find_function (py_builtins_module (), name);
+      return func;
+    }
+  else
+    {
+      std::string module = name.substr (0, idx);
+      std::string function = name.substr (idx + 1);
+      return py_find_function (module, function);
+    }
+}
+
+PyObject *
+py_find_type (const std::string& name)
+{
+  PyObject *obj = py_find_function (name);
+  if (obj && PyType_Check (obj))
+    return obj;
+
+  Py_XDECREF (obj);
+  return 0;
+}
+
+PyObject *
+py_import_module (const std::string& name)
+{
+  return PyImport_ImportModule (name.c_str ());
+}
+
+bool
+py_isinstance (PyObject *obj, PyObject *type)
+{
+  if (obj && type)
+    return static_cast<bool> (PyObject_IsInstance (obj, type));
+
+  return false;
+}
+
 std::string
 py_object_class_name (PyObject *obj)
 {
--- a/oct-py-util.h	Mon Aug 22 17:33:20 2016 -0700
+++ b/oct-py-util.h	Tue Aug 23 17:37:08 2016 -0700
@@ -38,6 +38,57 @@
 get_object_from_python (const octave_value& oct_value,
                         boost::python::object& py_object);
 
+//! Return a reference to the builtins module.
+//!
+//! @return reference to the builtins module
+PyObject *
+py_builtins_module ();
+
+//! Return a reference to the named function in the given module.
+//!
+//! @param module module to find the function in
+//! @param name name of the function
+//! @return a reference to the function, or a null pointer
+PyObject *
+py_find_function (PyObject *module, const std::string& name);
+
+//! Return a reference to the named function in the given module.
+//!
+//! @param module name of the module to find the function in
+//! @param name name of the function
+//! @return a reference to the function, or a null pointer
+PyObject *
+py_find_function (const std::string& module, const std::string& name);
+
+//! Return a reference to the fully-qualified function name.
+//!
+//! @param name fully-qualified name of the function
+//! @return a reference to the function, or a null pointer
+PyObject *
+py_find_function (const std::string& name);
+
+//! Return a reference to the fully-qualified type name.
+//!
+//! @param name fully-qualified name of the type
+//! @return a reference to the type, or a null pointer
+PyObject *
+py_find_type (const std::string& name);
+
+//! Return a reference to the named module.
+//!
+//! @param name fully-qualified name of the module
+//! @return a reference to the module, or a null pointer
+PyObject *
+py_import_module (const std::string& name);
+
+//! Check whether an object is an instance of a type.
+//!
+//! @param obj Python object
+//! @param type Python type
+//! @return @c true if @a obj is an instance of @a type, @c false otherwise
+bool
+py_isinstance (PyObject *obj, PyObject *type);
+
 std::string
 py_object_class_name (PyObject *obj);