[Python-checkins] cpython: #14807: move undocumented tarfile.filemode() to stat.filemode(). Add

giampaolo.rodola python-checkins at python.org
Tue May 15 15:30:29 CEST 2012


http://hg.python.org/cpython/rev/492e6c6a01bb
changeset:   76949:492e6c6a01bb
user:        Giampaolo Rodola' <g.rodola at gmail.com>
date:        Tue May 15 15:30:25 2012 +0200
summary:
  #14807: move undocumented tarfile.filemode() to stat.filemode(). Add tarfile.filemode alias with deprecation warning.

files:
  Doc/library/stat.rst  |  11 +++++-
  Doc/whatsnew/3.3.rst  |   8 ++++
  Lib/stat.py           |  40 ++++++++++++++++++++++
  Lib/tarfile.py        |  48 +++-----------------------
  Lib/test/test_stat.py |  55 +++++++++++++++++++++++++++++++
  Misc/NEWS             |   5 ++-
  6 files changed, 124 insertions(+), 43 deletions(-)


diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst
--- a/Doc/library/stat.rst
+++ b/Doc/library/stat.rst
@@ -104,6 +104,16 @@
    if __name__ == '__main__':
        walktree(sys.argv[1], visitfile)
 
+An additional utility function is provided to covert a file's mode in a human
+readable string:
+
+.. function:: filemode(mode)
+
+   Convert a file's mode to a string of the form '-rwxrwxrwx'.
+
+   .. versionadded:: 3.3
+
+
 All the variables below are simply symbolic indexes into the 10-tuple returned
 by :func:`os.stat`, :func:`os.fstat` or :func:`os.lstat`.
 
@@ -344,4 +354,3 @@
    The file is a snapshot file.
 
 See the \*BSD or Mac OS systems man page :manpage:`chflags(2)` for more information.
-
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst
--- a/Doc/whatsnew/3.3.rst
+++ b/Doc/whatsnew/3.3.rst
@@ -1177,6 +1177,14 @@
 
   (Contributed by Colin Marc in :issue:`14204`)
 
+stat
+----
+
+- The undocumented tarfile.filemode function has been moved to
+  :func:`stat.filemode`. It can be used to convert a file's mode to a string of
+  the form '-rwxrwxrwx'.
+
+  (Contributed by Giampaolo Rodolà in :issue:`14807`)
 
 sys
 ---
diff --git a/Lib/stat.py b/Lib/stat.py
--- a/Lib/stat.py
+++ b/Lib/stat.py
@@ -107,3 +107,43 @@
 SF_APPEND    = 0x00040000  # file may only be appended to
 SF_NOUNLINK  = 0x00100000  # file may not be renamed or deleted
 SF_SNAPSHOT  = 0x00200000  # file is a snapshot file
+
+
+_filemode_table = (
+    ((S_IFLNK,         "l"),
+     (S_IFREG,         "-"),
+     (S_IFBLK,         "b"),
+     (S_IFDIR,         "d"),
+     (S_IFCHR,         "c"),
+     (S_IFIFO,         "p")),
+
+    ((S_IRUSR,         "r"),),
+    ((S_IWUSR,         "w"),),
+    ((S_IXUSR|S_ISUID, "s"),
+     (S_ISUID,         "S"),
+     (S_IXUSR,         "x")),
+
+    ((S_IRGRP,         "r"),),
+    ((S_IWGRP,         "w"),),
+    ((S_IXGRP|S_ISGID, "s"),
+     (S_ISGID,         "S"),
+     (S_IXGRP,         "x")),
+
+    ((S_IROTH,         "r"),),
+    ((S_IWOTH,         "w"),),
+    ((S_IXOTH|S_ISVTX, "t"),
+     (S_ISVTX,         "T"),
+     (S_IXOTH,         "x"))
+)
+
+def filemode(mode):
+    """Convert a file's mode to a string of the form '-rwxrwxrwx'."""
+    perm = []
+    for table in _filemode_table:
+        for bit, char in table:
+            if mode & bit == bit:
+                perm.append(char)
+                break
+        else:
+            perm.append("-")
+    return "".join(perm)
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -274,47 +274,13 @@
         dst.write(buf)
     return
 
