diff --git a/Lib/dircmp.py b/Lib/dircmp.py
index 1227aa7..13a8a04 100644
--- a/Lib/dircmp.py
+++ b/Lib/dircmp.py
@@ -1,6 +1,4 @@
-# Module 'dirmp'
-#
-# Defines a class to build directory diff tools on.
+"""A class to build directory diff tools on."""
 
 import os
 
@@ -9,195 +7,195 @@
 import statcache
 from stat import *
 
-# Directory comparison class.
-#
 class dircmp:
-	#
-	def new(self, a, b): # Initialize
-		self.a = a
-		self.b = b
-		# Properties that caller may change before calling self.run():
-		self.hide = [os.curdir, os.pardir] # Names never to be shown
-		self.ignore = ['RCS', 'tags'] # Names ignored in comparison
-		#
-		return self
-	#
-	def run(self): # Compare everything except common subdirectories
-		self.a_list = filter(dircache.listdir(self.a), self.hide)
-		self.b_list = filter(dircache.listdir(self.b), self.hide)
-		self.a_list.sort()
-		self.b_list.sort()
-		self.phase1()
-		self.phase2()
-		self.phase3()
-	#
-	def phase1(self): # Compute common names
-		self.a_only = []
-		self.common = []
-		for x in self.a_list:
-			if x in self.b_list:
-				self.common.append(x)
-			else:
-				self.a_only.append(x)
-		#
-		self.b_only = []
-		for x in self.b_list:
-			if x not in self.common:
-				self.b_only.append(x)
-	#
-	def phase2(self): # Distinguish files, directories, funnies
-		self.common_dirs = []
-		self.common_files = []
-		self.common_funny = []
-		#
-		for x in self.common:
-			a_path = os.path.join(self.a, x)
-			b_path = os.path.join(self.b, x)
-			#
-			ok = 1
-			try:
-				a_stat = statcache.stat(a_path)
-			except os.error, why:
-				# print 'Can\'t stat', a_path, ':', why[1]
-				ok = 0
-			try:
-				b_stat = statcache.stat(b_path)
-			except os.error, why:
-				# print 'Can\'t stat', b_path, ':', why[1]
-				ok = 0
-			#
-			if ok:
-				a_type = S_IFMT(a_stat[ST_MODE])
-				b_type = S_IFMT(b_stat[ST_MODE])
-				if a_type <> b_type:
-					self.common_funny.append(x)
-				elif S_ISDIR(a_type):
-					self.common_dirs.append(x)
-				elif S_ISREG(a_type):
-					self.common_files.append(x)
-				else:
-					self.common_funny.append(x)
-			else:
-				self.common_funny.append(x)
-	#
-	def phase3(self): # Find out differences between common files
-		xx = cmpfiles(self.a, self.b, self.common_files)
-		self.same_files, self.diff_files, self.funny_files = xx
-	#
-	def phase4(self): # Find out differences between common subdirectories
-		# A new dircmp object is created for each common subdirectory,
-		# these are stored in a dictionary indexed by filename.
-		# The hide and ignore properties are inherited from the parent
-		self.subdirs = {}
-		for x in self.common_dirs:
-			a_x = os.path.join(self.a, x)
-			b_x = os.path.join(self.b, x)
-			self.subdirs[x] = newdd = dircmp().new(a_x, b_x)
-			newdd.hide = self.hide
-			newdd.ignore = self.ignore
-			newdd.run()
-	#
-	def phase4_closure(self): # Recursively call phase4() on subdirectories
-		self.phase4()
-		for x in self.subdirs.keys():
-			self.subdirs[x].phase4_closure()
-	#
-	def report(self): # Print a report on the differences between a and b
-		# Assume that phases 1 to 3 have been executed
-		# Output format is purposely lousy
-		print 'diff', self.a, self.b
-		if self.a_only:
-			print 'Only in', self.a, ':', self.a_only
-		if self.b_only:
-			print 'Only in', self.b, ':', self.b_only
-		if self.same_files:
-			print 'Identical files :', self.same_files
-		if self.diff_files:
-			print 'Differing files :', self.diff_files
-		if self.funny_files:
-			print 'Trouble with common files :', self.funny_files
-		if self.common_dirs:
-			print 'Common subdirectories :', self.common_dirs
-		if self.common_funny:
-			print 'Common funny cases :', self.common_funny
-	#
-	def report_closure(self): # Print reports on self and on subdirs
-		# If phase 4 hasn't been done, no subdir reports are printed
-		self.report()
-		try:
-			x = self.subdirs
-		except AttributeError:
-			return # No subdirectories computed
-		for x in self.subdirs.keys():
-			print
-			self.subdirs[x].report_closure()
-	#
-	def report_phase4_closure(self): # Report and do phase 4 recursively
-		self.report()
-		self.phase4()
-		for x in self.subdirs.keys():
-			print
-			self.subdirs[x].report_phase4_closure()
+    """Directory comparison class."""
+
+    def new(self, a, b):
+        """Initialize."""
+        self.a = a
+        self.b = b
+        # Properties that caller may change before calling self.run():
+        self.hide = [os.curdir, os.pardir] # Names never to be shown
+        self.ignore = ['RCS', 'tags'] # Names ignored in comparison
+
+        return self
+
+    def run(self):
+        """Compare everything except common subdirectories."""
+        self.a_list = filter(dircache.listdir(self.a), self.hide)
+        self.b_list = filter(dircache.listdir(self.b), self.hide)
+        self.a_list.sort()
+        self.b_list.sort()
+        self.phase1()
+        self.phase2()
+        self.phase3()
+
+    def phase1(self):
+        """Compute common names."""
+        self.a_only = []
+        self.common = []
+        for x in self.a_list:
+            if x in self.b_list:
+                self.common.append(x)
+            else:
+                self.a_only.append(x)
+
+        self.b_only = []
+        for x in self.b_list:
+            if x not in self.common:
+                self.b_only.append(x)
+
+    def phase2(self):
+        """Distinguish files, directories, funnies."""
+        self.common_dirs = []
+        self.common_files = []
+        self.common_funny = []
+
+        for x in self.common:
+            a_path = os.path.join(self.a, x)
+            b_path = os.path.join(self.b, x)
+
+            ok = 1
+            try:
+                a_stat = statcache.stat(a_path)
+            except os.error, why:
+                # print 'Can\'t stat', a_path, ':', why[1]
+                ok = 0
+            try:
+                b_stat = statcache.stat(b_path)
+            except os.error, why:
+                # print 'Can\'t stat', b_path, ':', why[1]
+                ok = 0
+
+            if ok:
+                a_type = S_IFMT(a_stat[ST_MODE])
+                b_type = S_IFMT(b_stat[ST_MODE])
+                if a_type <> b_type:
+                    self.common_funny.append(x)
+                elif S_ISDIR(a_type):
+                    self.common_dirs.append(x)
+                elif S_ISREG(a_type):
+                    self.common_files.append(x)
+                else:
+                    self.common_funny.append(x)
+            else:
+                self.common_funny.append(x)
+
+    def phase3(self):
+        """Find out differences between common files."""
+        xx = cmpfiles(self.a, self.b, self.common_files)
+        self.same_files, self.diff_files, self.funny_files = xx
+
+    def phase4(self):
+        """Find out differences between common subdirectories.
+        A new dircmp object is created for each common subdirectory,
+        these are stored in a dictionary indexed by filename.
+        The hide and ignore properties are inherited from the parent."""
+        self.subdirs = {}
+        for x in self.common_dirs:
+            a_x = os.path.join(self.a, x)
+            b_x = os.path.join(self.b, x)
+            self.subdirs[x] = newdd = dircmp().new(a_x, b_x)
+            newdd.hide = self.hide
+            newdd.ignore = self.ignore
+            newdd.run()
+
+    def phase4_closure(self):
+        """Recursively call phase4() on subdirectories."""
+        self.phase4()
+        for x in self.subdirs.keys():
+            self.subdirs[x].phase4_closure()
+
+    def report(self):
+        """Print a report on the differences between a and b."""
+        # Assume that phases 1 to 3 have been executed
+        # Output format is purposely lousy
+        print 'diff', self.a, self.b
+        if self.a_only:
+            print 'Only in', self.a, ':', self.a_only
+        if self.b_only:
+            print 'Only in', self.b, ':', self.b_only
+        if self.same_files:
+            print 'Identical files :', self.same_files
+        if self.diff_files:
+            print 'Differing files :', self.diff_files
+        if self.funny_files:
+            print 'Trouble with common files :', self.funny_files
+        if self.common_dirs:
+            print 'Common subdirectories :', self.common_dirs
+        if self.common_funny:
+            print 'Common funny cases :', self.common_funny
+
+    def report_closure(self):
+        """Print reports on self and on subdirs.
+        If phase 4 hasn't been done, no subdir reports are printed."""
+        self.report()
+        try:
+            x = self.subdirs
+        except AttributeError:
+            return # No subdirectories computed
+        for x in self.subdirs.keys():
+            print
+            self.subdirs[x].report_closure()
+
+    def report_phase4_closure(self):
+        """Report and do phase 4 recursively."""
+        self.report()
+        self.phase4()
+        for x in self.subdirs.keys():
+            print
+            self.subdirs[x].report_phase4_closure()
 
 
-# Compare common files in two directories.
-# Return:
-#	- files that compare equal
-#	- files that compare different
-#	- funny cases (can't stat etc.)
-#
 def cmpfiles(a, b, common):
