Comment 20 for bug 893091

Revision history for this message
In , Simon McVittie (smcv) wrote :

> (In reply to comment #9)
> I hope that it will possible to merge this, so that the python2 and python3
> bindings can be built from the same sources.

I hope so too, but only when it's ready. Please don't consider the py3k branch to be an API-stable platform until it's merged into master and included in a numbered release (which, IMO, it shouldn't be yet). I'm fairly sure it will need some work on the type system, which I'm afraid I don't have time to do right now; I should be able to devote more time to this in a couple of weeks.

(In reply to comment #11)
> Did a bunch of work and fixed all the issues for Python 2.6 (e.g. it passes
> make check). Simon, one thing that stumped me was the different ways we extend
> base types for variant_level. Why are some done with C extensions to the
> struct and others use attr? I noticed with the long object trying to covert it
> to a struct extension made the values you put in off by a power of two when you
> go to print it out.

That's because long is a "variable-length object" that can't safely extend the C struct, whereas int is "fixed-length object" that can be extended in the same way you're used to for GObject. Please read and understand the CPython API docs before hacking on the C extension! :-)

Briefly: the 'str' C struct ends with a char[1] or some such, which is actually a placeholder representing a char[n] for a suitably large n. If you put the variant_level member after the char[1], but assign a bigger-than-1-character value to it, the extra character data will overflow into, and corrupt, the variant_level. 'long' and 'unicode' behave like 'str', except that their "characters" are integers representing segments of the arbitrary-length integer it represents.

However, Python 2's 'int' is fixed-length, and 'list' and presumably Python 3's 'bytes' store their data in a separately-allocated array like you'd expect in a GObject (they have to, because they're mutable). For such types, it's safe (and somewhat more efficient) to extend the struct, rather than attaching a __dict__.

Extending the struct corresponds to using __slots__ all the way down a hierarchy of pure-Python subtypes, whereas attaching a __dict__ corresponds to not using __slots__.

(In reply to comment #13)
> Since dbus specifies that signatures, object_paths, service names, etc. are all
> ascii I have decided to make them all subclass the Bytes type.

I don't think that's right; they should all subclass str, the normal Python string type (which happens to be Unicode on Python 3).

However, dbus.UTF8String should be a deprecated subtype of bytes when running on Python 3, and dbus.ByteArray should be a subtype of bytes.

It's probably also worth setting byte_arrays=True by default in Python 3 (the ability to use a dbus.Array of dbus.Byte is almost never useful), and it might even be worth removing utf8_strings and UTF8String altogether.