diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-09 04:35:06 +0000 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-09 04:35:06 +0000 |
commit | 72f3132d2b98a44881ae7001d0001602a66bf8b5 (patch) | |
tree | d75ce61572ba4d18fcc746583f911f150e1c968a /ipalib/plugable.py | |
parent | 3495c67d57868a02bafe6f1935d4846cd5615bf5 (diff) | |
download | freeipa.git-72f3132d2b98a44881ae7001d0001602a66bf8b5.tar.gz freeipa.git-72f3132d2b98a44881ae7001d0001602a66bf8b5.tar.xz freeipa.git-72f3132d2b98a44881ae7001d0001602a66bf8b5.zip |
95: Improved docstrings for ReadOnly class; added ReadOnly.__islocked__() method; added corresponding unit tests
Diffstat (limited to 'ipalib/plugable.py')
-rw-r--r-- | ipalib/plugable.py | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py index c5ec08ec..4ce4a9ba 100644 --- a/ipalib/plugable.py +++ b/ipalib/plugable.py @@ -39,6 +39,39 @@ def check_identifier(name): class ReadOnly(object): """ Base class for classes with read-only attributes. + + Be forewarned that Python does not offer true read-only user defined + classes. In particular, do not rely upon the read-only-ness of this + class for security purposes. + + The point of this class is not to make it impossible to set or delete + attributes, but do make it impossible to accidentally do so. The plugins + are not thread-safe: in the server, they are loaded once and the same + instances will be used to process many requests. Therefore, it is + imperative that they not set any instance attributes after they have + been initialized. This base class enforces that policy. + + For example: + + >>> class givenName(ReadOnly): + >>> def __init__(self): + >>> self.whatever = 'some value' # Hasn't been locked yet + >>> self.__lock__() + >>> + >>> def finalize(self, api): + >>> # After the instance has been locked, attributes can still be + >>> # set, but only in a round-about, unconventional way: + >>> object.__setattr__(self, 'api', api) + >>> + >>> def normalize(self, value): + >>> # After the instance has been locked, trying to set an + >>> # attribute in the normal way will raise AttributeError. + >>> self.value = value # Not thread safe! + >>> return self.actually_normalize() + >>> + >>> def actually_normalize(self): + >>> # Again, this is not thread safe: + >>> return unicode(self.value).strip() """ __locked = False @@ -50,6 +83,12 @@ class ReadOnly(object): assert self.__locked is False, '__lock__() can only be called once' self.__locked = True + def __islocked__(self): + """ + Returns True if this instance is locked, False otherwise. + """ + return self.__locked + def __setattr__(self, name, value): """ Raises an AttributeError if ReadOnly.__lock__() has already been called; |