--- Modules/readline.c	2008-11-04 12:43:31.000000000 -0800
+++ Modules/readline.c	2009-04-22 15:50:49.000000000 -0700
@@ -759,6 +759,10 @@
 static char **
 flex_complete(char *text, int start, int end)
 {
+#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
+	rl_completion_append_character ='\0';
+	rl_completion_suppress_append = 0;
+#endif
 	Py_XDECREF(begidx);
 	Py_XDECREF(endidx);
 	begidx = PyInt_FromLong((long) start);
@@ -799,11 +803,8 @@
 	rl_attempted_completion_function = (CPPFunction *)flex_complete;
 	/* Set Python word break characters */
 	rl_completer_word_break_characters =
-		strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
+		strdup(" \t\n`!@#%^&*()=+[{]}\\|;:,<>?");
 		/* All nonalphanums except '.' */
-#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
-	rl_completion_append_character ='\0';
-#endif
 
 	begidx = PyInt_FromLong(0L);
 	endidx = PyInt_FromLong(0L);
--- Lib/rlcompleter.py	2009-04-22 15:42:38.000000000 -0700
+++ Lib/rlcompleter.py	2009-04-22 15:43:00.000000000 -0700
@@ -1,9 +1,10 @@
 """Word completion for GNU readline 2.0.
 
 This requires the latest extension to the readline module. The completer
-completes keywords, built-ins and globals in a selectable namespace (which
-defaults to __main__); when completing NAME.NAME..., it evaluates (!) the
-expression up to the last dot and completes its attributes.
+completes keywords, built-ins, globals, and file names in a selectable
+namespace (which defaults to __main__); when completing NAME.NAME...,
+it evaluates (!) the expression up to the last dot and completes its
+attributes.
 
 It's very cool to do "import sys" type "sys.", hit the
 completion key (twice), and see the list of names defined by the
@@ -72,24 +73,34 @@
             self.use_main_ns = 0
             self.namespace = namespace
 
+        # The cache of matches for a particular text fragment.
+        self.matches = []
+
     def complete(self, text, state):
         """Return the next possible completion for 'text'.
 
         This is called successively with state == 0, 1, 2, ... until it
-        returns None.  The completion should begin with 'text'.
+        returns None.  The completion should begin with 'text'.  Any text
+        with a period (.) will match as an attribute.  Any text that begins
+        with a single or double quote will match using file name expansion.
 
         """
         if self.use_main_ns:
             self.namespace = __main__.__dict__
 
+        # For the first call with this set of text, compute all possible
+        # matches and store them in a member variable.  Subsequent calls
+        # will then iterate through this set of matches.
         if state == 0:
-            if "." in text:
+            if ('"' in text) or ("'" in text):
+                self.matches = self.file_matches(text)
+            elif "." in text:
                 self.matches = self.attr_matches(text)
             else:
                 self.matches = self.global_matches(text)
-        try:
+        if state < len(self.matches):
             return self.matches[state]
-        except IndexError:
+        else:
             return None
 
     def _callable_postfix(self, val, word):
@@ -129,9 +140,14 @@
 
         """
         import re
+        import types
+
+        # Setup the regular expression for attributes
         m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
         if not m:
             return []
+
+        # Group 1 is the class name, group 3 is the attribute text
         expr, attr = m.group(1, 3)
         try:
             thisobject = eval(expr, self.namespace)
@@ -143,9 +159,18 @@
         if "__builtins__" in words:
             words.remove("__builtins__")
 
-        if hasattr(thisobject, '__class__'):
-            words.append('__class__')
-            words.extend(get_class_members(thisobject.__class__))
+        # If this type is a class instance, use the __class__ member to
+        # get the dictionary of attributes
+        if type(thisobject) == types.InstanceType:
+            if hasattr(thisobject, '__class__'):
+                words.append('__class__')
+                words.extend(get_class_members(thisobject.__class__))
+        elif type(thisobject) == types.ClassType:
+            words.extend(get_class_members(thisobject))
+        else:
+            words.extend(dir(thisobject))
+
+        # Build the full matching text from class.attribute matches
         matches = []
         n = len(attr)
         for word in words:
@@ -155,6 +180,43 @@
                 matches.append(word)
         return matches
 
+    def file_matches(self, text):
+        """Compute matches when text is a file name.
+
+        Expects a leading single or double quote character in the text.
+        Will expand a leading ~ or ~user to a valid home directory.
+        Will expand a leading $VAR to an environment variable name."""
+        import glob
+        import os
+
+        # save the leading quote character so we can re-add it later
+        quote = text[0]
+        # strip the leading quote character
+        path = text[1:]
+
+        # expand a tilde (~) or a leading environment variable in the text
+        path = os.path.expanduser( path )
+        path = os.path.expandvars( path )
+
+        # append the any match character to send to the glob routine
+        path = path + "*"
+
+        # use the glob module to get all of the matches
+        rawMatches = glob.glob( path )
+
+        # re-prefix the text with the quoting character and append the correct
+        # terminating character depending on the type of match that was found.
+        # Directories are terminated with '/' and files with an ending quote.
+        matches = []
+        for entry in rawMatches:
+            if os.path.isdir( entry ):
+                matches.append( quote + entry + os.sep )
+            elif os.path.isfile( entry ):
+                matches.append( quote + entry + quote )
+            else:
+                matches.append( quote + entry )
+        return matches
+
 def get_class_members(klass):
     ret = dir(klass)
     if hasattr(klass,'__bases__'):
