Repository: pandas-dev/pandas

Issue:
expanduser in to_file methods
Right now AFAIK there isn't any ~ expansion. Seems like nice, low-hanging fruit.



Discussion:
seems reasonable. prob should exist as a function in `pandas.io.common` (and be used in `get_filepath_or_buffer`


Resolving patch:
diff --git a/pandas/io/common.py b/pandas/io/common.py
--- a/pandas/io/common.py
+++ b/pandas/io/common.py
@@ -1,10 +1,11 @@
 """Common IO api utilities"""
 
 import sys
+import os
 import zipfile
 from contextlib import contextmanager, closing
 
-from pandas.compat import StringIO
+from pandas.compat import StringIO, string_types
 from pandas import compat
 
 
@@ -99,6 +100,24 @@ def maybe_read_encoded_stream(reader, encoding=None):
     return reader, encoding
 
 
+def _expand_user(filepath_or_buffer):
+    """Return the argument with an initial component of ~ or ~user
+       replaced by that user's home directory.
+
+    Parameters
+    ----------
+    filepath_or_buffer : object to be converted if possible
+
+    Returns
+    -------
+    expanded_filepath_or_buffer : an expanded filepath or the
+                                  input if not expandable
+    """
+    if isinstance(filepath_or_buffer, string_types):
+        return os.path.expanduser(filepath_or_buffer)
+    return filepath_or_buffer
+
+
 def get_filepath_or_buffer(filepath_or_buffer, encoding=None):
     """
     If the filepath_or_buffer is a url, translate and return the buffer
@@ -138,7 +157,8 @@ def get_filepath_or_buffer(filepath_or_buffer, encoding=None):
         filepath_or_buffer = StringIO(k.get_contents_as_string())
         return filepath_or_buffer, None
 
-    return filepath_or_buffer, None
+
+    return _expand_user(filepath_or_buffer), None
 
 
 def file_path_to_url(path):


Test patch:
diff --git a/pandas/io/tests/test_common.py b/pandas/io/tests/test_common.py
new file mode 100644
--- /dev/null
+++ b/pandas/io/tests/test_common.py
@@ -0,0 +1,40 @@
+"""
+    Tests for the pandas.io.common functionalities
+"""
+from pandas.compat import StringIO
+import os
+
+import pandas.util.testing as tm
+
+from pandas.io import common
+
+
+class TestCommonIOCapabilities(tm.TestCase):
+
+    def test_expand_user(self):
+        filename = '~/sometest'
+        expanded_name = common._expand_user(filename)
+
+        self.assertNotEqual(expanded_name, filename)
+        self.assertNotIn('~', expanded_name)
+        self.assertEqual(os.path.expanduser(filename), expanded_name)
+
+    def test_expand_user_normal_path(self):
+        filename = '/somefolder/sometest'
+        expanded_name = common._expand_user(filename)
+
+        self.assertEqual(expanded_name, filename)
+        self.assertNotIn('~', expanded_name)
+        self.assertEqual(os.path.expanduser(filename), expanded_name)
+
+    def test_get_filepath_or_buffer_with_path(self):
+        filename = '~/sometest'
+        filepath_or_buffer, _ = common.get_filepath_or_buffer(filename)
+        self.assertNotEqual(filepath_or_buffer, filename)
+        self.assertNotIn('~', filepath_or_buffer)
+        self.assertEqual(os.path.expanduser(filename), filepath_or_buffer)
+
+    def test_get_filepath_or_buffer_with_buffer(self):
+        input_buffer = StringIO()
+        filepath_or_buffer, _ = common.get_filepath_or_buffer(input_buffer)
+        self.assertEqual(filepath_or_buffer, input_buffer)