[pygobject] Fix property type mapping from int to TYPE_INT for python3.



commit affc7faa3fa7250e2e8c2c65e6860906f6fbc4fb
Author: Simon Feltman <s feltman gmail com>
Date:   Fri Jul 20 21:34:33 2012 -0700

    Fix property type mapping from int to TYPE_INT for python3.
    
    Python3 does not have a long type, however, propertyhelper.py was
    using long_ = int; to get things working. Type mapping code
    was then checking for long_ first and always returning TYPE_LONG.
    Additional refactoring was done to move large if/elif statements
    into dictionary lookups and usage of tuples instead of lists
    for simple 'in' list of items tests.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=679939

 gi/_gobject/propertyhelper.py |  117 +++++++++++++++++++----------------------
 tests/test_properties.py      |   55 +++++++++++++++-----
 2 files changed, 96 insertions(+), 76 deletions(-)
---
diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py
index 5c0bb0b..82b06b0 100644
--- a/gi/_gobject/propertyhelper.py
+++ b/gi/_gobject/propertyhelper.py
@@ -74,6 +74,50 @@ class Property(object):
         def propInt(self, value):
             ...
     """
+    _type_from_pytype_lookup = {
+        # Put long_ first in case long_ and int are the same so int clobbers long_
+        _long: TYPE_LONG,
+        int: TYPE_INT,
+        bool: TYPE_BOOLEAN,
+        float: TYPE_DOUBLE,
+        str: TYPE_STRING,
+        object: TYPE_PYOBJECT,
+    }
+
+    _min_value_lookup = {
+        TYPE_UINT: 0,
+        TYPE_ULONG: 0,
+        TYPE_UINT64: 0,
+        # Remember that G_MINFLOAT and G_MINDOUBLE are something different.
+        TYPE_FLOAT: -G_MAXFLOAT,
+        TYPE_DOUBLE: -G_MAXDOUBLE,
+        TYPE_INT: G_MININT,
+        TYPE_LONG: G_MINLONG,
+        TYPE_INT64: -2 ** 62 - 1,
+    }
+
+    _max_value_lookup = {
+        TYPE_UINT: G_MAXUINT,
+        TYPE_ULONG: G_MAXULONG,
+        TYPE_INT64: 2 ** 62 - 1,
+        TYPE_UINT64: 2 ** 63 - 1,
+        TYPE_FLOAT: G_MAXFLOAT,
+        TYPE_DOUBLE: G_MAXDOUBLE,
+        TYPE_INT: G_MAXINT,
+        TYPE_LONG: G_MAXLONG,
+    }
+
+    _default_lookup = {
+        TYPE_INT: 0,
+        TYPE_UINT: 0,
+        TYPE_LONG: 0,
+        TYPE_ULONG: 0,
+        TYPE_INT64: 0,
+        TYPE_UINT64: 0,
+        TYPE_STRING: '',
+        TYPE_FLOAT: 0.0,
+        TYPE_DOUBLE: 0.0,
+    }
 
     class __metaclass__(type):
         def __repr__(self):
@@ -203,48 +247,28 @@ class Property(object):
         return self
 
     def _type_from_python(self, type_):
-        if type_ == _long:
-            return TYPE_LONG
-        elif type_ == int:
-            return TYPE_INT
-        elif type_ == bool:
-            return TYPE_BOOLEAN
-        elif type_ == float:
-            return TYPE_DOUBLE
-        elif type_ == str:
-            return TYPE_STRING
-        elif type_ == object:
-            return TYPE_PYOBJECT
+        if type_ in self._type_from_pytype_lookup:
+            return self._type_from_pytype_lookup[type_]
         elif (isinstance(type_, type) and
               issubclass(type_, (_gobject.GObject,
                                  _gobject.GEnum,
                                  _gobject.GFlags,
                                  _gobject.GBoxed))):
             return type_.__gtype__
-        elif type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
+        elif type_ in (TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
                        TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
                        TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
                        TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
                        TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
-                       TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
+                       TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV):
             return type_
         else:
             raise TypeError("Unsupported type: %r" % (type_,))
 
     def _get_default(self, default):
-        ptype = self.type
         if default is not None:
             return default
-
-        if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
-                     TYPE_INT64, TYPE_UINT64]:
-            return 0
-        elif ptype == TYPE_STRING:
-            return ''
-        elif ptype == TYPE_FLOAT or ptype == TYPE_DOUBLE:
-            return 0.0
-        else:
-            return None
+        return self._default_lookup.get(self.type, None)
 
     def _check_default(self):
         ptype = self.type
@@ -276,43 +300,10 @@ class Property(object):
                     raise TypeError("Strv value %s must contain only strings" % str(default))
 
     def _get_minimum(self):
-        ptype = self.type
-        if ptype in [TYPE_UINT, TYPE_ULONG, TYPE_UINT64]:
-            return 0
-        # Remember that G_MINFLOAT and G_MINDOUBLE are something different.
-        elif ptype == TYPE_FLOAT:
-            return -G_MAXFLOAT
-        elif ptype == TYPE_DOUBLE:
-            return -G_MAXDOUBLE
-        elif ptype == TYPE_INT:
-            return G_MININT
-        elif ptype == TYPE_LONG:
-            return G_MINLONG
-        elif ptype == TYPE_INT64:
-            return -2 ** 62 - 1
-
-        return None
+        return self._min_value_lookup.get(self.type, None)
 
     def _get_maximum(self):
-        ptype = self.type
-        if ptype == TYPE_UINT:
-            return G_MAXUINT
-        elif ptype == TYPE_ULONG:
-            return G_MAXULONG
-        elif ptype == TYPE_INT64:
-            return 2 ** 62 - 1
-        elif ptype == TYPE_UINT64:
-            return 2 ** 63 - 1
-        elif ptype == TYPE_FLOAT:
-            return G_MAXFLOAT
-        elif ptype == TYPE_DOUBLE:
-            return G_MAXDOUBLE
-        elif ptype == TYPE_INT:
-            return G_MAXINT
-        elif ptype == TYPE_LONG:
-            return G_MAXLONG
-
-        return None
+        return self._max_value_lookup.get(self.type, None)
 
     #
     # Getter and Setter
@@ -338,13 +329,13 @@ class Property(object):
 
     def get_pspec_args(self):
         ptype = self.type
-        if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
-                     TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE]:
+        if ptype in (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
+                     TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE):
             args = self.minimum, self.maximum, self.default
         elif (ptype == TYPE_STRING or ptype == TYPE_BOOLEAN or
               ptype.is_a(TYPE_ENUM) or ptype.is_a(TYPE_FLAGS)):
             args = (self.default,)
-        elif ptype in [TYPE_PYOBJECT, TYPE_GTYPE]:
+        elif ptype in (TYPE_PYOBJECT, TYPE_GTYPE):
             args = ()
         elif ptype.is_a(TYPE_OBJECT) or ptype.is_a(TYPE_BOXED):
             args = ()
diff --git a/tests/test_properties.py b/tests/test_properties.py
index f81ed4f..2b77d28 100644
--- a/tests/test_properties.py
+++ b/tests/test_properties.py
@@ -2,6 +2,7 @@
 
 import sys
 import struct
+import types
 import unittest
 
 from gi.repository import GObject
@@ -9,7 +10,11 @@ from gi.repository.GObject import GType, new, PARAM_READWRITE, \
     PARAM_CONSTRUCT, PARAM_READABLE, PARAM_WRITABLE, PARAM_CONSTRUCT_ONLY
 from gi.repository.GObject import \
     TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_INT64, \
-    TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV
+    TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV, \
+    TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, TYPE_BOOLEAN, TYPE_FLOAT, \
+    TYPE_DOUBLE, TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
+    TYPE_STRING, TYPE_PYOBJECT
+
 from gi.repository.GObject import \
     G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, G_MAXULONG
 
@@ -312,22 +317,22 @@ class TestProperties(unittest.TestCase):
         minint64 = -maxint64 - 1
         maxuint64 = umax('Q')
 
-        types = dict(int=(TYPE_INT, minint, maxint),
-                     uint=(TYPE_UINT, 0, maxuint),
-                     long=(TYPE_LONG, minlong, maxlong),
-                     ulong=(TYPE_ULONG, 0, maxulong),
-                     int64=(TYPE_INT64, minint64, maxint64),
-                     uint64=(TYPE_UINT64, 0, maxuint64))
+        types_ = dict(int=(TYPE_INT, minint, maxint),
+                      uint=(TYPE_UINT, 0, maxuint),
+                      long=(TYPE_LONG, minlong, maxlong),
+                      ulong=(TYPE_ULONG, 0, maxulong),
+                      int64=(TYPE_INT64, minint64, maxint64),
+                      uint64=(TYPE_UINT64, 0, maxuint64))
 
-        def build_gproperties(types):
+        def build_gproperties(types_):
             d = {}
-            for key, (gtype, min, max) in types.items():
+            for key, (gtype, min, max) in types_.items():
                 d[key] = (gtype, 'blurb', 'desc', min, max, 0,
                           PARAM_READABLE | PARAM_WRITABLE)
             return d
 
         class RangeCheck(GObject.GObject):
-            __gproperties__ = build_gproperties(types)
+            __gproperties__ = build_gproperties(types_)
 
             def __init__(self):
                 self.values = {}
@@ -353,7 +358,7 @@ class TestProperties(unittest.TestCase):
         self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64)
 
         obj = RangeCheck()
-        for key, (gtype, min, max) in types.items():
+        for key, (gtype, min, max) in types_.items():
             self.assertEqual(obj.get_property(key),
                              getattr(RangeCheck.props, key).default_value)
 
@@ -494,7 +499,7 @@ class TestProperty(unittest.TestCase):
         minint64 = -2 ** 62 - 1
         maxuint64 = 2 ** 63 - 1
 
-        types = [
+        types_ = [
             (TYPE_INT, G_MININT, G_MAXINT),
             (TYPE_UINT, 0, G_MAXUINT),
             (TYPE_LONG, G_MINLONG, G_MAXLONG),
@@ -503,7 +508,7 @@ class TestProperty(unittest.TestCase):
             (TYPE_UINT64, 0, maxuint64),
             ]
 
-        for gtype, min, max in types:
+        for gtype, min, max in types_:
             # Normal, everything is alright
             prop = GObject.Property(type=gtype, minimum=min, maximum=max)
             subtype = type('', (GObject.GObject,), dict(prop=prop))
@@ -680,6 +685,30 @@ class TestProperty(unittest.TestCase):
 
         self.assertEqual(C.blurbed.blurb, 'blurbed doc string')
 
+    def testPythonToGLibTypeMapping(self):
+        tester = GObject.Property()
+        self.assertEqual(tester._type_from_python(int), GObject.TYPE_INT)
+        if sys.version_info < (3, 0):
+            self.assertEqual(tester._type_from_python(long), GObject.TYPE_LONG)
+        self.assertEqual(tester._type_from_python(bool), GObject.TYPE_BOOLEAN)
+        self.assertEqual(tester._type_from_python(float), GObject.TYPE_DOUBLE)
+        self.assertEqual(tester._type_from_python(str), GObject.TYPE_STRING)
+        self.assertEqual(tester._type_from_python(object), GObject.TYPE_PYOBJECT)
+
+        self.assertEqual(tester._type_from_python(GObject.GObject), GObject.GObject.__gtype__)
+        self.assertEqual(tester._type_from_python(GObject.GEnum), GObject.GEnum.__gtype__)
+        self.assertEqual(tester._type_from_python(GObject.GFlags), GObject.GFlags.__gtype__)
+        self.assertEqual(tester._type_from_python(GObject.GBoxed), GObject.GBoxed.__gtype__)
+
+        for type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
+                      TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
+                      TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
+                      TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
+                      TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
+                      TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
+            self.assertEqual(tester._type_from_python(type_), type_)
+
+        self.assertRaises(TypeError, tester._type_from_python, types.CodeType)
 
 if __name__ == '__main__':
     unittest.main()



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