[pygobject] Show proper exception when trying to allocate a disguised struct



commit 77844c571ad0badc189428b93de9f2572051b67e
Author: Martin Pitt <martinpitt gnome org>
Date:   Mon Sep 3 17:58:38 2012 +0200

    Show proper exception when trying to allocate a disguised struct
    
    Instead of a simple "MemoryError" with no details, raise a proper
    TypeError with a traceback and an explanation what happened.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=639972

 gi/pygi-struct.c         |    7 +++++++
 tests/test_everything.py |   13 +++++++++++++
 2 files changed, 20 insertions(+), 0 deletions(-)
---
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
index c2e1f4d..eace77c 100644
--- a/gi/pygi-struct.c
+++ b/gi/pygi-struct.c
@@ -74,6 +74,13 @@ _struct_new (PyTypeObject *type,
     }
 
     size = g_struct_info_get_size ( (GIStructInfo *) info);
+    if (size == 0) {
+        PyErr_Format (PyExc_TypeError,
+            "cannot allocate disguised struct %s.%s; consider adding a constructor to the library or to the overrides",
+            g_base_info_get_namespace (info),
+            g_base_info_get_name (info));
+        goto out;
+    }
     pointer = g_try_malloc0 (size);
     if (pointer == NULL) {
         PyErr_NoMemory();
diff --git a/tests/test_everything.py b/tests/test_everything.py
index e09b27a..406fcb3 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -3,6 +3,7 @@
 # vim: tabstop=4 shiftwidth=4 expandtab
 
 import unittest
+import traceback
 
 import sys
 from sys import getrefcount
@@ -228,6 +229,18 @@ class TestEverything(unittest.TestCase):
         self.assertEqual(getrefcount(l1), init_refcount + 1)
         self.assertEqual(getrefcount(l3), init_refcount)
 
+    def test_struct_opaque(self):
+        # we should get a sensible error message
+        try:
+            Everything.TestBoxedPrivate()
+            self.fail('allocating disguised struct without default constructor unexpectedly succeeded')
+        except TypeError as e:
+            self.assertTrue('TestBoxedPrivate' in str(e), str(e))
+            self.assertTrue('override' in str(e), str(e))
+            self.assertTrue('constructor' in str(e), str(e))
+            tb = ''.join(traceback.format_exception(type(e), e, e.__traceback__))
+            self.assertTrue('tests/test_everything.py", line' in tb, tb)
+
 
 class TestNullableArgs(unittest.TestCase):
     def test_in_nullable_hash(self):



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]