Issue #12442: add shutil.disk_usage()

This commit is contained in:
Giampaolo Rodola' 2011-07-01 13:55:36 +02:00
parent 59929d9877
commit 210e7ca032
6 changed files with 77 additions and 1 deletions

View file

@ -164,6 +164,14 @@ Directory and files operations
If the destination is on the current filesystem, then simply use rename. If the destination is on the current filesystem, then simply use rename.
Otherwise, copy src (with :func:`copy2`) to the dst and then remove src. Otherwise, copy src (with :func:`copy2`) to the dst and then remove src.
.. function:: disk_usage(path)
Return disk usage statistics about the given path as a namedtuple including
total, used and free space expressed in bytes.
.. versionadded:: 3.3
Availability: Unix, Windows.
.. exception:: Error .. exception:: Error

View file

@ -200,7 +200,16 @@ The :class:`~ftplib.FTP_TLS` class now provides a new
plaintex. This can be useful to take advantage of firewalls that know how to plaintex. This can be useful to take advantage of firewalls that know how to
handle NAT with non-secure FTP without opening fixed ports. handle NAT with non-secure FTP without opening fixed ports.
(Patch submitted by Giampaolo Rodolà in :issue:`12139`.) (Contributed by Giampaolo Rodolà in :issue:`12139`)
shutil
------
The :mod:`shutil` module has a new :func:`~shutil.disk_usage` providing total,
used and free disk space statistics.
(Contributed by Giampaolo Rodolà in :issue:`12442`)
Optimizations Optimizations

View file

@ -12,6 +12,7 @@ import fnmatch
import collections import collections
import errno import errno
import tarfile import tarfile
from collections import namedtuple
try: try:
import bz2 import bz2
@ -754,3 +755,21 @@ def unpack_archive(filename, extract_dir=None, format=None):
func = _UNPACK_FORMATS[format][1] func = _UNPACK_FORMATS[format][1]
kwargs = dict(_UNPACK_FORMATS[format][2]) kwargs = dict(_UNPACK_FORMATS[format][2])
func(filename, extract_dir, **kwargs) func(filename, extract_dir, **kwargs)
if hasattr(os, "statvfs") or os.name == 'nt':
_ntuple_diskusage = namedtuple('usage', 'total used free')
def disk_usage(path):
"""Return disk usage statistics about the given path as a namedtuple
including total, used and free space expressed in bytes.
"""
if hasattr(os, "statvfs"):
st = os.statvfs(path)
free = (st.f_bavail * st.f_frsize)
total = (st.f_blocks * st.f_frsize)
used = (st.f_blocks - st.f_bfree) * st.f_frsize
else:
import nt
total, free = nt._getdiskusage(path)
used = total - free
return _ntuple_diskusage(total, used, free)

View file

@ -728,6 +728,16 @@ class TestShutil(unittest.TestCase):
unregister_unpack_format('Boo2') unregister_unpack_format('Boo2')
self.assertEqual(get_unpack_formats(), formats) self.assertEqual(get_unpack_formats(), formats)
@unittest.skipUnless(hasattr(shutil, 'disk_usage'),
"disk_usage not available on this platform")
def test_disk_usage(self):
usage = shutil.disk_usage(os.getcwd())
self.assertTrue(usage.total > 0)
self.assertTrue(usage.used > 0)
self.assertTrue(usage.free >= 0)
self.assertTrue(usage.total >= usage.used)
self.assertTrue(usage.total > usage.free)
class TestMove(unittest.TestCase): class TestMove(unittest.TestCase):

View file

@ -200,6 +200,9 @@ Core and Builtins
Library Library
------- -------
- Issue #12442: new shutil.disk_usage function, providing total, used and free
disk space statistics.
- Issue #12451: The XInclude default loader of xml.etree now decodes files from - Issue #12451: The XInclude default loader of xml.etree now decodes files from
UTF-8 instead of the locale encoding if the encoding is not specified. It now UTF-8 instead of the locale encoding if the encoding is not specified. It now
also opens XML files for the parser in binary mode instead of the text mode also opens XML files for the parser in binary mode instead of the text mode

View file

@ -7451,6 +7451,32 @@ posix_statvfs(PyObject *self, PyObject *args)
} }
#endif /* HAVE_STATVFS */ #endif /* HAVE_STATVFS */
#ifdef MS_WINDOWS
PyDoc_STRVAR(win32__getdiskusage__doc__,
"_getdiskusage(path) -> (total, free)\n\n\
Return disk usage statistics about the given path as (total, free) tuple.");
static PyObject *
win32__getdiskusage(PyObject *self, PyObject *args)
{
BOOL retval;
ULARGE_INTEGER _, total, free;
LPCTSTR path;
if (! PyArg_ParseTuple(args, "s", &path))
return NULL;
Py_BEGIN_ALLOW_THREADS
retval = GetDiskFreeSpaceEx(path, &_, &total, &free);
Py_END_ALLOW_THREADS
if (retval == 0)
return PyErr_SetFromWindowsErr(0);
return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
}
#endif
/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
* It maps strings representing configuration variable names to * It maps strings representing configuration variable names to
* integer values, allowing those functions to be called with the * integer values, allowing those functions to be called with the
@ -9716,6 +9742,7 @@ static PyMethodDef posix_methods[] = {
{"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
{"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
{"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
{"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__},
#endif #endif
#ifdef HAVE_GETLOADAVG #ifdef HAVE_GETLOADAVG
{"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},