views:

38

answers:

1

Here is my class:

class ManagementReview(object):
    """Class describing ManagementReview Object.
    """

    # Class attributes
    id = 0
    Title = 'New Management Review Object'
    fiscal_year = ''
    region = ''
    review_date = ''
    date_completed = ''
    prepared_by = ''

    __goals = [] # List of <ManagementReviewGoals>.
    __objectives = [] # List of <ManagementReviewObjetives>.
    __actions = [] # List of <ManagementReviewActions>.
    __deliverables = [] # List of <ManagementReviewDeliverable>.
    __issues = [] # List of <ManagementReviewIssue>.

    __created = ''
    __created_by = ''
    __modified = ''
    __modified_by = ''


    def __init__(self,Title='',id=0,fiscal_year='',region='',review_date='',
                    date_completed='',prepared_by='',created='',created_by='',
                    modified='',modified_by=''):
        """Instantiate object.
        """
        if id:
            self.setId(id)
        if Title:
            self.setTitle(Title)
        if fiscal_year:
            self.setFiscal_year(fiscal_year)
        if region:
            self.setRegion(region)
        if review_date:
            self.setReview_date(review_date)
        if date_completed:
            # XXX TODO: validation to see if date_completed pattern matches ISO-8601
            self.setDate_completed(date_completed)
        if prepared_by:
            self.setPrepared_by(prepared_by)
        if created:
            # XXX TODO: validation to see if date_completed pattern matches ISO-8601
            self.setCreated(created)
        else:
            self.setCreated(self.getNow())
        if created_by:
            self.setCreated_by(created_by)
        self.__modified = self.getNow()
        if modified_by:
            self.__modified_by = modified_by

    def __str__(self):
        return "<ManagementReview '%s (%s)'>" % (self.Title,self.id)

    def __setattr__(self, name, value): # Override built-in setter
        # set the value like usual and then update the modified attribute too
        object.__setattr__(self, name, value) # Built-in 
        self.__dict__['__modified'] = datetime.now().isoformat()

    def getActions(self):
        return self.__actions

    def addAction(self,mra):
        self.__actions.append(mra)

    def removeAction(self,id):
        pass # XXX TODO

I have this test:

from datetime import datetime
import random
import unittest

from ManagementReview import ManagementReview, ManagementReviewAction

# Default Values for ManagementReviewAction Object Type
DUMMY_ID = 1
DUMMY_ACTION = 'Action 1'
DUMMY_OWNER = 'Owner 1'
DUMMY_TITLE = 'Test MR'

DUMMY_FISCAL_YEAR = '2011'
DUMMY_REGION = 'WO'
DUMMY_REVIEW_DATE = '2009-01-18T10:50:21.766169',
DUMMY_DATE_COMPLETED = '2008-07-18T10:50:21.766169'
DUMMY_PREPARED_BY = 'test user'
DUMMY_CREATED = '2002-07-18T10:50:21.766169'
DUMMY_CREATED_BY = 'test user 2'
DUMMY_MODIFIED = datetime.now().isoformat()
DUMMY_MODIFIED_BY = 'test user 3'

class TestManagementReviewSetAction(unittest.TestCase):

    def setUp(self):
        self.mr = ManagementReview(DUMMY_TITLE,DUMMY_ID,fiscal_year=DUMMY_FISCAL_YEAR,region=DUMMY_REGION,
                                    review_date=DUMMY_REVIEW_DATE,date_completed=DUMMY_DATE_COMPLETED,
                                    prepared_by=DUMMY_PREPARED_BY,created=DUMMY_CREATED,
                                    created_by=DUMMY_CREATED_BY,modified=DUMMY_MODIFIED,
                                    modified_by=DUMMY_MODIFIED_BY)

    def tearDown(self):
        self.mr = None


    def test_add_action(self):
        for i in range(1,11):
            mra = ManagementReviewAction(i,'action '+str(i),'owner '+str(i))
            self.mr.addAction(mra)
        self.assertEqual(len(self.mr.getActions()),10)

    def test_remove_action(self):
        print len(self.mr.getActions())
        for i in range(1,11):
            mra = ManagementReviewAction(i,'action '+str(i),'owner '+str(i))
            self.mr.addAction(mra)
        self.mr.removeAction(3)
        self.assertEqual(len(self.mr.getActions()),9)


if __name__ == '__main__':
    unittest.main()

The first test passes. That is, self.mr.getActions() has 10 actions.

However, when I run the 2nd test, test_remove_action, the value for len(self.mr.getActions()) is 10. At this point, though, it should be 0.

Why is this?

Thanks

+1  A: 

see if you are keeping track of actions in a class attribute of ManagementReview as opposed to an instance attribute

A class attribute will be something like

class Spam(object):
    actions = []

and an instance attribute will look something like

class Spam(object):
    def __init__(self):
        self.actions = []

What happens is that actions = [] is executed when the class is created and all instances of the class share the same list.

EDIT: In light of your update, I can see that this is definitely what is going on

aaronasterling
I've updated the original post with the class info.
Eric
see the update to my post
aaronasterling
Ah, I understand. Thanks! :)
Eric