After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 338098 - Add signal/property helpers
Add signal/property helpers
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: gobject
Git master
Other Linux
: Normal normal
: ---
Assigned To: Johan (not receiving bugmail) Dahlin
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2006-04-11 16:02 UTC by Johan (not receiving bugmail) Dahlin
Modified: 2007-05-01 15:54 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
v1: Add gsignal/gproperty in gobject.utils (9.25 KB, patch)
2006-04-11 16:08 UTC, Johan (not receiving bugmail) Dahlin
none Details | Review
signals and properties alternative (8.30 KB, patch)
2006-04-16 15:17 UTC, Gustavo Carneiro
none Details | Review
patch (26.31 KB, patch)
2007-04-30 20:21 UTC, Johan (not receiving bugmail) Dahlin
none Details | Review

Description Johan (not receiving bugmail) Dahlin 2006-04-11 16:02:18 UTC
Defining signals and properties for an object is quite tricky, some of the
problems with the current situation:

* The API is just horrible, __gsignals__ and __gproperties__ is plain ugly.
* You need to specify reduntant information, in most cases it doesn't 
  matter when the signal is run nor what the return value is
* There's no way of getting good error messages, which makes it very frustrating  
  to specify properties, eg, some pspecs requires more parameters than others,   
  numeric types want maximum, minimum apart from the default
Comment 1 Johan (not receiving bugmail) Dahlin 2006-04-11 16:08:13 UTC
Created attachment 63244 [details] [review]
v1: Add gsignal/gproperty in gobject.utils

These are wrappers which I wrote some time ago and has been included in kiwi and various other places.
I'd welcome suggestions for API changes and improvements. The gproperty needs to be improved to always throw errors before type_register does, which is currently not the case. However it's still better than the current situation.
Comment 2 Gustavo Carneiro 2006-04-11 16:21:38 UTC
My 0.02€ (for starting):
 - Strip the 'g' prefix and move the functions into gobject module;
 - Don't use gobject.type_is_a; it is deprecated.
 - Not sure "float : _max('f')," on _MAX_VALUES is correct: max value of a floating point number cannot be calculated like that.
Comment 3 Johan (not receiving bugmail) Dahlin 2006-04-11 16:28:32 UTC
>  - Strip the 'g' prefix and move the functions into gobject module;

I disagree mainly because of the following two reasons:
* __init__.py should never do any aliasing, because it breaks the mapping of import statements to source files, eg if you see a line like:
   from foo.bar.baz import noogie
You can be sure that noogie is defined in a file called baz.py in the directory 
foo/bar.

* the gobject namespace should belong to gobject itself, not to python extensions or additions

>  - Don't use gobject.type_is_a; it is deprecated.

It is not deprecated. And it is actually not the same as isinstance or issubclass.

>  - Not sure "float : _max('f')," on _MAX_VALUES is correct: max value of a
> floating point number cannot be calculated like that.

That's one of the improvements that needs to be done, but we can't access G_MAXFLOAT currently.

Comment 4 Andy Wingo 2006-04-12 11:50:01 UTC
Having spent a bit of time thinking about the problem I don't have any better answer than these methods. At least they are documented.
Comment 5 Gustavo Carneiro 2006-04-16 15:17:12 UTC
Created attachment 63642 [details] [review]
signals and properties alternative

This patch adds an alternative, though similar, way of registering properties and signals. Examples:

Register a property:
    foo = gobject.property(str, default='bar')

Register a signal:
    my_signal = gobject.signal(int)
