comparison mercurial/win32.py @ 8951:835a51e63c5b

windows: fix use of undefined exception (issue1707) This fixes the implied reliance on pywin32 and the win32 module. This also fixes a regression in ae275ad46bd0 that made Mercurial unusable without pywin32.
author Henrik Stuart <hg@hstuart.dk>
date Thu, 25 Jun 2009 22:43:58 +0200
parents 284fda4cd093
children 061eeb602354
comparison
equal deleted inserted replaced
8950:be6b57b2bdb8 8951:835a51e63c5b
18 import errno, os, sys, pywintypes, win32con, win32file, win32process 18 import errno, os, sys, pywintypes, win32con, win32file, win32process
19 import winerror 19 import winerror
20 import osutil, encoding 20 import osutil, encoding
21 from win32com.shell import shell,shellcon 21 from win32com.shell import shell,shellcon
22 22
23 class WinError(Exception):
24 winerror_map = {
25 winerror.ERROR_ACCESS_DENIED: errno.EACCES,
26 winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
27 winerror.ERROR_ACCOUNT_RESTRICTION: errno.EACCES,
28 winerror.ERROR_ALREADY_ASSIGNED: errno.EBUSY,
29 winerror.ERROR_ALREADY_EXISTS: errno.EEXIST,
30 winerror.ERROR_ARITHMETIC_OVERFLOW: errno.ERANGE,
31 winerror.ERROR_BAD_COMMAND: errno.EIO,
32 winerror.ERROR_BAD_DEVICE: errno.ENODEV,
33 winerror.ERROR_BAD_DRIVER_LEVEL: errno.ENXIO,
34 winerror.ERROR_BAD_EXE_FORMAT: errno.ENOEXEC,
35 winerror.ERROR_BAD_FORMAT: errno.ENOEXEC,
36 winerror.ERROR_BAD_LENGTH: errno.EINVAL,
37 winerror.ERROR_BAD_PATHNAME: errno.ENOENT,
38 winerror.ERROR_BAD_PIPE: errno.EPIPE,
39 winerror.ERROR_BAD_UNIT: errno.ENODEV,
40 winerror.ERROR_BAD_USERNAME: errno.EINVAL,
41 winerror.ERROR_BROKEN_PIPE: errno.EPIPE,
42 winerror.ERROR_BUFFER_OVERFLOW: errno.ENAMETOOLONG,
43 winerror.ERROR_BUSY: errno.EBUSY,
44 winerror.ERROR_BUSY_DRIVE: errno.EBUSY,
45 winerror.ERROR_CALL_NOT_IMPLEMENTED: errno.ENOSYS,
46 winerror.ERROR_CANNOT_MAKE: errno.EACCES,
47 winerror.ERROR_CANTOPEN: errno.EIO,
48 winerror.ERROR_CANTREAD: errno.EIO,
49 winerror.ERROR_CANTWRITE: errno.EIO,
50 winerror.ERROR_CRC: errno.EIO,
51 winerror.ERROR_CURRENT_DIRECTORY: errno.EACCES,
52 winerror.ERROR_DEVICE_IN_USE: errno.EBUSY,
53 winerror.ERROR_DEV_NOT_EXIST: errno.ENODEV,
54 winerror.ERROR_DIRECTORY: errno.EINVAL,
55 winerror.ERROR_DIR_NOT_EMPTY: errno.ENOTEMPTY,
56 winerror.ERROR_DISK_CHANGE: errno.EIO,
57 winerror.ERROR_DISK_FULL: errno.ENOSPC,
58 winerror.ERROR_DRIVE_LOCKED: errno.EBUSY,
59 winerror.ERROR_ENVVAR_NOT_FOUND: errno.EINVAL,
60 winerror.ERROR_EXE_MARKED_INVALID: errno.ENOEXEC,
61 winerror.ERROR_FILENAME_EXCED_RANGE: errno.ENAMETOOLONG,
62 winerror.ERROR_FILE_EXISTS: errno.EEXIST,
63 winerror.ERROR_FILE_INVALID: errno.ENODEV,
64 winerror.ERROR_FILE_NOT_FOUND: errno.ENOENT,
65 winerror.ERROR_GEN_FAILURE: errno.EIO,
66 winerror.ERROR_HANDLE_DISK_FULL: errno.ENOSPC,
67 winerror.ERROR_INSUFFICIENT_BUFFER: errno.ENOMEM,
68 winerror.ERROR_INVALID_ACCESS: errno.EACCES,
69 winerror.ERROR_INVALID_ADDRESS: errno.EFAULT,
70 winerror.ERROR_INVALID_BLOCK: errno.EFAULT,
71 winerror.ERROR_INVALID_DATA: errno.EINVAL,
72 winerror.ERROR_INVALID_DRIVE: errno.ENODEV,
73 winerror.ERROR_INVALID_EXE_SIGNATURE: errno.ENOEXEC,
74 winerror.ERROR_INVALID_FLAGS: errno.EINVAL,
75 winerror.ERROR_INVALID_FUNCTION: errno.ENOSYS,
76 winerror.ERROR_INVALID_HANDLE: errno.EBADF,
77 winerror.ERROR_INVALID_LOGON_HOURS: errno.EACCES,
78 winerror.ERROR_INVALID_NAME: errno.EINVAL,
79 winerror.ERROR_INVALID_OWNER: errno.EINVAL,
80 winerror.ERROR_INVALID_PARAMETER: errno.EINVAL,
81 winerror.ERROR_INVALID_PASSWORD: errno.EPERM,
82 winerror.ERROR_INVALID_PRIMARY_GROUP: errno.EINVAL,
83 winerror.ERROR_INVALID_SIGNAL_NUMBER: errno.EINVAL,
84 winerror.ERROR_INVALID_TARGET_HANDLE: errno.EIO,
85 winerror.ERROR_INVALID_WORKSTATION: errno.EACCES,
86 winerror.ERROR_IO_DEVICE: errno.EIO,
87 winerror.ERROR_IO_INCOMPLETE: errno.EINTR,
88 winerror.ERROR_LOCKED: errno.EBUSY,
89 winerror.ERROR_LOCK_VIOLATION: errno.EACCES,
90 winerror.ERROR_LOGON_FAILURE: errno.EACCES,
91 winerror.ERROR_MAPPED_ALIGNMENT: errno.EINVAL,
92 winerror.ERROR_META_EXPANSION_TOO_LONG: errno.E2BIG,
93 winerror.ERROR_MORE_DATA: errno.EPIPE,
94 winerror.ERROR_NEGATIVE_SEEK: errno.ESPIPE,
95 winerror.ERROR_NOACCESS: errno.EFAULT,
96 winerror.ERROR_NONE_MAPPED: errno.EINVAL,
97 winerror.ERROR_NOT_ENOUGH_MEMORY: errno.ENOMEM,
98 winerror.ERROR_NOT_READY: errno.EAGAIN,
99 winerror.ERROR_NOT_SAME_DEVICE: errno.EXDEV,
100 winerror.ERROR_NO_DATA: errno.EPIPE,
101 winerror.ERROR_NO_MORE_SEARCH_HANDLES: errno.EIO,
102 winerror.ERROR_NO_PROC_SLOTS: errno.EAGAIN,
103 winerror.ERROR_NO_SUCH_PRIVILEGE: errno.EACCES,
104 winerror.ERROR_OPEN_FAILED: errno.EIO,
105 winerror.ERROR_OPEN_FILES: errno.EBUSY,
106 winerror.ERROR_OPERATION_ABORTED: errno.EINTR,
107 winerror.ERROR_OUTOFMEMORY: errno.ENOMEM,
108 winerror.ERROR_PASSWORD_EXPIRED: errno.EACCES,
109 winerror.ERROR_PATH_BUSY: errno.EBUSY,
110 winerror.ERROR_PATH_NOT_FOUND: errno.ENOENT,
111 winerror.ERROR_PIPE_BUSY: errno.EBUSY,
112 winerror.ERROR_PIPE_CONNECTED: errno.EPIPE,
113 winerror.ERROR_PIPE_LISTENING: errno.EPIPE,
114 winerror.ERROR_PIPE_NOT_CONNECTED: errno.EPIPE,
115 winerror.ERROR_PRIVILEGE_NOT_HELD: errno.EACCES,
116 winerror.ERROR_READ_FAULT: errno.EIO,
117 winerror.ERROR_SEEK: errno.EIO,
118 winerror.ERROR_SEEK_ON_DEVICE: errno.ESPIPE,
119 winerror.ERROR_SHARING_BUFFER_EXCEEDED: errno.ENFILE,
120 winerror.ERROR_SHARING_VIOLATION: errno.EACCES,
121 winerror.ERROR_STACK_OVERFLOW: errno.ENOMEM,
122 winerror.ERROR_SWAPERROR: errno.ENOENT,
123 winerror.ERROR_TOO_MANY_MODULES: errno.EMFILE,
124 winerror.ERROR_TOO_MANY_OPEN_FILES: errno.EMFILE,
125 winerror.ERROR_UNRECOGNIZED_MEDIA: errno.ENXIO,
126 winerror.ERROR_UNRECOGNIZED_VOLUME: errno.ENODEV,
127 winerror.ERROR_WAIT_NO_CHILDREN: errno.ECHILD,
128 winerror.ERROR_WRITE_FAULT: errno.EIO,
129 winerror.ERROR_WRITE_PROTECT: errno.EROFS,
130 }
131
132 def __init__(self, err):
133 try:
134 # unpack a pywintypes.error tuple
135 self.win_errno, self.win_function, self.win_strerror = err
136 except ValueError:
137 # get attributes from a WindowsError
138 self.win_errno = err.winerror
139 self.win_function = None
140 self.win_strerror = err.strerror
141 self.win_strerror = self.win_strerror.rstrip('.')
142
143 class WinIOError(WinError, IOError):
144 def __init__(self, err, filename=None):
145 WinError.__init__(self, err)
146 IOError.__init__(self, self.winerror_map.get(self.win_errno, 0),
147 self.win_strerror)
148 self.filename = filename
149
150 class WinOSError(WinError, OSError):
151 def __init__(self, err):
152 WinError.__init__(self, err)
153 OSError.__init__(self, self.winerror_map.get(self.win_errno, 0),
154 self.win_strerror)
155
156 def os_link(src, dst): 23 def os_link(src, dst):
157 try: 24 try:
158 win32file.CreateHardLink(dst, src) 25 win32file.CreateHardLink(dst, src)
159 # CreateHardLink sometimes succeeds on mapped drives but 26 # CreateHardLink sometimes succeeds on mapped drives but
160 # following nlinks() returns 1. Check it now and bail out. 27 # following nlinks() returns 1. Check it now and bail out.
162 try: 29 try:
163 win32file.DeleteFile(dst) 30 win32file.DeleteFile(dst)
164 except: 31 except:
165 pass 32 pass
166 # Fake hardlinking error 33 # Fake hardlinking error
167 raise WinOSError((18, 'CreateHardLink', 'The system cannot ' 34 raise OSError(errno.EINVAL, 'Hardlinking not supported')
168 'move the file to a different disk drive'))
169 except pywintypes.error, details: 35 except pywintypes.error, details:
170 raise WinOSError(details) 36 raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
171 except NotImplementedError: # Another fake error win Win98 37 except NotImplementedError: # Another fake error win Win98
172 raise WinOSError((18, 'CreateHardLink', 'Hardlinking not supported')) 38 raise OSError(errno.EINVAL, 'Hardlinking not supported')
173 39
174 def nlinks(pathname): 40 def nlinks(pathname):
175 """Return number of hardlinks for the given file.""" 41 """Return number of hardlinks for the given file."""
176 try: 42 try:
177 fh = win32file.CreateFile(pathname, 43 fh = win32file.CreateFile(pathname,