Skip to content

Add 'singledispatch' to the __subclasscheck__ whitelist in the python2.7 port #405

Description

@adetokunbo

Hi,

I'm trying to add python2.7 support to cattrs, which is an experimental library for converting Python data (see rtd for more detailed info).

cattrs uses typing.py for runtime conversions, along with singledispatch.

For the main python3 version of typing.py this works as expected. However, there is a discrepancy between the python2 port of typing.py and python3 version that breaks use of singledispatch in python2.

This check,

    def __subclasscheck__(self, cls):
        if self.__origin__ is not None:
            if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']:
                raise TypeError("Parameterized generics cannot be used with class "
                                "or instance checks")
      ...

determines if a TypeError should be thrown when issubclass() is called on the parameterized type. If the calling code is from the 'functools' or 'abc' module then it's allowed. In python3, this allows the singledispatch function to dispatch on parametrized generic types.

However, in python2.7, the singledispatch function is not part of the functools module. It's provided in in a separate backport module named 'singledispatch'. Hence, that check currently fails in python2.7 in situations it would pass in python3.x.

A simple fix would be to add 'singledispatch' to the whitelist in the python2 port:

    def __subclasscheck__(self, cls):
        if self.__origin__ is not None:
            if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools', 'singledispatch']:
                raise TypeError("Parameterized generics cannot be used with class "
                                "or instance checks")
      ...

Please let me know if this change makes sense, I'm quite happy to send a PR to make the change.
If so, I'd like to try and get it done in time for the (3.6.1 release)[#403].

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions