[Cvsshell-devel] CVS: cvsshell/src oo_tools.py,NONE,1.1
Status: Beta
Brought to you by:
stefanheimann
From: Stefan H. <ste...@us...> - 2002-03-09 17:24:50
|
Update of /cvsroot/cvsshell/cvsshell/src In directory usw-pr-cvs1:/tmp/cvs-serv32725 Added Files: oo_tools.py Log Message: initial checkin --- NEW FILE: oo_tools.py --- ############################################################################### # This file is part of CvsShell # # CvsShell is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # CvsShell is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with CvsShell; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright 2002 by Stefan Heimann # Website: http://cvsshell.sourceforge.net/ ############################################################################### # This class is not thread-safe! Prior to python 2.2 it is not possible # to write something like: # def foo(): # x = 5 # def bar(): # print x # bar() # and so all communication between the inner and the outer function # has to be done with global variables. # # To make it thread-safe, one must lock all access-points of the variable # GetSetProvider.__storage. AccessError = 'AccessError' class GetSetProvider: """Classes which are derived from GetSetProvider have implicit get/set methods for all their variables. """ def __init__(self): self.__readonly = [] self.__private = [] def __getattr__(self, name): if len(name) > 3: pre, attr = name[:3], name[3].lower() + name[4:] if attr[0] == '_': self.__raiseAccessError(attr, 'private') if pre == 'get': if attr in self.__private: self.__raiseAccessError(attr, 'private') GetSetProvider.__storage = eval('self.' + attr) return lambda : GetSetProvider.__storage if pre == 'set': if attr in self.__private: self.__raiseAccessError(attr, 'private') elif attr in self.__readonly: self.__raiseAccessError(attr, 'readonly') GetSetProvider.__storage = (self.__dict__, attr) def __set(val): dict, name = GetSetProvider.__storage dict[name] = val return __set raise AttributeError, "class %s has no attribute '%s'" % \ (self.__class__.__name__, name) def _GetSetProvider__raiseAccessError(self, attr, access): raise AccessError, \ 'attribute %s in class %s has %s access' % \ (attr, self.__class__.__name__, access) def _setReadonly_(self, name): self.__readonly.append(name) def _setPrivate_(self, name): self.__private.append(name) ############################## # TestCases ############################## if __name__ == '__main__': import unittest class Test(GetSetProvider): def __init__(self, name): GetSetProvider.__init__(self) self.name = name self.private = None self._setPrivate_('private') self.readonly = 'readonly' self._setReadonly_('readonly') class GetSetProviderTestCase(unittest.TestCase): def setUp(self): self.t = Test('Stefan') def tearDown(self): del self.t def testGet(self): self.assertEqual(self.t.getName(), 'Stefan') try: self.t.getAge() self.fail('should raise exception here.') except AttributeError: pass def testSet(self): self.t.setName('Heimann') self.assertEqual(self.t.getName(), 'Heimann') self.t.setAge(23) self.assertEqual(self.t.getAge(), 23) def testAccess(self): self.assertEqual(self.t.getReadonly(), 'readonly') try: self.t.setReadonly(None) fail('should raise exception here.') except AccessError: pass try: self.t.getPrivate() fail('should raise exception here.') except AccessError: pass try: self.t.setPrivate(None) fail('should raise exception here.') except AccessError: pass unittest.main() |