Python (and me) getting confused finding keys

Discussion in 'Python' started by John, Dec 22, 2009.

  1. John

    John Guest

    Hi there,

    I have a rather lengthy program that troubles me for quite some time. After
    some debugging, I arrived at the following assertion error:

    for e in edges.keys():
    assert edges.has_key(e)

    Oops!? Is there ANY way that something like this can possibly happen?

    Cheers,
    John
     
    John, Dec 22, 2009
    #1
    1. Advertising

  2. John

    Lie Ryan Guest

    On 12/23/2009 3:33 AM, John wrote:
    > Hi there,
    >
    > I have a rather lengthy program that troubles me for quite some time. After
    > some debugging, I arrived at the following assertion error:
    >
    > for e in edges.keys():
    > assert edges.has_key(e)
    >
    > Oops!? Is there ANY way that something like this can possibly happen?


    in a multithreaded program, it's possible another thread erased 'e'
    after the for-loop grabbed it but before the suite is executed.

    but often you'll get something like this:
    RuntimeError: dictionary changed size during iteration
     
    Lie Ryan, Dec 22, 2009
    #2
    1. Advertising

  3. On Tue, 22 Dec 2009 17:33:04 +0100, John wrote:

    > Hi there,
    >
    > I have a rather lengthy program that troubles me for quite some time.
    > After some debugging, I arrived at the following assertion error:
    >
    > for e in edges.keys():
    > assert edges.has_key(e)
    >
    > Oops!? Is there ANY way that something like this can possibly happen?


    In another post, you assert that:

    (1) You aren't knowingly using threads, so it's not likely that another
    thread is modifying edges.

    (2) edges is a regular dictionary, not a custom mapping class.


    In that case, I would say that the most likely culprit is that the edges
    are mutable but given a hash function. I can reproduce the problem like
    this:


    >>> class Edge:

    .... def __init__(self, start, finish):
    .... self.ends = (start, finish)
    .... def __eq__(self, other):
    .... return self.ends == other.ends
    .... def __hash__(self):
    .... return hash(self.ends)
    ....
    >>> edges = {Edge(1, 5): None}
    >>> for e in edges:

    .... assert e in edges # same as edges.has_key(e)
    .... e.ends = (5, 6)
    .... assert e in edges, "and now it's gone"
    ....
    Traceback (most recent call last):
    File "<stdin>", line 4, in <module>
    AssertionError: and now it's gone



    So the likely problem is that your edge type is mutable and being mutated.

    Now, if your code snippet above:

    for e in edges.keys():
    assert edges.has_key(e)


    is a literal copy-and-paste from the failing code, I can only assume that
    the edge type __eq__ or __hash__ method mutates self.

    The lesson of this? Do not make mutable classes hashable.

    The obvious follow-up is to ask how to make an immutable class.

    http://northernplanets.blogspot.com/2007/01/immutable-instances-in-python.html



    --
    Steven
     
    Steven D'Aprano, Dec 22, 2009
    #3
  4. * Steven D'Aprano:
    >

    [snip]
    > The obvious follow-up is to ask how to make an immutable class.
    >
    > http://northernplanets.blogspot.com/2007/01/immutable-instances-in-python.html


    Thanks, I've been wondering about that.

    By the way, the link at the bottom in the article you linked to, referring to an
    earlier posting by Alex Martelli, was broken.

    I believe it was the posting available here: <url:
    http://www.opensubscriber.com/message//2659890.html>.


    Cheers,

    - Alf
     
    Alf P. Steinbach, Dec 23, 2009
    #4
  5. John

    John Guest

    John, Dec 23, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sandeep Kanwal

    serial keys/validation keys

    sandeep Kanwal, Oct 29, 2004, in forum: C++
    Replies:
    1
    Views:
    585
    Mike Wahler
    Oct 29, 2004
  2. Harry George
    Replies:
    9
    Views:
    707
    sonal
    Jun 13, 2006
  3. Replies:
    10
    Views:
    729
    Daniel T.
    Feb 3, 2006
  4. alan
    Replies:
    3
    Views:
    367
    Victor Bazarov
    Nov 28, 2007
  5. A. Farber
    Replies:
    10
    Views:
    238
    A. Farber
    Jun 12, 2004
Loading...

Share This Page