Skip to content
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

Add options to explicitly specify DBus signatures in decorators #111

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

ahem
Copy link

@ahem ahem commented Jan 6, 2022

This adds options to the @method, @dbus_property and @signal decorators that can be used to explicitly specify the DBus signature.

While I find the use of the type annotations to specify the DBus signatures to be very readable, it has the downside that ordinary Python type annotations cannot be used when creating DBus interfaces. Also, as discussed in #78, any type checker (such as mypy or pyright) that tries to validate types will complain about the DBus annotations, and some editors will flag the annotations as errors because of this.

This PR allows the use of "normal" type annotations by allowing the signatures to be specified in the decorators, like this:

    @method(in_signature="sasu", out_signature="i")
    def a_third_method(self, one: str, two: List[str], three) -> int:
        return 42

    @signal(signature="as")
    def foo_signal(self) -> List[str]:
        return ['result']

    @dbus_property(signature='u')
    def foo_prop(self) -> int:
        return self._foo_prop

    @foo_prop.setter
    def foo_prop(self, val: int):
        self._foo_prop = val

If the signature is specified directly in the decorator the method and return type annotations are not inspected, but I have been careful to ensure that the correct data structures are still created for argument lists and signature trees.

I have added some testcases to the tests in test_decorators to validate the new feature.

@ahem
Copy link
Author

ahem commented Jan 6, 2022

The tests are passing, but the flake8 check is erroring on a bunch of things - also in files I haven't touched at all. I can easily fix the formatting across all files but I don't know if you would like that on top of this PR?

@acrisci
Copy link
Member

acrisci commented Jan 7, 2022

It was caused by a yapf update. Take b74742e and it should work with no changes.

Anders Hellerup Madsen added 4 commits January 7, 2022 08:42
The builtin @decorator property recreates itself when the .setter,
.getter or .deleter child-decorators are used. This meant that the
introspection meant for the getter was also being applied to the setter.
I added a guard for this situation to exit early, and instead copy the
already introspected properties over from the getter.
@ahem ahem force-pushed the support-signature-in-decorator branch from b2ead3c to c4fb5c7 Compare January 7, 2022 07:45
@ahem
Copy link
Author

ahem commented Jan 7, 2022

Okay, now all the tests and linting checks are passing

@ahem
Copy link
Author

ahem commented Jan 13, 2022

@acrisci did you have a chance to look at this PR? Is this a feature you are interested in, and if so is there anything I can do to help getting it merged?

@JohnFreeborg
Copy link

This sounds very attractive! Does this change also enable the use of named arguments in the client? We like to use those not to enable out of order argument passing or optional arguments, but just clarity to the next code maintainer on what the call is doing. Currently dbus_next doesn't work if you use them.

e.g.
@method()
def servicemethod(self, argname: 'd', argname2: 'd') -> 'd'
return argname * argname2

If I try to call the above like this, it doesn't work:
call_servicemethod(argname=1.2, argname2=54.3)

@ahem
Copy link
Author

ahem commented Jul 4, 2022

I don't believe that DBus itself supports optional arguments. At least, I think that it requires that all argument lists must be concretely typed. The normal way of supplying optional arguments is something with passing a dict or a "Varying".

I guess that you could argue that a "high level" abstraction interface shouldn't necessarily be limited by limitations from further down in the stack, but I guess in this case the maintainers have decided that it is more sensible for a DBus interface to follow this core rule of DBus communication.

Anyway, this PR doesn't really have anything to do with any of that - it was mostly something I did to enable dbus-next to be used in projects that check type annotation with mypy or pyright.

@endrift
Copy link

endrift commented Aug 3, 2023

I would really appreciate some traction on this for the same reason: it lets the type annotations be used as type annotations as opposed to being hijacked for a semantic purpose. mypy doesn't really like that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants