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()
|