help: Unit test fixture returning the same object
Michael McCracken
mmccrack at gradlab.ucsd.edu
Wed Aug 4 15:25:47 EDT 2004
Roy Smith <roy at panix.com> writes:
> michael_mccracken at mac.com (Michael McCracken) wrote:
> > So, I'm still surprised that id() would point to the same object every
> > time, but I'm willing to believe it. However, I don't think that's the
> > only thing that's going on - the reason I noticed this in the first
> > place is that the setUp method was opening a file and populating some
> > lists in my File object, and those lists were accumulating objects
> > between test methods.
>
> My first guess would be that you're using class variables instead of
> instance variables, but you say:
>
> > I don't think I'm accidentally using class variables
>
> so I'm stumped. Can you post your code?
I managed to fix my problem, but I don't understand why the fix works
yet, so I'm not quite satisfied.
I am trying to narrow it down so I can post more informatively.
So far my attempts at making a minimal example don't exhibit the same
problem. While I'm trying to get the smallest example with the
problem, I will describe what happened and how I 'fixed' it.
The File id() was indeed a red herring.
The problem was that in __init__, File reads a bunch of stuff (in XML
using libxml2) and populates some internal lists. The one that had the
problem was a list of Modules, which has a list of Procedures which
has a list of Blocks. Each Block has predecessors and successors.
Block looks like this:
class Block:
def __init__(self, name, preds = [], succs = []):
self.name = name
self.predecessors = preds
self.successors = succs
self.metrics = []
for pred in self.predecessors:
pred.addSuccessor(self)
for succ in self.successors:
succ.addPredecessor(self)
# add* just append to the lists, avoiding cycles.
def __repr__(self):
s = "{%d -> %s (0x%d) -> %d (%d)}" %\
(len(self.predecessors), self.name,\
id(self), len(self.successors),
len(self.metrics))
return s
In File, Blocks are created in a method that gets called as we're
parsing out the Procedures and Modules. I make a new Block with empty
preds and succs initially, then link them up after they're all
created:
in File.py:
def blockForXMLNode(self, n):
name = safeGetAttribute(n, "label", xlinkNSURI)
# this is called during the first pass, can't link up yet
preds = []
succs = []
block = Block.Block(name)# preds, succs)
print 'DEBUG: Making new block: ', block
The problem: if I run it as is, I get this output:
(During the first testCase:)
DEBUG: Making new block: {0 -> no_exit.1 (0x2714520) -> 0 (0)}
DEBUG: Making new block: {0 -> loopexit.1 (0x2714840) -> 0 (0)}
DEBUG: Making new block: {0 -> loopexit.0 (0x2715000) -> 0 (0)}
(During the next testCase:)
DEBUG: Making new block: {3 -> no_exit.1 (0x2735080) -> 5 (0)}
DEBUG: Making new block: {4 -> loopexit.1 (0x2735400) -> 6 (0)}
DEBUG: Making new block: {5 -> loopexit.0 (0x2735560) -> 7 (0)}
(and so on...)
So it does look like a class variable vs. instance variable problem,
but I can't say why. The fix is to uncomment the "# preds, succs)" and
pass in those empty lists to the Block constructor. That gives the
expected results, but I can't explain the difference.
-mike
--
More information about the Python-list
mailing list