-filemode_table = (
-    ((S_IFLNK,      "l"),
-     (S_IFREG,      "-"),
-     (S_IFBLK,      "b"),
-     (S_IFDIR,      "d"),
-     (S_IFCHR,      "c"),
-     (S_IFIFO,      "p")),
+def filemode(mode):
+    """Deprecated in this location; use stat.filemode."""
+    import warnings
+    warnings.warn("deprecated in favor of stat.filemode",
+                  DeprecationWarning, 2)
+    return stat.filemode(mode)
 
-    ((TUREAD,       "r"),),
-    ((TUWRITE,      "w"),),
-    ((TUEXEC|TSUID, "s"),
-     (TSUID,        "S"),
-     (TUEXEC,       "x")),
-
-    ((TGREAD,       "r"),),
-    ((TGWRITE,      "w"),),
-    ((TGEXEC|TSGID, "s"),
-     (TSGID,        "S"),
-     (TGEXEC,       "x")),
-
-    ((TOREAD,       "r"),),
-    ((TOWRITE,      "w"),),
-    ((TOEXEC|TSVTX, "t"),
-     (TSVTX,        "T"),
-     (TOEXEC,       "x"))
-)
-
-def filemode(mode):
-    """Convert a file's mode to a string of the form
-       -rwxrwxrwx.
-       Used by TarFile.list()
-    """
-    perm = []
-    for table in filemode_table:
-        for bit, char in table:
-            if mode & bit == bit:
-                perm.append(char)
-                break
-        else:
-            perm.append("-")
-    return "".join(perm)
 
 class TarError(Exception):
     """Base exception."""
@@ -1891,7 +1857,7 @@
 
         for tarinfo in self:
             if verbose:
-                print(filemode(tarinfo.mode), end=' ')
+                print(stat.filemode(tarinfo.mode), end=' ')
                 print("%s/%s" % (tarinfo.uname or tarinfo.uid,
                                  tarinfo.gname or tarinfo.gid), end=' ')
                 if tarinfo.ischr() or tarinfo.isblk():
diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py
new file mode 100644
--- /dev/null
+++ b/Lib/test/test_stat.py
@@ -0,0 +1,55 @@
+import unittest
+import os
+import stat
+from test.support import TESTFN, run_unittest
+
+
+def get_mode(fname=TESTFN):
+    return stat.filemode(os.lstat(fname).st_mode)
+
+
+class TestFilemode(unittest.TestCase):
+
+    def setUp(self):
+        try:
+            os.remove(TESTFN)
+        except OSError:
+            try:
+                os.rmdir(TESTFN)
+            except OSError:
+                pass
+    tearDown = setUp
+
+    def test_mode(self):
+        with open(TESTFN, 'w'):
+            pass
+        os.chmod(TESTFN, 0o700)
+        self.assertEqual(get_mode(), '-rwx------')
+        os.chmod(TESTFN, 0o070)
+        self.assertEqual(get_mode(), '----rwx---')
+        os.chmod(TESTFN, 0o007)
+        self.assertEqual(get_mode(), '-------rwx')
+        os.chmod(TESTFN, 0o444)
+        self.assertEqual(get_mode(), '-r--r--r--')
+
+    def test_directory(self):
+        os.mkdir(TESTFN)
+        os.chmod(TESTFN, 0o700)
+        self.assertEqual(get_mode(), 'drwx------')
+
+    @unittest.skipUnless(hasattr(os, 'symlink'), 'os.symlink not available')
+    def test_link(self):
+        os.symlink(os.getcwd(), TESTFN)
+        self.assertEqual(get_mode(), 'lrwxrwxrwx')
+
+    @unittest.skipUnless(hasattr(os, 'mkfifo'), 'os.mkfifo not available')
+    def test_fifo(self):
+        os.mkfifo(TESTFN, 0o700)
+        self.assertEqual(get_mode(), 'prwx------')
+
+
+def test_main():
+    run_unittest(TestFilemode)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -31,10 +31,13 @@
 Library
 -------
 
+- Issue 14807: move undocumented tarfile.filemode() to stat.filemode() and add
+  doc entry. Add tarfile.filemode alias with deprecation warning.
+
 - Issue #13815: TarFile.extractfile() now returns io.BufferedReader objects.
 
 - Issue #14532: Add a secure_compare() helper to the hmac module, to mitigate
-  timing attacks. Patch by Jon Oberheide. 
+  timing attacks. Patch by Jon Oberheide.
 
 - Add importlib.util.resolve_name().
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list