Is UserList.py "strange" or is it cmp()?

Tom Funk _spam_sux_tdfunk at _spam_sux_nettally.com
Tue Mar 14 13:13:40 EST 2000


I was writing a class based on UserList.  The class showed some "strange" 
behaviors when I was writing some test scripts for it.  I've isolated at 
least one of the problems to a bug (??) in UserList.py, or in cmp().  I 
placed some print statements into UserList.py to watch what happens.  
It's a bit odd.... perhaps someone can enlightment me as to why the 
following occurs:

  PythonWin 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] 
    on win32
  Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
  Portions Copyright 1994-2000 Mark Hammond (MHammond at skippinet.com.au)  
  >>> aList = [0,1,2,3]
  >>> from UserList import UserList
  >>> ul = UserList(aList) # duplicates code in test_userlist.py
  >>> aList
  [0, 1, 2, 3]
  >>> ul
  [0, 1, 2, 3]
  >>> ul == aList
  in UserList.__cmp__(self=[0, 1, 2, 3], other=[0, 1, 2, 3]):
     false leg: cmp(self.data, other)=0
  1
  >>> cmp(ul,aList)
  in UsreList.__cmp__(self=[0, 1, 2, 3], other=[0, 1, 2, 3]):
     false leg: cmp(self.data, other)=0
  0
  >>> type(ul) 
  <type 'instance'>
  >>> type(aList)
  <type 'list'>

__cmp__ is called for both the equality check (==) and the explicit call 
to cmp(), however, __cmp__() *appears* to return different values for 
different calls -- even though cmp() always returns 0 (not equal).  What 
gives?  Is one of the other "magic methods" in UserList also getting 
called and indicating inequality (UserList.__len__() is *not* called -- I 
checked)?

Also, since __cmp__() itself calls cmp(), why doesn't this recurse?  From 
the interactive session, cmp() calls __cmp__, yet when __cmp__{) calls 
cmp(), it calls the built-in cmp(), it doesn't recurse to __cmp__().  Why 
doesn't the interactive cmp(ul,aList) go straight to the built-in?  Why 
doesn't __cmp__() recurse when calling cmp()?  Enquiring minds want to 
know... <g>

Fwiw, this behavior also breaks test_userlist.py:

  Traceback (innermost last):
    File "D:\Python\Lib\test\test_userlist.py", line 70, in ?
      assert u2[:i] == l2[:i]
  AssertionError

Here's the code from UsreList.py:

  def __cmp__(self, other):
      print"in UserList.__cmp__(self=%s, other=%s):" %( `self`, `other`)
      if isinstance(other, UserList):
          c = cmp(self.data, other.data)
          print "  true leg: cmp(self.data, other.data)=" + `c`
      else:
          c = cmp(self.data, other)
          print "  false leg: cmp(self.data, other)=" + `c` 
      return c
  def __len__(self):
      print "UserList.__len__(self=%s):" %(`self`)
      theLen = len(self.data)
      print "len(self.data): %d" % (theLen)
      return theLen

Does anyone have any thoughts on these mysteries?

Thanks ahead of time for your feedback.

P.S.: Please see also note my upcoming post on a related UserList issue:  
UserList.__getslice__(): copy.copy(self.data) vs. 
self.__class__(self.data).

-- 
-=< tom >=-
Thomas D. Funk                           |        "Software is the lever
Software Engineering Consultant          | Archimedes was searching for"
Advanced Systems Design, Tallahassee FL. |




More information about the Python-list mailing list