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

dict.update() optimisation gives unexpected/invalid results when passed a subclass of DictType #47708

Closed
david mannequin opened this issue Jul 28, 2008 · 3 comments
Closed
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@david
Copy link
Mannequin

david mannequin commented Jul 28, 2008

BPO 3458
Nosy @rhettinger
Files
  • dictionary.patch: proposed patch against python 2.5.2
  • 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/rhettinger'
    closed_at = <Date 2008-07-29.00:17:50.617>
    created_at = <Date 2008-07-28.16:24:26.315>
    labels = ['interpreter-core', 'type-bug']
    title = 'dict.update() optimisation gives unexpected/invalid results when passed a subclass of DictType'
    updated_at = <Date 2008-07-29.00:17:50.577>
    user = 'https://bugs.python.org/david'

    bugs.python.org fields:

    activity = <Date 2008-07-29.00:17:50.577>
    actor = 'rhettinger'
    assignee = 'rhettinger'
    closed = True
    closed_date = <Date 2008-07-29.00:17:50.617>
    closer = 'rhettinger'
    components = ['Interpreter Core']
    creation = <Date 2008-07-28.16:24:26.315>
    creator = 'david'
    dependencies = []
    files = ['10997']
    hgrepos = []
    issue_num = 3458
    keywords = ['patch']
    message_count = 3.0
    messages = ['70353', '70363', '70373']
    nosy_count = 2.0
    nosy_names = ['rhettinger', 'david']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = None
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue3458'
    versions = ['Python 2.6', 'Python 2.5']

    @david
    Copy link
    Mannequin Author

    david mannequin commented Jul 28, 2008

    Using a python module that expected me to pass a dictionary as a
    parameter to a function, I found that I was getting unexpected results
    when using a class which inherits from types.DictType.

    The module was passing the instance I had supplied as a parameter to
    update() on a newly created dictionary. I wanted my class to present its
    methods as items of the dictionary it was pretending to be. Even though
    I could see that __getattribute__ had been called to get 'keys', keys()
    was not called and I ended up with an empty dictionary.

    Trying to find the cause of the problem, I downloaded the python source
    package and found that in PyDict_Merge (in Objects/dictobject.c, line
    1359), there is an optimisation that is run if PyDict_Check determines
    that the parameter we passed is itself a dictionary. The optimisation
    takes advantage of the fact that we know how data is stored in the
    dictionary and accesses whatever it needs directly.

    I had overridden keys() to provide the result I wanted but this
    optimisation prevented the code from ever being run, leading to code
    that seems like it should work failing with no apparent cause. The only
    way I could find around this was to raise AttributeError in
    __getattribute__ when getting 'keys', causing dict_update_common to call
    PyDict_MergeFromSeq2 in place of PyDict_Merge.

    Should the call to PyDict_Check in PyDict_Merge not be replaced with
    PyDict_CheckExact ? This would keep the optimisation in place in most
    cases, where we know that it is safe, still allowing keys() to be
    overridden as you expect.

    @david david mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Jul 28, 2008
    @rhettinger
    Copy link
    Contributor

    Will look back in my notes. I believe this was previously discussed
    and rejected.

    @rhettinger rhettinger self-assigned this Jul 28, 2008
    @rhettinger
    Copy link
    Contributor

    This is duplicate of http://bugs.python.org/issue1615701 . The
    check_exact solution was attempted once but it broke code in a subtle
    and hard to find way so it had to be reverted. For your use case, try
    UserDict instead of subclassing dict.

    @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
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant