Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

functools.singledispatch fails when "not BaseClass" is True #67760

Closed
SergioPascual mannequin opened this issue Mar 3, 2015 · 9 comments
Closed

functools.singledispatch fails when "not BaseClass" is True #67760

SergioPascual mannequin opened this issue Mar 3, 2015 · 9 comments
Assignees
Labels
stdlib Python modules in the Lib dir

Comments

@SergioPascual
Copy link
Mannequin

SergioPascual mannequin commented Mar 3, 2015

BPO 23572
Nosy @pfmoore, @ambv, @serhiy-storchaka, @1st1
Files
  • singledispatch-test.py: A class that breaks singledispatch
  • issue23572.stoneleaf.01.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ambv'
    closed_at = <Date 2015-08-18.18:24:22.035>
    created_at = <Date 2015-03-03.12:17:09.172>
    labels = ['library']
    title = 'functools.singledispatch fails when "not BaseClass" is True'
    updated_at = <Date 2015-09-04.17:23:56.610>
    user = 'https://bugs.python.org/SergioPascual'

    bugs.python.org fields:

    activity = <Date 2015-09-04.17:23:56.610>
    actor = 'lukasz.langa'
    assignee = 'lukasz.langa'
    closed = True
    closed_date = <Date 2015-08-18.18:24:22.035>
    closer = 'yselivanov'
    components = ['Library (Lib)']
    creation = <Date 2015-03-03.12:17:09.172>
    creator = 'Sergio Pascual'
    dependencies = []
    files = ['38314', '39398']
    hgrepos = []
    issue_num = 23572
    keywords = ['patch']
    message_count = 9.0
    messages = ['237126', '242291', '242381', '243374', '248685', '248782', '248783', '248784', '249792']
    nosy_count = 7.0
    nosy_names = ['paul.moore', 'lukasz.langa', 'python-dev', 'serhiy.storchaka', 'yselivanov', 'Drekin', 'Sergio Pascual']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'patch review'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue23572'
    versions = ['Python 3.4', 'Python 3.5', 'Python 3.6']

    @SergioPascual
    Copy link
    Mannequin Author

    SergioPascual mannequin commented Mar 3, 2015

    I admit this case is rather convoluted, but I have been debugging a few hours so I think I should share my findings.

    I have a metaclass MetaA that provides to the classes constructed with it have a dictionary interface. Of all the functions only __len__ is important. In some cases, the result of __len__ is 0 and that is what triggers the error

    class MetaA(type):
        def __len__(self):
            return 0
    
    class A(metaclass=MetaA):
        pass
    
    class AA(A):
        pass

    Now, I construct a function with single dispatch and register the case of class A but not the class AA

    @singledispatch
    def fun(a):
        print('base case')
    
    @fun.register(A)
    def _(a):
        print('fun A')

    And then, call fun with an object of class AA

    fun(AA())

    This should call the function for the class up in the hierarchy, A
    Instead it raises an exception

    RuntimeError: Inconsistent hierarchy

    in function functools._c3_merge
    because in the line

    if not candidate:
        raise RuntimeError("Inconsistent hierarchy")

    "not candidate" evaluates to True due to __len__ returning 0

    This can be avoided by:

    • adding __nonzero__ to MetaA

    • not adding the map interface to a class in the first place

    • changing the code in _c3_merge

    I'm not really sure, but instead of:

    if not candidate:
        raise RuntimeError("Inconsistent hierarchy")

    would this work?

    if candidate is None:
        raise RuntimeError("Inconsistent hierarchy")

    I attach a test case

    @SergioPascual SergioPascual mannequin added the stdlib Python modules in the Lib dir label Mar 3, 2015
    @ambv
    Copy link
    Contributor

    ambv commented Apr 30, 2015

    Yes, this needs addressing.

    @ambv ambv self-assigned this Apr 30, 2015
    @serhiy-storchaka
    Copy link
    Member

    An example is Enum.

    @ethanfurman
    Copy link
    Member

    Attached is patch and test case.

    @Drekin
    Copy link
    Mannequin

    Drekin mannequin commented Aug 16, 2015

    I was also bitten by this via Enum. Is there any chance this will be fixed in Python 3.5?

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Aug 18, 2015

    New changeset 73984e665bf5 by Yury Selivanov in branch '3.5':
    Issue bpo-23572: Fixed functools.singledispatch on classes with falsy metaclasses.
    https://hg.python.org/cpython/rev/73984e665bf5

    New changeset 94d0c219d46f by Yury Selivanov in branch 'default':
    Merge 3.5 (issue bpo-23572)
    https://hg.python.org/cpython/rev/94d0c219d46f

    @1st1
    Copy link
    Member

    1st1 commented Aug 18, 2015

    I was also bitten by this via Enum. Is there any chance this will be fixed in Python 3.5?

    It will be fixed in 3.5.1.

    Thanks for the patch, Ethan!

    @1st1 1st1 closed this as completed Aug 18, 2015
    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Aug 18, 2015

    New changeset 586195685aaf by Yury Selivanov in branch '3.4':
    Issue bpo-23572: Fixed functools.singledispatch on classes with falsy metaclasses.
    https://hg.python.org/cpython/rev/586195685aaf

    @ambv
    Copy link
    Contributor

    ambv commented Sep 4, 2015

    Thank you for fixing this and sorry for not being responsive sooner!

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    stdlib Python modules in the Lib dir
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants