[pygobject] [gi] python 3 fixes
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] [gi] python 3 fixes
- Date: Wed, 26 Jan 2011 20:23:42 +0000 (UTC)
commit 6ff357839feb39930a5f3175de3d0ed35f24d3f4
Author: John (J5) Palmieri <johnp redhat com>
Date: Wed Jan 26 15:17:03 2011 -0500
[gi] python 3 fixes
Patches need to work in Python 3 - here are some of the issues I fixed up.
Patch submitters should keep this in mind. When I note to only use something
in tests it means that there is a compat module that is only available to the
tests. Actuall code should either add the workaround to the top of their
module or try not to have a distinction between things such as unicode and
longs which no longer exist in Python 3
* use range instead of xrange - loss of performance in Python 2 but Python 3 i
treats range similarly to python 2's xrange
* use dict.items() instead of dict.iteritems() - same as the xrange issue
* callable does not exist in 3.x, use hasattr(obj, '__call__') or
if sys.version_info > (3, 0):
def callable(obj):
return hasattr(obj, '__call__')
* using unicode in tests is tricky, you can't use u'' even in a versioned
conditional as python3's parser chokes on it. Do this in tests (and only i
in tests):
from compathelper import _unicode
unicode_string = _unicode('this is a unicode string')
* exception caching changed in 2.7, instead of except Exception, e we now use
except Exception as e. Do this to be compatible with older versions:
except Exception:
etype, e = sys.exc_info()[:2]
* Unbound methods with an im_func attribute no longer exits in 3.x.
Unbound methods are now just functions so class.method in 3.x is
equivalent to class.method.im_func in 2.x. If you have to go this
low level do this:
func = class1.method
if sys.version_info < (3,0):
func = func.im_func
* all numbers are long in 3.x so 42L is invalid in 3.x. In tests (and
only in tests) do this:
from compathelper import _long
l = _long(42)
gi/overrides/GLib.py | 16 ++++++++--------
gi/types.py | 5 ++++-
tests/compathelper.py | 19 +++++++++++++++++++
tests/test_gdbus.py | 12 ++++++++----
tests/test_gi.py | 19 ++++++++++++-------
tests/test_overrides.py | 8 +++++---
6 files changed, 56 insertions(+), 23 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index dd85877..ac783be 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -102,7 +102,7 @@ class _VariantCreator(object):
if not args or type(args[0]) != type(()):
raise (TypeError, 'expected tuple argument')
- for i in xrange(len(args[0])):
+ for i in range(len(args[0])):
if format.startswith(')'):
raise (TypeError, 'too many arguments for tuple signature')
@@ -127,7 +127,7 @@ class _VariantCreator(object):
builder.init(variant_type_from_string(element_type))
else:
builder.init(variant_type_from_string('a{?*}'))
- for k, v in args[0].iteritems():
+ for k, v in args[0].items():
(key_v, rest_format, _) = self._create(format[2:], [k])
(val_v, rest_format, _) = self._create(rest_format, [v])
@@ -157,7 +157,7 @@ class _VariantCreator(object):
builder.init(variant_type_from_string(element_type))
else:
builder.init(variant_type_from_string('a*'))
- for i in xrange(len(args[0])):
+ for i in range(len(args[0])):
(v, rest_format, _) = self._create(format[1:], args[0][i:])
builder.add_value(v)
if args is not None:
@@ -213,13 +213,13 @@ class Variant(GLib.Variant):
# tuple
if self.get_type_string().startswith('('):
res = [self.get_child_value(i).unpack()
- for i in xrange(self.n_children())]
+ for i in range(self.n_children())]
return tuple(res)
# dictionary
if self.get_type_string().startswith('a{'):
res = {}
- for i in xrange(self.n_children()):
+ for i in range(self.n_children()):
v = self.get_child_value(i)
res[v.get_child_value(0).unpack()] = v.get_child_value(1).unpack()
return res
@@ -227,7 +227,7 @@ class Variant(GLib.Variant):
# array
if self.get_type_string().startswith('a'):
return [self.get_child_value(i).unpack()
- for i in xrange(self.n_children())]
+ for i in range(self.n_children())]
# variant (just unbox transparently)
if self.get_type_string().startswith('v'):
@@ -257,7 +257,7 @@ class Variant(GLib.Variant):
# lookup_value() only works for string keys, which is certainly
# the common case; we have to do painful iteration for other
# key types
- for i in xrange(self.n_children()):
+ for i in range(self.n_children()):
v = self.get_child_value(i)
if v.get_child_value(0).unpack() == key:
return v.get_child_value(1).unpack()
@@ -283,7 +283,7 @@ class Variant(GLib.Variant):
return TypeError, 'GVariant type %s is not a dictionary' % self.get_type_string()
res = []
- for i in xrange(self.n_children()):
+ for i in range(self.n_children()):
v = self.get_child_value(i)
res.append(v.get_child_value(0).unpack())
return res
diff --git a/gi/types.py b/gi/types.py
index b3a9d3d..a7a4569 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -34,6 +34,9 @@ from ._gi import \
register_interface_info, \
hook_up_vfunc_implementation
+if sys.version_info > (3, 0):
+ def callable(obj):
+ return hasattr(obj, '__call__')
def Function(info):
@@ -104,7 +107,7 @@ class MetaClassHelper(object):
setattr(cls, name, value)
def _setup_vfuncs(cls):
- for vfunc_name, py_vfunc in cls.__dict__.iteritems():
+ for vfunc_name, py_vfunc in cls.__dict__.items():
if not vfunc_name.startswith("do_") or not callable(py_vfunc):
continue
diff --git a/tests/compathelper.py b/tests/compathelper.py
index 754285c..2465747 100644
--- a/tests/compathelper.py
+++ b/tests/compathelper.py
@@ -44,7 +44,26 @@ if sys.version_info >= (3, 0):
'''
_bytes = lambda s: s.encode()
+
+ '''
+ for tests that need to write to intefaces that take unicode in
+ python 2
+
+ python 3 strings are unicode encoded as UTF-8 so the unicode object
+ doesn't exist
+
+ python 2 differs between a string an unicode string and you must specify
+ an encoding. This macro will specify UTF-8 in python 2
+
+ any tests that need to use unicode should do this
+
+ from compathelper import _unicode
+ unicode_string = _unicode('this is a unicode string')
+ '''
+
+ _unicode = lambda s: str(s)
else:
_long = long
_basestring = basestring
_bytes = str
+ _unicode = lambda s: unicode(s, 'UTF-8')
diff --git a/tests/test_gdbus.py b/tests/test_gdbus.py
index 66df327..b5a253b 100644
--- a/tests/test_gdbus.py
+++ b/tests/test_gdbus.py
@@ -40,7 +40,8 @@ class TestGDBusClient(unittest.TestCase):
self.dbus_proxy.call_sync('GetConnectionUnixProcessID', None,
Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call with invalid arguments should raise an exception')
- except Exception, e:
+ except Exception:
+ etype, e = sys.exc_info()[:2]
self.assert_('InvalidArgs' in e.message)
# error case: invalid argument
@@ -49,7 +50,8 @@ class TestGDBusClient(unittest.TestCase):
GLib.Variant('(s)', (' unknown',)),
Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call with invalid arguments should raise an exception')
- except Exception, e:
+ except Exception:
+ etype, e = sys.exc_info()[:2]
self.assert_('NameHasNoOwner' in e.message)
# error case: unknown method
@@ -57,7 +59,8 @@ class TestGDBusClient(unittest.TestCase):
self.dbus_proxy.call_sync('UnknownMethod', None,
Gio.DBusCallFlags.NO_AUTO_START, 500, None)
self.fail('call for unknown method should raise an exception')
- except Exception, e:
+ except Exception:
+ etype, e = sys.exc_info()[:2]
self.assert_('UnknownMethod' in e.message)
def test_native_calls_async(self):
@@ -82,7 +85,8 @@ class TestGDBusClient(unittest.TestCase):
try:
self.dbus_proxy.call_finish(result)
self.fail('call_finish() for unknown method should raise an exception')
- except Exception, e:
+ except Exception:
+ etype, e = sys.exc_info()[:2]
self.assert_('UnknownMethod' in e.message)
finally:
user_data['main_loop'].quit()
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 19a7d46..3598e61 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -1456,9 +1456,13 @@ class TestPythonGObject(unittest.TestCase):
# Here we check that accessing a vfunc from the subclass returns the same wrapper object,
# meaning that multiple wrapper objects have not been created for the same vfunc.
- self.assertTrue(GIMarshallingTests.Object.do_method_with_default_implementation.im_func is \
- GIMarshallingTests.SubObject.do_method_with_default_implementation.im_func)
-
+ func1 = GIMarshallingTests.Object.do_method_with_default_implementation
+ func2 = GIMarshallingTests.SubObject.do_method_with_default_implementation
+ if sys.version_info < (3,0):
+ func1 = func1.im_func
+ func2 = func2.im_func
+
+ self.assertTrue(func1 is func2)
class TestMultiOutputArgs(unittest.TestCase):
@@ -1473,10 +1477,11 @@ class TestGErrorException(unittest.TestCase):
self.assertRaises(GObject.GError, GIMarshallingTests.gerror)
try:
GIMarshallingTests.gerror()
- except Exception, error:
- self.assertEquals(error.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
- self.assertEquals(error.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
- self.assertEquals(error.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
+ except Exception:
+ etype, e = sys.exc_info()[:2]
+ self.assertEquals(e.domain, GIMarshallingTests.CONSTANT_GERROR_DOMAIN)
+ self.assertEquals(e.code, GIMarshallingTests.CONSTANT_GERROR_CODE)
+ self.assertEquals(e.message, GIMarshallingTests.CONSTANT_GERROR_MESSAGE)
# Interface
diff --git a/tests/test_overrides.py b/tests/test_overrides.py
index ec0fda4..25cea6a 100644
--- a/tests/test_overrides.py
+++ b/tests/test_overrides.py
@@ -6,6 +6,8 @@ import unittest
import sys
sys.path.insert(0, "../")
+from compathelper import _long, _unicode
+
from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gdk
@@ -70,7 +72,7 @@ class TestGLib(unittest.TestCase):
# nested tuples
variant = GLib.Variant('((si)(ub))', (('hello', -1), (42, True)))
self.assertEqual(variant.get_type_string(), '((si)(ub))')
- self.assertEqual(variant.unpack(), (('hello', -1), (42L, True)))
+ self.assertEqual(variant.unpack(), (('hello', -1), (_long(42), True)))
# dictionaries
@@ -684,7 +686,7 @@ class TestGtk(unittest.TestCase):
test_pylist))
i = 93
- label = u'this is row #93'
+ label = _unicode('this is row #93')
treeiter = list_store.append()
list_store.set_value(treeiter, 0, i)
list_store.set_value(treeiter, 1, label)
@@ -695,7 +697,7 @@ class TestGtk(unittest.TestCase):
# test automatic unicode->str conversion
i = 94
- label = u'this is row #94'
+ label = _unicode('this is row #94')
treeiter = list_store.append((i,
label,
TestGtk.TestClass(self, i, label),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]