morepath / reg

Clever dispatch
https://reg.readthedocs.org
BSD 3-Clause "New" or "Revised" License
76 stars 12 forks source link

Dispatchable ABC interface not supported #22

Open ccomb opened 9 years ago

ccomb commented 9 years ago

Hi! I've tried to create an interface similar to z3 ones, but as an ABC, and register it as the dispatchable callable without creating a separate function, so that I can write IStuff(obj) to retrieve an adapter of obj implementing IStuff. (I really liked this syntax for the lookup).

Something like:

@reg.dispatch('entity')
class IStuff(metaclass=ABCMeta):

    @abstractmethod
    def __init__(context):
        pass

    @abstractmethod
    def foobar():
        """Foobar doc"""

It doesn"t work. The first reason is that get_callable_info does not support abstract classes. It's just a matter of adding this in it (and assuming the __init__ is an abstractmethod):

if inspect.isabstract(callable):
    return get_class_init(callable), callable, False

Once this is fixed, I get another issue in register_function_by_predicate_key because the arginfo(value) is using the Dispatcher constructor instead of the decorated class constructor (the abc interface), so the signature is not the same: 'context' is not found I've not gone further.

Otherwise thanks a lot for reg, it's a very nice replacement for the zca!

faassen commented 8 years ago

Hey, thank you for reporting this issue. Sorry it took a while for me to get to it.

I'd be very welcome to see patches to make this work. We need to make it understand abcs to do so. Just a patch that contains some tests of what you'd like to work would be helpful.

Note that I went full-on for generic functions in the end in Morepath so don't use this zca style pattern.

To construct the right mro for a class that contains abcs we will need something like code I originally found in Python single dispatch logic to insert abcs in the right places in the class hierarchy. Here's a revision that contains that code still:

https://github.com/morepath/reg/commit/820055ecced666195bff2b8bcadb86b61c7ec925