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

Document dict behavior when setting equal but not identical key #91081

Open
malthe mannequin opened this issue Mar 4, 2022 · 9 comments
Open

Document dict behavior when setting equal but not identical key #91081

malthe mannequin opened this issue Mar 4, 2022 · 9 comments
Labels
3.9 3.10 3.11 docs Documentation in the Doc dir type-bug An unexpected behavior, bug, or error

Comments

@malthe
Copy link
Mannequin

malthe mannequin commented Mar 4, 2022

BPO 46925
Nosy @rhettinger, @methane, @malthe, @JelleZijlstra, @potiuk
PRs
  • Replace key if not identical to old key in dict #31685
  • 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 = None
    closed_at = None
    created_at = <Date 2022-03-04.23:25:53.644>
    labels = ['3.11', 'type-bug', '3.9', '3.10', 'docs']
    title = 'Document dict behavior when setting equal but not identical key'
    updated_at = <Date 2022-03-07.10:13:25.530>
    user = 'https://github.com/malthe'

    bugs.python.org fields:

    activity = <Date 2022-03-07.10:13:25.530>
    actor = 'potiuk'
    assignee = 'docs@python'
    closed = False
    closed_date = None
    closer = None
    components = ['Documentation']
    creation = <Date 2022-03-04.23:25:53.644>
    creator = 'malthe'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 46925
    keywords = []
    message_count = 9.0
    messages = ['414554', '414560', '414562', '414572', '414581', '414586', '414607', '414636', '414652']
    nosy_count = 6.0
    nosy_names = ['rhettinger', 'methane', 'docs@python', 'malthe', 'JelleZijlstra', 'potiuk']
    pr_nums = ['31685']
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue46925'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Linked PRs

    @malthe
    Copy link
    Mannequin Author

    malthe mannequin commented Mar 4, 2022

    When a key that is equal to an existing key (but not the same object identity) is used to set a new value, the key itself is not replaced.

    This manifests perhaps most clearly in weakref.WeakKeyDictionary where keys can mysteriously disappear.

    Consider two equal keys, k1 and k2:

    d = WeakKeyDictionary()
    d[k1] = 1
    d[k2] = 2
    del k1

    We would expect the dictionary to have a single entry k2 => 2. But in fact it is empty now.

    @malthe malthe mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Mar 4, 2022
    @JelleZijlstra
    Copy link
    Member

    JelleZijlstra commented Mar 5, 2022

    As @methane also said on the PR, this is a backward compatibility break and we can't just change the behavior. I'd be opposed to a change here: the proposed behavior isn't clearly better than the existing behavior (sometimes you want one behavior, sometimes another), and it will be difficult to find and adjust code that relies on the existing behavior.

    @rhettinger
    Copy link
    Contributor

    rhettinger commented Mar 5, 2022

    I concur with Jelle and Methane that we can't do this without breaking code.

    Also if you don't care about dict order, the work around is easy. Just remove the old key:

    d.pop(k); d[k] = v
    

    @potiuk
    Copy link
    Mannequin

    potiuk mannequin commented Mar 5, 2022

    How about if we make PR instead to the documentation about this behaviour?

    I think this behaviour is a little surprising (you need to know the internals of how WeakKeyDict keys are constructed and checked) and while I understand you do not want breaking change, maybe this should be explained to the users and example given how to apply the workaround?

    Just following the "least surprise" principle.

    @JelleZijlstra
    Copy link
    Member

    JelleZijlstra commented Mar 5, 2022

    Agree, I couldn't find a place where this behavior is documented. The second paragraph in https://docs.python.org/3.10/library/stdtypes.html#mapping-types-dict comes close. Reopening as a documentation issue.

    @JelleZijlstra JelleZijlstra added 3.9 3.10 3.11 docs Documentation in the Doc dir and removed stdlib Python modules in the Lib dir labels Mar 5, 2022
    @JelleZijlstra JelleZijlstra reopened this Mar 5, 2022
    @JelleZijlstra JelleZijlstra changed the title Replace key if not identical to old key in dict Document dict behavior when setting equal but not identical key Mar 5, 2022
    @JelleZijlstra JelleZijlstra added docs Documentation in the Doc dir and removed stdlib Python modules in the Lib dir labels Mar 5, 2022
    @JelleZijlstra JelleZijlstra reopened this Mar 5, 2022
    @JelleZijlstra JelleZijlstra changed the title Replace key if not identical to old key in dict Document dict behavior when setting equal but not identical key Mar 5, 2022
    @rhettinger
    Copy link
    Contributor

    rhettinger commented Mar 5, 2022

    The weakref docs in particular should point out the OP's example and highlight the workaround.

    @malthe
    Copy link
    Mannequin Author

    malthe mannequin commented Mar 6, 2022

    Java's HashMap has also the (current) Python behavior. An existing same key is not replaced.

    @methane
    Copy link
    Member

    methane commented Mar 7, 2022

    I don't know much about Java, but Java's WeakHashMap is same to Python's WeakKeyDictionary.

    https://docs.oracle.com/javase/9/docs/api/java/util/WeakHashMap.html

    """
    This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a lookup of that key in a WeakHashMap at some later time and be surprised that its entry has been removed. This class will work perfectly well with key objects whose equals methods are not based upon object identity, such as String instances. With such recreatable key objects, however, the automatic removal of WeakHashMap entries whose keys have been discarded may prove to be confusing.
    """

    @potiuk
    Copy link
    Mannequin

    potiuk mannequin commented Mar 7, 2022

    Yeah. Sounds like adding docs is indeed needed :)

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    JelleZijlstra added a commit that referenced this issue Dec 21, 2022
    …aced entry (#91499)
    
    Co-authored-by: Pieter Eendebak <P.T.eendebak@tudelft.nl>
    Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
    miss-islington pushed a commit to miss-islington/cpython that referenced this issue Dec 21, 2022
    …a replaced entry (pythonGH-91499)
    
    (cherry picked from commit c615286)
    
    Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com>
    Co-authored-by: Pieter Eendebak <P.T.eendebak@tudelft.nl>
    Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
    miss-islington pushed a commit to miss-islington/cpython that referenced this issue Dec 21, 2022
    …a replaced entry (pythonGH-91499)
    
    (cherry picked from commit c615286)
    
    Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com>
    Co-authored-by: Pieter Eendebak <P.T.eendebak@tudelft.nl>
    Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
    miss-islington added a commit that referenced this issue Dec 21, 2022
    …aced entry (GH-91499)
    
    (cherry picked from commit c615286)
    
    Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com>
    Co-authored-by: Pieter Eendebak <P.T.eendebak@tudelft.nl>
    Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
    miss-islington added a commit that referenced this issue Dec 21, 2022
    …aced entry (GH-91499)
    
    (cherry picked from commit c615286)
    
    Co-authored-by: Stanley <46876382+slateny@users.noreply.github.com>
    Co-authored-by: Pieter Eendebak <P.T.eendebak@tudelft.nl>
    Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.9 3.10 3.11 docs Documentation in the Doc dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants