Issue 6737: PEP 372 odict.eq behaves incorrectly (original) (raw)

The current definition for odict.eq is def eq(self, other): if isinstance(other, OrderedDict): return all(p==q for p, q in _zip_longest(self.items(), other.items())) return dict.eq(self, other)

The current behavior of NotImplemented is:

if( NotImplemented ): ... print 'foo' foo dict.eq( {}, None ) NotImplemented if ( dict.eq( {}, None ) ): ... print 'oops' oops

The surprising behavior is:

if ( OrderedDict() != None ): ... print 'okie' ... else: ... print 'gah!' gah!

As best I understand it, normally other (in this case None) would be given the chance to evaluate other.eq( OrderedDict() ), but this doesn't seem to be happening.

I cannot reproduce your final example:

Python 2.7a0 (trunk, Aug 4 2009, 12:07:15)

from collections import OrderedDict [41375 refs] if (OrderedDict() != None): ... print 'okie' ... else: ... print 'gah' ... okie

Both are based on OrderedDict.eq defined as:

def __eq__(self, other):
    '''od.__eq__(y) <==> od==y.  Comparison to another OD is

order-sensitive while comparison to a regular mapping is order-insensitive.

    '''
    if isinstance(other, OrderedDict):
        return len(self)==len(other) and \
               all(p==q for p, q in zip(self.items(), other.items()))
    return dict.__eq__(self, other)

Other questions about your bug report.

Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information.

from collections import OrderedDict if (OrderedDict() != None): ... print('Okie') ... else: ... print('Gah')

Okie

Okie

I was running the odict.py file from the PEP, figured out that things were going off the rails at dict.eq and generalised, saw the same implementation in OrderedDict, I thought the same problem would exist. This is what I get for taking a shortcut.

I checked out the activestate recipe mentioned in which works.

The odict.py version, here is a literal paste from the pdb prompt (aside from changing some of the more private data to xxx): (Pdb) p urlConsolidationArtefact_row_prev odict.odict([(u'id', 58768L), (u'urlConsolidationRun_id', 22L), (u'valid', True), (u'validated', False), (u'refererUrl', u'http://search.yahoo.com/search?y=xxx'), (u'refererUrl_hash', '\xa60\xe2\xb8D\x7fv\x03\xb1=\xf3{\x15\xc0\xb0)'), (u'url', u'http://xxx'), (u'url_hash', '\x00\x00\xc8\xf3\xa3\x0f\x1d\xc2wn\xb4\xc7\xd7\xe1\xca3'), (u'updatedAt', datetime.datetime(2009, 8, 15, 10, 54, 15)), (u'createdAt', datetime.datetime(2009, 8, 15, 10, 54, 14))]) (Pdb) p urlConsolidationArtefact_row_prev != None False (Pdb) p urlConsolidationArtefact_row_prev == None False

So there is a problem at least in the odict module provided by http://dev.pocoo.org/hg/sandbox/raw-file/tip/odict.py (referenced in the PEP, once more prominently than now, I think).

Anyhow, I don't really know the details of what python does with NotImplemented but version you gave doesn't have the same problem, so I'll gladly use that instead.

If you can confirm that there's no deeper issue here, I'll be glad to close the bug.

Thanks for the help!