changeset 386:668fcb0f68ef

Fix extraction of class name for Python types without a module (fixes issue #79) * oct-py-util.cc (pytave::py_object_class_name): Handle object types with __module__ set to None, just return the value of __name__. * __py_struct_from_dict__.cc (F__py_class_name__): Add test case.
author Mike Miller <mtmiller@octave.org>
date Mon, 03 Apr 2017 08:30:20 -0700
parents 132fec49e438
children 1af368713379
files __py_struct_from_dict__.cc oct-py-util.cc
diffstat 2 files changed, 5 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/__py_struct_from_dict__.cc	Sun Apr 02 16:24:02 2017 -0700
+++ b/__py_struct_from_dict__.cc	Mon Apr 03 08:30:20 2017 -0700
@@ -65,6 +65,9 @@
 %!assert (__py_class_name__ (pyeval ("()")), "tuple")
 %!assert (__py_class_name__ (pyeval ("__import__('array').array('d')")), "array.array")
 
+%% Test an anonymous class with its __module__ property set to None
+%!assert (__py_class_name__ (pyeval ("[[t() for t.__module__ in (None,)][0] for t in (type('foo', (), {}),)][0]")), "foo")
+
 %!error __py_class_name__ ()
 %!error __py_class_name__ (1)
 %!error __py_class_name__ (1, 2)
--- a/oct-py-util.cc	Sun Apr 02 16:24:02 2017 -0700
+++ b/oct-py-util.cc	Mon Apr 03 08:30:20 2017 -0700
@@ -139,14 +139,14 @@
       else
         name = PyObject_GetAttrString (type, "__name__");
 
-      std::string mod_str = mod ? extract_py_str (mod) : "";
+      std::string mod_str = (mod && mod != Py_None) ? extract_py_str (mod) : "";
       std::string name_str = name ? extract_py_str (name) : "";
 
       Py_DECREF (type);
       Py_XDECREF (mod);
       Py_XDECREF (name);
 
-      if (mod_str == py_builtins_module_name ())
+      if (mod_str.empty () || mod_str == py_builtins_module_name ())
         retval = name_str;
       else
         retval = mod_str + "." + name_str;