Comment 6 Gustavo Carneiro 2006-07-09 20:12:29 UTC
ping?
Comment 7 Johan (not receiving bugmail) Dahlin 2007-04-30 03:12:54 UTC
(In reply to comment #6)
> ping?
> 

okay, I think I generally like your patch, but I have a few questions:
- I found out a way of calculating the max/minimum value for float, it can be found in the trunk of kiwi.
- We need plenty of tests for this.
- Can we move the code to a separate module, to keep __init__.py smaller?

- It's a bit evil cleaning up all properties & signals. What are the disadvantages of leaving them there? [possible with more information stored such as args, max min etc]

A: gobject.property('name', int) 
B: name = gobject.property(int)

B is often preferred, but that implies that you can access the value after creating the class. [eg, no delattr as the patch does]

Perhaps we should include a little bit more metaclass magic if you use gobject.property so that obj.prop is roughly the same as obj.props.prop.

Signals are a little bit more complicated, perhaps we want to leave a reference to something which can be emitted and connected?

   obj.signal.emit()
   obj.signal.connect(func)

Will there be name space collissions in case of overriding?

If we want to do all this, should we also do it for signals/properties defined in __gsignals__/__gproperties__ ? API/ABI compatibilty might be too hard in that case.
Comment 8 Johan (not receiving bugmail) Dahlin 2007-04-30 20:21:58 UTC
Created attachment 87290 [details] [review]
patch

This adds a property helper similar to the one suggested by Gustavo in attachment 63642 [details] [review].
* custom getters & setters support
* Much improved maximum/minimum checks
* With unittests
* Some documentation
Comment 9 Gustavo Carneiro 2007-04-30 23:51:24 UTC
Only a quick glance, but something jumps at me: you are removing unit testing of old style properties and replacing with new unit tests.  I think we should continue to unit test even old properties because they need to continue working.

Another comment is, we already have a highly efficient C based property descriptor.  While I like a Python frontend for declaring and registering properties, once they're registered I would prefer to use the C descriptor.  This can be easily done by iterating over the class attributes of type gobject.property and replacing them with equivalent C descriptors.
Comment 10 Johan (not receiving bugmail) Dahlin 2007-05-01 00:11:46 UTC
(In reply to comment #9)
> Only a quick glance, but something jumps at me: you are removing unit testing
> of old style properties and replacing with new unit tests.  I think we should
> continue to unit test even old properties because they need to continue
> working.

It was a good way to find bugs in the code. Not sure if it's worth keeping the tests as they used to be. I didn't remove the tests themselves, only the way of defining the properties.

> Another comment is, we already have a highly efficient C based property
> descriptor.  While I like a Python frontend for declaring and registering
> properties, once they're registered I would prefer to use the C descriptor. 
> This can be easily done by iterating over the class attributes of type
> gobject.property and replacing them with equivalent C descriptors.

I'd prefer porting over the property class to C instead, that'd make most sense since there are other performance critical path (do_set/get_property, the default setters).
Keeping the current one as a reference implementation is probably a good idea.

I'm also not convinced that a C based implementation is going to be worth the effort, but I won't stop you if you want to spend your time doing that.

Comment 11 Gustavo Carneiro 2007-05-01 14:31:09 UTC
(In reply to comment #10)
> (In reply to comment #9)
> > Only a quick glance, but something jumps at me: you are removing unit testing
> > of old style properties and replacing with new unit tests.  I think we should
> > continue to unit test even old properties because they need to continue
> > working.
> 
> It was a good way to find bugs in the code. Not sure if it's worth keeping the
> tests as they used to be. I didn't remove the tests themselves, only the way of defining the properties.

But the old way properties are defined needs to keep working as usual, so it should continue to be tested IMHO.

> 
> > Another comment is, we already have a highly efficient C based property
> > descriptor.  While I like a Python frontend for declaring and registering
> > properties, once they're registered I would prefer to use the C descriptor. 
> > This can be easily done by iterating over the class attributes of type
> > gobject.property and replacing them with equivalent C descriptors.
> 
> I'd prefer porting over the property class to C instead, that'd make most sense
> since there are other performance critical path (do_set/get_property, the
> default setters).
> Keeping the current one as a reference implementation is probably a good idea.
> 
> I'm also not convinced that a C based implementation is going to be worth the
> effort, but I won't stop you if you want to spend your time doing that.

That's a good plan.  I'll see what (if anything) I can do to optimise, after the python based design is finalized and committed.  Too soon to worry about performance anyway.  Anyway, looks great.
Comment 12 Johan (not receiving bugmail) Dahlin 2007-05-01 14:50:52 UTC
(In reply to comment #11)

> But the old way properties are defined needs to keep working as usual, so it
> should continue to be tested IMHO.

Actually I disagree, since it's just syntactic sugar that is the difference.
We end up populating __gproperties__ with identical values.
The point of the tests are just to define properties, not the syntax used to define them!

> That's a good plan.  I'll see what (if anything) I can do to optimise, after
> the python based design is finalized and committed.  Too soon to worry about
> performance anyway.  Anyway, looks great.
> 

Good, I'll write some more tests and commit it.
Comment 13 Johan (not receiving bugmail) Dahlin 2007-05-01 15:54:02 UTC
Committed as revision 662.

I'll close this bug and open up a new one for a signal helper.