Eliminate direct dependencies of Tahoe-LAFS on pywin32 (rebased to trunk). refs #1274

This commit is contained in:
david-sarah 2011-01-18 23:59:11 -08:00
parent 3798d9946e
commit d21f4071c3
3 changed files with 56 additions and 29 deletions

View File

@ -69,9 +69,6 @@ if sys.version_info < (2, 5):
## # it is going to offer iocp reactor. We currently require process management. It would be
## # better if Twisted would declare that it requires pywin32 if it is going to offer process
## # management. That is twisted ticket #3238 -- http://twistedmatrix.com/trac/ticket/3238 .
## # On the other hand, Tahoe also depends on pywin32 for getting free disk space statistics
## # (although that is not a hard requirement: if win32api can't be imported then we don't
## # rely on having the disk stats).
## install_requires.append('pywin32')
if hasattr(sys, 'frozen'): # for py2exe

View File

@ -305,16 +305,27 @@ def abspath_expanduser_unicode(path):
# there is always at least one Unicode path component.
return os.path.normpath(path)
windows = False
try:
import win32api, win32con
except ImportError:
pass
else:
windows = True
# <http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx>
win32api.SetErrorMode(win32con.SEM_FAILCRITICALERRORS |
win32con.SEM_NOOPENFILEERRORBOX)
have_GetDiskFreeSpaceExW = False
if sys.platform == "win32":
try:
from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_ulonglong
from ctypes.wintypes import BOOL, DWORD, LPCWSTR
# <http://msdn.microsoft.com/en-us/library/aa383742%28v=VS.85%29.aspx>
PULARGE_INTEGER = POINTER(c_ulonglong)
# <http://msdn.microsoft.com/en-us/library/aa364937%28VS.85%29.aspx>
GetDiskFreeSpaceExW = WINFUNCTYPE(BOOL, LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)(
("GetDiskFreeSpaceExW", windll.kernel32))
# <http://msdn.microsoft.com/en-us/library/ms679360%28v=VS.85%29.aspx>
GetLastError = WINFUNCTYPE(DWORD)(("GetLastError", windll.kernel32))
have_GetDiskFreeSpaceExW = True
except Exception:
import traceback
traceback.print_exc()
def get_disk_stats(whichdir, reserved_space=0):
"""Return disk statistics for the storage disk, in the form of a dict
@ -338,15 +349,24 @@ def get_disk_stats(whichdir, reserved_space=0):
filesystem as reserved_space.
"""
if windows:
# For Windows systems, where os.statvfs is not available, use GetDiskFreeSpaceEx.
# <http://docs.activestate.com/activepython/2.5/pywin32/win32api__GetDiskFreeSpaceEx_meth.html>
#
# Although the docs say that the argument should be the root directory
# of a disk, GetDiskFreeSpaceEx actually accepts any path on that disk
# (like its Win32 equivalent).
if have_GetDiskFreeSpaceExW:
# If this is a Windows system and GetDiskFreeSpaceExW is available, use it.
# (This might put up an error dialog unless
# SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX) has been called,
# which we do in allmydata.windows.fixups.initialize().)
(free_for_nonroot, total, free_for_root) = win32api.GetDiskFreeSpaceEx(whichdir)
n_free_for_nonroot = c_ulonglong(0)
n_total = c_ulonglong(0)
n_free_for_root = c_ulonglong(0)
retval = GetDiskFreeSpaceExW(whichdir, byref(n_free_for_nonroot),
byref(n_total),
byref(n_free_for_root))
if retval == 0:
raise OSError("Windows error %d attempting to get disk statistics for %r"
% (GetLastError(), whichdir))
free_for_nonroot = n_free_for_nonroot.value
total = n_total.value
free_for_root = n_free_for_root.value
else:
# For Unix-like systems.
# <http://docs.python.org/library/os.html#os.statvfs>
@ -372,9 +392,12 @@ def get_disk_stats(whichdir, reserved_space=0):
used = total - free_for_root
avail = max(free_for_nonroot - reserved_space, 0)
return { 'total': total, 'free_for_root': free_for_root,
return { 'total': total,
'free_for_root': free_for_root,
'free_for_nonroot': free_for_nonroot,
'used': used, 'avail': avail, }
'used': used,
'avail': avail,
}
def get_available_space(whichdir, reserved_space):
"""Returns available space for share storage in bytes, or None if no

View File

@ -8,6 +8,19 @@ def initialize():
return True
done = True
import codecs, re
from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
from ctypes.wintypes import BOOL, HANDLE, DWORD, UINT, LPWSTR, LPCWSTR, LPVOID
from allmydata.util import log
from allmydata.util.encodingutil import canonical_encoding
# <http://msdn.microsoft.com/en-us/library/ms680621%28VS.85%29.aspx>
SetErrorMode = WINFUNCTYPE(UINT, UINT)(("SetErrorMode", windll.kernel32))
SEM_FAILCRITICALERRORS = 0x0001
SEM_NOOPENFILEERRORBOX = 0x8000
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX)
original_stderr = sys.stderr
# If any exception occurs in this code, we'll probably try to print it on stderr,
@ -18,12 +31,6 @@ def initialize():
print >>original_stderr, isinstance(message, str) and message or repr(message)
log.msg(message, level=log.WEIRD)
import codecs, re
from ctypes import WINFUNCTYPE, windll, POINTER, byref, c_int
from ctypes.wintypes import BOOL, HANDLE, DWORD, LPWSTR, LPCWSTR, LPVOID
from allmydata.util import log
from allmydata.util.encodingutil import canonical_encoding
# Work around <http://bugs.python.org/issue6058>.
codecs.register(lambda name: name == 'cp65001' and codecs.lookup('utf-8') or None)