-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Variant unpacker #27
Comments
|
Note: Patch against pygi is not enough, I can't depend on the latest version of pygi as it's not on pypi. |
Note: If I decide to auto-remove trailing \0 from ay when unpacking, I'll need to "repack" all GLib.Variants received from the user - to add trailing \0 (as changing the behavior of the constructor seems evil, and monkeypatching this change is even more evil) |
For context, I am the maintainer of dbus-python, or possibly the unmaintainer. This mostly involves rejecting changes that would make it lose its single most important feature, namely "is compatible with dbus-python". I try to encourage all dbus-python users to use something better instead - perhaps g-i or pydbus. If I was writing a Python D-Bus binding now, with no compatibility constraints, I think I'd be making all D-Bus types (or at least all types without a perfect match in Python) unmarshal into GVariant-like objects rather than the Python primitives that they superficially resemble, and just giving them the appropriate methods (including
dbus-python also unpacks dbus-python also has a
dbus-python does that (its D-Bus type
You can't. When a generic D-Bus library receives an Higher-level things that actually understand the semantics of what they receive - for instance something that uses Flatpak - can make the decision to call `.rstrip(b'\0'); but a generic D-Bus library like pydbus only understands the syntax of the message content, not the semantics, so it can't do that. In a Python 3 way of thinking, I would personally be inclined to return a
|
pydbus is a Pythonic dbus library. This means, that its primary goal is to be as intuitive, and standard-python-like, as possible. To hide as much of DBus's implementation details as possible, and present native Python interface - familiar to web developers and other Python users, who do not necessarily have any C / DBus experience. In terms of features, this means:
pydbus is designed to be the highest-level interface to DBus services; for lower level access there is PyGI. Implementing higher-level, per-interface wrappers should not be necessary. It can be used in code, but it's also awesome (and probably the best) for interacting with DBus thru the interactive console. Looks like the DBus has standarized on '\0'-terminated binary strings. Do you know any APIs that provide non-'\0'-terminated "ay"s? If not, then I think it's time to standarize that "ay"s shall ALWAYS have trailing '\0', and ALWAYS ignore the last character (and throw an exception if it's not \0). This way, the Flatpak case works perfectly, and people can still send true binary data (containing multiple \0) - it'll simply get another \0 appended at the transport layer, and then stripped by the bindings on the other side. I guess I should collaborate on it with authors of bindings for other languages. |
Yes: every byte array that is not "basically a string", and some byte arrays that are strings too. For an example of the former, the
For an example of the latter, |
If you want to coordinate among binding and library authors, please (encourage them all to) contact dbus@lists.freedesktop.org.
I can understand the appeal of thinking this, because I used to think the same: who needs domain-specific C/Python/whatever APIs when you can just provide a D-Bus API and use each language's generic bindings? In my experience, the answer turns out to be that this results in a lot of sharp edges, and an API that can't be used in practice without at least some understanding of D-Bus. You can have a convenient high-level API for some particular domain/problem that can be used without understanding D-Bus, or you can have generic bindings for D-Bus, but I have yet to encounter anything that achieves both.
I think the way to think about this is: it's a common convention, and ideally that common convention would be easy, but it can't be done at the expense of the other possible uses for byte-arrays. Not every byte-array is a bytestring. Saying that D-Bus has standardized on the In fact I'm fairly sure the reason Flatpak is using |
Hm... Maybe we could create a new DBus annotation saying something like "treat all arguments of this method as \0-terminated bytestrings"? This wouldn't break anything, and high-level libraries will be happy. However, I still think that there is no reason to send \0-terminated strings over the wire, and this \0 could be added transparently by gdbus in g_variant_get_bytestring() and removed in g_variant_new_bytestring(). Of course there might be compatibility problems here, but we could deprecate those functions and add new ones. Hm... Annotation looks like less work, but it'll have to be implemented in all the high-level libraries (or at least those that want to be nice). |
Whether you consider the reasons to be sufficiently good or not, you're too late to have this not happen in existing APIs.
GVariant cannot add I know you don't care about this for pydbus, because Pythonic bindings for C code are always going to have to copy strings into |
ruby-dbus here. As Simon has already said, an |
FWIW, Rust does not use zero-terminated strings and thus has no use for the extra zero anyway. Also, for now, we only know of two places where this happens so I doubt it's commonly used. If the D-Bus specification grows some kind of annotation about autoremoval/autoadd of |
My raw opinion: given that D-Bus already describes array-length, I don't see any reason for using \0-terminated strings for serializing strings. |
If it was, it would be closed NOTABUG. This is not a bug in GDBus. It is a convention encouraged (but not required) by GVariant, that has subsequently been adopted by the designers of several D-Bus APIs.
That would be because you don't write in C, or you write in C but you don't care about the performance impact of copying every bytestring one more time. Those are valid arguments in your own D-Bus designs, but you don't get to change other people's D-Bus API designs when their position on a particular trade-off doesn't match yours. |
I've looked at GDBus, and it looks like they're copying the values while converting between messages and GVariants. https://github.com/GNOME/glib/blob/master/gio/gdbusmessage.c#L1558 (g_variant_new_string copies the data, as it uses g_bytes_new internally) |
(That was for strings, for 'ay's (gdbusmessage.c#L1687) g_variant_new_fixed_array is used, which also copies the data) |
Indeed, GDBus isn't zero-copy in this way (but GVariant is; and in libdbus, access to strings that use the GVariant bytestring convention from a DBusMessage can be). At one point there was a plan for GVariant to be D-Bus message serialization 2.0, although I'm not sure what happened to that. |
AFAIR kdbus used GVariant's serialization, but it's dead now. Looks like we can safely change GVariant's in-memory representation to always include trailing \0 in "ay"s, and possibly create GVariant serialization format 2.0. GDBus apps won't get slower, and we won't need the bytestring convention on the bus. |
What's the status on this issue? |
GLib.Variant.unpack: https://github.com/GNOME/pygobject/blob/master/gi/overrides/GLib.py#L284
Possibly a patch against pygi, but can also be a pydbus's own function.
The text was updated successfully, but these errors were encountered: