summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2012-01-11 14:03:53 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2012-01-11 14:03:53 +0000
commit69342f86b0d036ca41a19363efaf4e8352837c24 (patch)
tree411e3f328188590eaa14f3959bf07ec67d958e54
parentcada4883df6b67f4059eedd2def1f5cffa41c7d8 (diff)
downloaddbus-python-69342f86b0d036ca41a19363efaf4e8352837c24.tar.gz
Do not allow Byte(unicode(x)) (i.e. Byte(str(x)) in Python 3)
Unicode strings aren't bytestrings, so there's no obvious meaning for the byte value of a Unicode string of length 1.
-rw-r--r--PY3PORT.rst12
-rw-r--r--_dbus_bindings/bytes.c14
-rw-r--r--test/cross-test-client.py18
-rwxr-xr-xtest/test-standalone.py38
4 files changed, 46 insertions, 36 deletions
diff --git a/PY3PORT.rst b/PY3PORT.rst
index c873c2c..2e4be43 100644
--- a/PY3PORT.rst
+++ b/PY3PORT.rst
@@ -39,22 +39,22 @@ unchanged. There are a few changes you'll notice in Python 2 though::
simplifies the implementation and cross-compatibility with Python 3.
- Some values which were ints are now longs. Primarily, this affects the
type of the `variant_level` attributes.
- - `dbus.Byte` can be constructed from a 1-character str or unicode object.
- Some exception strings have changed.
- `MethodCallMessage` and `SignalMessage` objects have better reprs now.
What do you need to do to port that to Python 3? Here are the user visible
changes you should be aware of. Python 3.2 is the minimal required version::
- - `ByteArray`s must be initialized with bytes objects, not unicodes. Use
- `b''` literals in the constructor. This also works in Python 2, where
+ - `ByteArray` objects must be initialized with bytes objects, not unicodes.
+ Use `b''` literals in the constructor. This also works in Python 2, where
bytes objects are aliases for 8-bit strings.
+ - `Byte` objects must be initialized with either a length-1 bytes object
+ (again, use `b''` literals to be compatible with either Python 2 or 3)
+ or an integer.
- byte signatures (i.e. `y` type codes) must be passed either a length-1
- bytes object or an integer. unicodes are not allowed.
+ bytes object or an integer. unicodes (str in Python 3) are not allowed.
- `ByteArray` is now a subclass of `bytes`, where in Python 2 it is a
subclass of `str`.
- - `dbus.Byte` can be constructed from a 1-character byte or str object, or an
- integer.
- `dbus.UTF8String` is gone, use `dbus.String`. Also `utf8_string` arguments
are no longer allowed.
- All longs are now ints, since Python 3 has only a single int type. This
diff --git a/_dbus_bindings/bytes.c b/_dbus_bindings/bytes.c
index 548ca46..e053f43 100644
--- a/_dbus_bindings/bytes.c
+++ b/_dbus_bindings/bytes.c
@@ -96,20 +96,6 @@ Byte_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
if (!obj)
goto bad_arg;
}
- else if (PyUnicode_Check(obj)) {
- PyObject *obj_as_bytes = PyUnicode_AsUTF8String(obj);
- if (!obj_as_bytes)
- return NULL;
- if (PyBytes_GET_SIZE(obj_as_bytes) != 1) {
- Py_CLEAR(obj_as_bytes);
- goto bad_arg;
- }
- obj = PyLong_FromLong(
- (unsigned char)PyBytes_AS_STRING(obj_as_bytes)[0]);
- Py_CLEAR(obj_as_bytes);
- if (!obj)
- goto bad_arg;
- }
else if (PyLong_Check(obj)
#ifndef PY3
|| PyInt_Check(obj)
diff --git a/test/cross-test-client.py b/test/cross-test-client.py
index dc6154b..75c4119 100644
--- a/test/cross-test-client.py
+++ b/test/cross-test-client.py
@@ -294,13 +294,13 @@ class Client(SignalTestsImpl):
self.assert_method_eq(INTERFACE_TESTS, 42, 'IdentityUInt64', 42)
self.assert_method_eq(INTERFACE_TESTS, 42.0, 'IdentityDouble', 42)
- self.assert_method_eq(INTERFACE_TESTS, [Byte('\x01', variant_level=1),
- Byte('\x02', variant_level=1),
- Byte('\x03', variant_level=1)],
+ self.assert_method_eq(INTERFACE_TESTS, [Byte(b'\x01', variant_level=1),
+ Byte(b'\x02', variant_level=1),
+ Byte(b'\x03', variant_level=1)],
'IdentityArray',
- Array([Byte('\x01'),
- Byte('\x02'),
- Byte('\x03')],
+ Array([Byte(b'\x01'),
+ Byte(b'\x02'),
+ Byte(b'\x03')],
signature='v'))
self.assert_method_eq(INTERFACE_TESTS, [Int32(1, variant_level=1),
@@ -321,9 +321,9 @@ class Client(SignalTestsImpl):
signature='v'))
if have_signatures:
- self.assert_method_eq(INTERFACE_TESTS, [Byte('\x01', variant_level=1),
- Byte('\x02', variant_level=1),
- Byte('\x03', variant_level=1)],
+ self.assert_method_eq(INTERFACE_TESTS, [Byte(b'\x01', variant_level=1),
+ Byte(b'\x02', variant_level=1),
+ Byte(b'\x03', variant_level=1)],
'IdentityArray',
ByteArray(b'\x01\x02\x03'))
self.assert_method_eq(INTERFACE_TESTS, [Int32(1, variant_level=1),
diff --git a/test/test-standalone.py b/test/test-standalone.py
index 22e8444..677abd9 100755
--- a/test/test-standalone.py
+++ b/test/test-standalone.py
@@ -89,14 +89,16 @@ class TestTypes(unittest.TestCase):
self.assertEqual(x, ('a','b','c'))
def test_Byte(self):
- self.assertEqual(types.Byte('x', variant_level=2),
+ self.assertEqual(types.Byte(b'x', variant_level=2),
types.Byte(ord('x')))
self.assertEqual(types.Byte(1), 1)
self.assertEqual(types.Byte(make_long(1)), 1)
-
- def test_Byte_from_unicode(self):
+ self.assertRaises(Exception, lambda: types.Byte(b'ab'))
self.assertRaises(TypeError, types.Byte, '\x12xxxxxxxxxxxxx')
- self.assertEqual(types.Byte('\x12'), ord(b'\x12'))
+
+ # Byte from a unicode object: what would that even mean?
+ self.assertRaises(Exception,
+ lambda: types.Byte(b'a'.decode('latin-1')))
def test_ByteArray(self):
self.assertEqual(types.ByteArray(b''), b'')
@@ -197,15 +199,37 @@ class TestMessageMarshalling(unittest.TestCase):
s.append([], signature='ay')
aeq(s.get_args_list(), [[]])
+ def test_append_Byte(self):
+ aeq = self.assertEqual
+ from _dbus_bindings import SignalMessage
+
+ s = SignalMessage('/', 'foo.bar', 'baz')
+ s.append(0xFE, signature='y')
+ aeq(s.get_args_list(), [types.Byte(0xFE)])
+
+ s = SignalMessage('/', 'foo.bar', 'baz')
+ s.append(b'\xfe', signature='y')
+ aeq(s.get_args_list(), [types.Byte(0xFE)])
+
+ # appending a unicode object (including str in Python 3)
+ # is not allowed
+ s = SignalMessage('/', 'foo.bar', 'baz')
+ self.assertRaises(Exception,
+ lambda: s.append('a'.decode('latin-1'), signature='y'))
+
+ s = SignalMessage('/', 'foo.bar', 'baz')
+ self.assertRaises(Exception,
+ lambda: s.append(b'ab', signature='y'))
+
def test_append_ByteArray(self):
aeq = self.assertEqual
from _dbus_bindings import SignalMessage
s = SignalMessage('/', 'foo.bar', 'baz')
s.append(types.ByteArray(b'ab'), signature='ay')
- aeq(s.get_args_list(), [[types.Byte('a'), types.Byte('b')]])
+ aeq(s.get_args_list(), [[types.Byte(b'a'), types.Byte(b'b')]])
s = SignalMessage('/', 'foo.bar', 'baz')
s.append(types.ByteArray(b'ab'), signature='av')
- aeq(s.get_args_list(), [[types.Byte('a'), types.Byte('b')]])
+ aeq(s.get_args_list(), [[types.Byte(b'a'), types.Byte(b'b')]])
s = SignalMessage('/', 'foo.bar', 'baz')
s.append(types.ByteArray(b''), signature='ay')
aeq(s.get_args_list(), [[]])
@@ -217,7 +241,7 @@ class TestMessageMarshalling(unittest.TestCase):
s = SignalMessage('/', 'foo.bar', 'baz')
s.append(types.Int32(1, variant_level=0),
types.String('a', variant_level=42),
- types.Array([types.Byte('a', variant_level=1),
+ types.Array([types.Byte(b'a', variant_level=1),
types.UInt32(123, variant_level=1)],
signature='v'),
signature='vvv')