enthought / traits

Observable typed attributes for Python classes
Other
436 stars 85 forks source link

Unexpected supports_protocol behavior #591

Open rahulporuri opened 4 years ago

rahulporuri commented 4 years ago

We use supports_protocol to check if objects being handled can be adapted to a specific protocol and use the information appropriately.

Trying to adapt an object to a specific protocol can result in three behaviors

At the moment, the AdaptationErrors are not handled by supports_protocol, which we believe they should. The adapters registered could be explicitly raising AdaptationErrors - which should be caught by supports_protocol, which would then return False.

https://github.com/enthought/traits/blob/5dddc966b8f87e5550e83c98e14b4a251b33b561/traits/adaptation/adaptation_manager.py#L183-L191

rahulporuri commented 4 years ago

Here's an example to reproduce the issue. When I run the code, I expect to see True and False but instead we see the AdaptationError.

from traits.api import *
from traits.adaptation.api import *

class A(HasTraits):
    a = Int

class AdaptedA(Adapter):
    adaptee = Instance(A)
    positive_a = Int
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.adaptee.a <= 0:
            raise AdaptationError("a should be > 0")

def an_adapter(adaptee):
    return AdaptedA(adaptee)

adaptation_mgr = get_global_adaptation_manager()
adaptation_mgr.register_offer(
    AdaptationOffer(
        factory=an_adapter,
        from_protocol=A,
        to_protocol=AdaptedA,
    )
)

inst = A(a=1)
another_inst = A(a=-1)

print("adaptation works? - {}".format(supports_protocol(inst, AdaptedA)))
print("adaptation works? - {}".format(supports_protocol(another_inst, AdaptedA)))