Difficulty with `cmp', still

Gordon McMillan gmcm at hypernet.com
Tue Sep 21 17:01:05 EDT 1999


François Pinard wrote:

> Hi, people.  I feel a bit opaque, as I cannot quickly get this
> code to work:

Oh no, don't feel opaque.  
 
> # Return the comparison value of two versions, of two file names
> # with versions.
> def compare_versions(a, b):
>     a0, a1, a2, a3, a4 = _weights(a)
>     b0, b1, b2, b3, b4 = _weights(b)
>     print dir(__builtins__)
>     cmp = __builtins__.cmp              # because of `import cmp'
>     above return cmp(a0, b0) or a1 - b1 or a2 - b2 or a3 - b3 or
>     a4 - b4
> 
> 
> When used in batch, I get "AttributeError: cmp".  When used
> interactively, everything seems to work fine, and
> `compare_versions' does what it should. The `print' statement is
> a mere try to understanding the problem, and it has the effect of
> adding this line to the output, just before the traceback:
> 
> 
> ['clear', 'copy', 'get', 'has_key', 'items', 'keys', 'update',
> 'values']
> 
> 
> If I do the same `print' interactively, I get (refilled in this
> message):
> 
> 
> ['ArithmeticError', 'AssertionError', 'AttributeError',
> 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception',
> 'FloatingPointError', 'IOError', 'ImportError', 'IndexError',
> 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError',
> 'NameError', 'None', 'NotImplementedError', 'OSError',
> 'OverflowError', 'RuntimeError', 'StandardError', 'SyntaxError',
> 'SystemError', 'SystemExit', 'TypeError', 'ValueError',
> 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
> '__name__', 'abs', 'apply', 'buffer', 'callable', 'chr', 'cmp',
> 'coerce', 'compile', 'complex', 'delattr', 'dir', 'divmod',
> 'eval', 'execfile', 'exit', 'filter', 'float', 'getattr',
> 'globals', 'hasattr', 'hash', 'hex', 'id', 'input', 'int',
> 'intern', 'isinstance', 'issubclass', 'len', 'list', 'locals',
> 'long', 'map', 'max', 'min', 'oct', 'open', 'ord', 'pow', 'quit',
> 'range', 'raw_input', 'reduce', 'reload', 'repr', 'round',
> 'setattr', 'slice', 'str', 'tuple', 'type', 'vars', 'xrange']
> 
> 
> So far that I know, I'm not playing tricks nor trying to more
> clever than Python, I would think my code is rather straight. 
> I'm surely not trying to play with the builtin lists, the most I
> do is trying to get the `cmp' from it.  I do not see how or why
> the builtin list get reduced when my code is executed in batch,
> and why `cmp' is disappearing.  Would someone have a suggestion
> or an idea of what I should study to grasp what is happening?

It's a wrinkle in the space-time continuum that interactive is 
smart enough to navigate, but batch mode falls right into.

You need to:
 
import __builtin__

and use __builtin__.cmp

This is the real source of the builtins (it's a module). 
__builtins__ is a dictionary. Recall things like eval and exec, 
where you can pass a globals dict. If this dict is empty, 
Python will stuff an entry "__builtins__" into it for the eval'ed / 
exec'ed code to use. I'm not really sure of the sequence of 
events here, but apparently the shortcut hasn't been properly 
prepared when you try to use it!

BTW, I fell for it, and voluteered to carry out the BDFL's 
"suggestion".

- Gordon




More information about the Python-list mailing list