GNOME Bugzilla – Bug 360992
Cannot create/add to StateSet object
Last modified: 2007-04-06 22:39:01 UTC
To use Collection, pyORBit clients must be able to instantiate StateSet objects and add states. In GNOME 2.14, this doesn't appear to be possible: import ORBit, bonobo orb = ORBit.CORBA.ORB_init() ORBit.load_typelib('Accessibility') import Accessibility as a import Accessibility__POA as ap ss = a.StateSet() # Traceback (most recent call last): # File "<stdin>", line 1, in ? # NotImplementedError: can not construct objecre references ss = ap.StateSet() ss.add(a.STATE_VISIBLE) # Traceback (most recent call last): # File "<stdin>", line 1, in ? # AttributeError: 'StateSet' object has no attribute 'add' ss._this().add(a.STATE_VISIBLE) # Traceback (most recent call last): # File "<stdin>", line 1, in ? # CORBA.NO_IMPLEMENT
Willie, Do you have any comments for this bug?
Peter's a smart guy and knows Python well. This does indeed look like a problem for GNOME 2.14 as Peter describes. I'm not sure, however, that the Collection stuff was really supported then. Peter, does it work with anything later (e.g., GNOME 2.16, GNOME 2.17.x)?
Hey guys. I tested the code above in GNOME 2.16 with the same results. Will is right that this behavior wasn't a problem in GNOME 2.14 because Collection did not exist yet. It's not a problem in GNOME 2.16/2.18 either because Collection is still in the process of being implemented. However, when we get to 2.20, then it becomes a bug because an AT-SPI client will need to be able to construct StateSet objects when building a match rule. See http://www.gnome.org/~billh/at-spi-new-idl/html/html/classAccessibility_1_1Collection.html#a1 The other set types are not a problem (at present) because they're defined as base sequence types, not IDL defined classes. In Python, for instance, I can build a RoleSet using a list: rs = [ROLE_BUTTON, ROLE_WINDOW]
Peter, Li and I are not familar with Python bindings. Could you please take a look at at-spi/libspi/atkstates.c and let us know what should be done to fix this bug? Patches are welcome :)
I don't understand the issue, since Accessibility_StateSet is an interface (as defined in Accessibility_State.idl), and libspi's state.c shows implementations for an 'add' method and a spi_state_set_new() constructor. SpiStateSet is a GObject, so python bindings should be able to instantiate one just as they can instantiate other object instances.
With Bill's pointer, I can see the implementation certainly exists in libspi. So perhaps I'm just using the wrong incantation to instantiate from Python. I will look into using gobject to create a new set instead of PyORBit. You can mark this bug as not at-spi at least. I'll reopen with the Python bindings for gobject or ORBit if need be.
OK, mark as invalid for now.
Peter, Can you try the following: import ORBit, bonobo orb = ORBit.CORBA.ORB_init() ORBit.load_typelib('Accessibility') import Accessibility as a import Accessibility__POA as ap def info(object, spacing=10, collapse=1): """Print methods and doc strings. Takes module, class, list, dictionary, or string.""" methodList = [method for method in dir(object) if callable(getattr(object, method))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList]) s = a.StateSet z = s.STATE_VISIBLE info(s) s.add(z) s.getStates()
Ariel, That code throws an exception on z = s.STATE_VISIBLE because that constant is not a member of the StateSet class. If I change z = s.STATE_VISIBLE to z = a.STATE_VISIBLE (which where the constant actually resides) I get the following printout followed by an exception: If I remove that line entirely and just have it print out the info of the StateSet class, I get the following: __class__ type(object) -> the object's type type(name, bases, dict) -> a new type __cmp__ x.__cmp__(y) <==> cmp(x,y) __delattr__ x.__delattr__('name') <==> del x.name __getattribute__ x.__getattribute__('name') <==> x.name __hash__ x.__hash__() <==> hash(x) __init__ x.__init__(...) initializes x; see x.__class__.__doc__ for signature __new__ T.__new__(S, ...) -> a new object with type S, a subtype of T __reduce__ helper for pickle __reduce_ex__ helper for pickle __repr__ x.__repr__() <==> repr(x) __setattr__ x.__setattr__('name', value) <==> x.name = value __str__ x.__str__() <==> str(x) _duplicate _duplicate() -> CORBA.Object _hash _hash(maximum) -> int _is_a _is_a(type_id) -> boolean _is_equivalent _is_equivalent(other) -> boolean _is_nil _is_nil() -> boolean _narrow _narrow(stub) -> object _non_existent _non_existent() -> boolean add add(state) -> 'IDL:omg.org/CORBA/void:1.0' compare compare(compareState) -> 'IDL:Accessibility/StateSet:1.0' contains contains(state) -> 'IDL:omg.org/CORBA/boolean:1.0' equals equals(stateSet) -> 'IDL:omg.org/CORBA/boolean:1.0' getStates getStates() -> 'IDL:Accessibility/StateSeq:1.0' isEmpty isEmpty() -> 'IDL:omg.org/CORBA/boolean:1.0' queryInterface queryInterface(repoid) -> 'IDL:Bonobo/Unknown:1.0' ref ref() -> 'IDL:omg.org/CORBA/void:1.0' remove remove(state) -> 'IDL:omg.org/CORBA/void:1.0' unImplemented unImplemented() -> 'IDL:omg.org/CORBA/void:1.0' unImplemented2 unImplemented2() -> 'IDL:omg.org/CORBA/void:1.0' unImplemented3 unImplemented3() -> 'IDL:omg.org/CORBA/void:1.0' unImplemented4 unImplemented4() -> 'IDL:omg.org/CORBA/void:1.0' unref unref() -> 'IDL:omg.org/CORBA/void:1.0' Traceback (most recent call last):
+ Trace 116174
s.add(z)
The reason for this error is that the code is trying to call a method on the StateSet class rather than an instance. The first arg it is looking for is the self reference to the instance and the code is giving it the STATE_VISIBLE constant instead. If you try to make an instance, you run into the problem I filed above (which I still haven't been able to resolve using gobject.new from Python).
Transferring from at-spi to pyorbit. Please read the original comment for a description of the problem. We have since confirmed that StateSet objects can be constructed in Scheme using ORBit, so it seems like the problem is related to pyorbit (or at least my understanding of pyorbit).
Created attachment 85914 [details] working code You cannot directly instantiate StateSet; it is an abstract servant base class, and has to be subclassed and implemented in Python before it can be used. That's what the NOIMPLEMENT exception means: "no implementation" :)
If I need to hand one of these StateSet objects I implemented in Python back to a CORBA method, is the object on the other side of the connection going to know what to do with it?
(In reply to comment #12) > If I need to hand one of these StateSet objects I implemented in Python back to > a CORBA method, is the object on the other side of the connection going to know > what to do with it? > You have to implement all the methods in Python, add/remove/compare/etc.. Then you hand over a corba objref to the client (_this()) and the client invokes methods on it. The client doesn't know the object is implemented in Python.
That clears it up. Thanks!