Nova's test suite fails with python 2.7.2rc1

Bug #791221 reported by Soren Hansen
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Compute (nova)
Invalid
Undecided
Unassigned
Python
Invalid
Unknown
nova (Ubuntu)
Invalid
Medium
Unassigned
python-mox (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

This is the error from the build log

======================================================================
ERROR: test_compute_can_update_available_resource (nova.tests.test_service.ServiceTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/build/buildd/nova-2011.3~d2~20110601.1130/nova/tests/test_service.py", line 334, in test_compute_can_update_available_resource
    {'wait': wait_func})
  File "/usr/lib/pymodules/python2.7/mox.py", line 256, in CreateMock
    new_mock = MockObject(class_to_mock, attrs=attrs)
  File "/usr/lib/pymodules/python2.7/mox.py", line 553, in __init__
    for method in dir(class_to_mock):
TypeError: __dir__() must return a list, not MockMethod

It turns out the semantics around __dir__ changed in 2.7.2. I'm guessing we're mocking a mock object, and MockAnything's __init__ calls dir(class_to_mock) which calls __dir__ which gets intercepted by __getattr__ (or maybe __call__ I'm not sure right now), which returns a MockMethod rather than a list.

Revision history for this message
Soren Hansen (soren) wrote :

I've not had time to whip up anything coherent to file a bug report upstream. If someone else wants to, please feel free to do so.

Revision history for this message
Chuck Short (zulcss) wrote :
Soren Hansen (soren)
summary: - Test suite fails with python 2.7.2rc1
+ Nova's test suite fails with python 2.7.2rc1
Soren Hansen (soren)
Changed in nova (Ubuntu):
importance: Undecided → Medium
Revision history for this message
Barry Warsaw (barry) wrote :

It's almost certainly related to this entry in Misc/NEWS:

- Correct lookup of __dir__ on objects. Among other things, this causes errors
  besides AttributeError found on lookup to be propagated.

and this log entry:

changeset: 70312:b2fc6b9f850f
branch: 2.7
parent: 70304:9d004a9a2ced
user: Benjamin Peterson <email address hidden>
date: Mon May 23 16:11:05 2011 -0500
files: Lib/test/test_descr.py Misc/NEWS Objects/object.c
description:
correctly lookup __dir__

As there's no issue number to link this to the Python tracker, I need to as Benjamin why this change was made and whether it's really appropriate for an rc, let alone a patch release.

Revision history for this message
Soren Hansen (soren) wrote :

This reproduces the problem:

=== mymodule.py ===

class MyClass(object):
    pass

=== reproduce.py ===

import mox
import mymodule

class Test(object):
    def __init__(self):
        self.mox = mox.Mox()
        self.mox.StubOutWithMock(mymodule, 'MyClass', use_mock_anything=True)
        self.mox.CreateMock(mymodule.MyClass)

Test()

I don't know if this is CPython changing its behaviour to be closer to spec and pymox depending on CPython implementation details. I'm hoping someone else can clear this up.

Revision history for this message
Barry Warsaw (barry) wrote :

I think this one is even simpler to illustrate the change:

class Foo:
    def __dir__(self):
        return ['a', 'b', 'c']

class Bar:
    def __dir__(self):
        return ('a', 'b', 'c')

print dir(Foo())
print dir(Bar())

AFAICT, in Python 2.7.1 you get two lines of ['a', 'b', 'c'] while in 2.7.2rc2, the second line gives you the TypeError.

Revision history for this message
Barry Warsaw (barry) wrote :
Revision history for this message
Benjamin Peterson (benjaminp) wrote :

This is what you actually get on 2.7.1:

$ python
Python 2.7.1 (r271:86832, Mar 24 2011, 22:44:47)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo:
... def __dir__(self):
... return ['a', 'b', 'c']
...
>>> class Bar:
... def __dir__(self):
... return ('a', 'b', 'c')
...
>>> print dir(Foo())
['__dir__', '__doc__', '__module__']
>>> print dir(Bar())
['__dir__', '__doc__', '__module__']

So __dir__ was actually completely broken on old-style classes in 2.7.1. You're only seeing the behavior it would have had if __dir__ worked.

Changed in python:
status: Unknown → New
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package python-mox - 0.5.3-1ubuntu2

---------------
python-mox (0.5.3-1ubuntu2) oneiric; urgency=low

  * python-2.7.2-compat.patch: Python 2.7.2 calls __dir__ for old-style
    classes. Make sure a MockAnything returns a list of some sort
    instead of a MockMethod (LP: #791221)
 -- Soren Hansen <email address hidden> Mon, 06 Jun 2011 10:36:48 +0200

Changed in python-mox (Ubuntu):
status: New → Fix Released
Revision history for this message
Thierry Carrez (ttx) wrote :

Anything left to do on Nova upstream or ubuntu/nova packaging ?

Revision history for this message
Chuck Short (zulcss) wrote :

Thierry: No

Thierry Carrez (ttx)
Changed in nova:
status: New → Invalid
Changed in nova (Ubuntu):
status: New → Invalid
Changed in python:
status: New → Invalid
Revision history for this message
Barry Warsaw (barry) wrote :

BTW, reverting/working around the change was rejected for 2.7.2 so upstream will need to adjust.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.