# HG changeset patch # User Mike Miller # Date 1471999028 25200 # Node ID ebd83497ebda21adbf538356210dfb521b829cd1 # Parent 6cd58166117687a00367e541b16823c6edc1eeb1 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. diff -r 6cd581661176 -r ebd83497ebda oct-py-util.cc --- 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 (PyObject_IsInstance (obj, type)); + + return false; +} + std::string py_object_class_name (PyObject *obj) { diff -r 6cd581661176 -r ebd83497ebda oct-py-util.h --- 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);