-	res = ([], [], [])
-	for x in common:
-		res[cmp(os.path.join(a, x), os.path.join(b, x))].append(x)
-	return res
+    """Compare common files in two directories.
+    Return:
+        - files that compare equal
+        - files that compare different
+        - funny cases (can't stat etc.)"""
+
+    res = ([], [], [])
+    for x in common:
+        res[cmp(os.path.join(a, x), os.path.join(b, x))].append(x)
+    return res
 
 
-# Compare two files.
-# Return:
-#	0 for equal
-#	1 for different
-#	2 for funny cases (can't stat, etc.)
-#
 def cmp(a, b):
-	try:
-		if cmpcache.cmp(a, b): return 0
-		return 1
-	except os.error:
-		return 2
+    """Compare two files.
+    Return:
+        0 for equal
+        1 for different
+        2 for funny cases (can't stat, etc.)"""
+
+    try:
+        if cmpcache.cmp(a, b): return 0
+        return 1
+    except os.error:
+        return 2
 
 
-# Remove a list item.
-# NB: This modifies the list argument.
-#
-def remove(list, item):
-	for i in range(len(list)):
-		if list[i] == item:
-			del list[i]
-			break
-
-
-# Return a copy with items that occur in skip removed.
-#
 def filter(list, skip):
-	result = []
-	for item in list:
-		if item not in skip: result.append(item)
-	return result
+    """Return a copy with items that occur in skip removed."""
+
+    result = []
+    for item in list:
+        if item not in skip: result.append(item)
+    return result
 
 
-# Demonstration and testing.
-#
 def demo():
-	import sys
-	import getopt
-	options, args = getopt.getopt(sys.argv[1:], 'r')
-	if len(args) <> 2: raise getopt.error, 'need exactly two args'
-	dd = dircmp().new(args[0], args[1])
-	dd.run()
-	if ('-r', '') in options:
-		dd.report_phase4_closure()
-	else:
-		dd.report()
+    """Demonstration and testing."""
 
-# demo()
+    import sys
+    import getopt
+    options, args = getopt.getopt(sys.argv[1:], 'r')
+    if len(args) <> 2: raise getopt.error, 'need exactly two args'
+    dd = dircmp().new(args[0], args[1])
+    dd.run()
+    if ('-r', '') in options:
+        dd.report_phase4_closure()
+    else:
+        dd.report()
+
+if __name__ == "__main__":
+    demo()
