s/_assert_consistency/_assert_invariants/

[Imported from Trac: page CodingStandards, version 16]
davidsarah 2011-09-26 22:41:20 +00:00
parent 2fb249af43
commit 83ef120c62

@ -81,7 +81,7 @@ The "error message" that will accompany a failed expression should be a statemen
If your class has internal state which is complicated enough that a bug in the class's implementation could lead to garbled internal state, then you should have a class invariant. A class invariant is a method like this (an actual example from !BlockWrangler, but truncated for space): If your class has internal state which is complicated enough that a bug in the class's implementation could lead to garbled internal state, then you should have a class invariant. A class invariant is a method like this (an actual example from !BlockWrangler, but truncated for space):
``` ```
def _assert_consistency(self): def _assert_invariants(self):
# All of the keys in all of these dicts are required to be ids. # All of the keys in all of these dicts are required to be ids.
for d in (self.bId2chunkobj, self.bId2peers, self.Idsofwantedblocks, self.Idsoflocatedblocks,): for d in (self.bId2chunkobj, self.bId2peers, self.Idsofwantedblocks, self.Idsoflocatedblocks,):
_assert(not [key for key in d.keys() if not idlib.is_id(key)], "All of the keys in these dicts are required to be ids.", listofnonIds=[key for key in d.keys() if not idlib.is_id(key)]) _assert(not [key for key in d.keys() if not idlib.is_id(key)], "All of the keys in these dicts are required to be ids.", listofnonIds=[key for key in d.keys() if not idlib.is_id(key)])
@ -94,7 +94,9 @@ def _assert_consistency(self):
_assert((claim == "yes") == (peer in self.bId2peers.get(blockId, ())), "The blockId must appear in bId2peers if and only if the peer has claimed the block.", claim=claim, peer=peer, bId2peersentry=self.bId2peers.get(blockId, ())) _assert((claim == "yes") == (peer in self.bId2peers.get(blockId, ())), "The blockId must appear in bId2peers if and only if the peer has claimed the block.", claim=claim, peer=peer, bId2peersentry=self.bId2peers.get(blockId, ()))
``` ```
Now you can put `assert self._assert_consistency()` everywhere in your class where the class ought to be in an internally consistent state. For example, at the beginning of every externally-callable method. This technique can be very valuable in developing a complex class -- it catches bugs early, it isolates bugs into specific code paths, and it clarifies the internal structure of the class so that other developers can hack on it without subtle misunderstandings. Now you can put `assert self._assert_invariants()` everywhere in your class where the class ought to be in an internally consistent state. For example, at the beginning of every externally-callable method. This technique can be very valuable in developing a complex class -- it catches bugs early, it isolates bugs into specific code paths, and it clarifies the internal structure of the class so that other developers can hack on it without subtle misunderstandings.
* we actually appear to only have one instance of this pattern in Tahoe at time of writing, in `allmydata.util.dictutil`. It has the disadvantage of cluttering up the logic with calls to `_assert_invariants`, and should probably be used sparingly. -- DavidSarah
=== configuration === === configuration ===