##// END OF EJS Templates
windows: eliminate win32 wildcard import
Adrian Buehlmann -
r14985:dbf91976 default
parent child Browse files
Show More
@@ -1,297 +1,310 b''
1 1 # windows.py - Windows utility function implementations for Mercurial
2 2 #
3 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from i18n import _
9 9 import osutil
10 10 import errno, msvcrt, os, re, sys
11 11
12 from win32 import executablepath
13 from win32 import getuser
14 from win32 import hidewindow
15 from win32 import lookupreg
16 from win32 import makedir
17 from win32 import nlinks
18 from win32 import oslink
19 from win32 import samedevice
20 from win32 import samefile
21 from win32 import setsignalhandler
22 from win32 import spawndetached
23 from win32 import termwidth
24 from win32 import testpid
25 from win32 import unlink
26
12 27 nulldev = 'NUL:'
13 28 umask = 002
14 29
15 30 # wrap osutil.posixfile to provide friendlier exceptions
16 31 def posixfile(name, mode='r', buffering=-1):
17 32 try:
18 33 return osutil.posixfile(name, mode, buffering)
19 34 except WindowsError, err:
20 35 raise IOError(err.errno, '%s: %s' % (name, err.strerror))
21 36 posixfile.__doc__ = osutil.posixfile.__doc__
22 37
23 38 class winstdout(object):
24 39 '''stdout on windows misbehaves if sent through a pipe'''
25 40
26 41 def __init__(self, fp):
27 42 self.fp = fp
28 43
29 44 def __getattr__(self, key):
30 45 return getattr(self.fp, key)
31 46
32 47 def close(self):
33 48 try:
34 49 self.fp.close()
35 50 except IOError:
36 51 pass
37 52
38 53 def write(self, s):
39 54 try:
40 55 # This is workaround for "Not enough space" error on
41 56 # writing large size of data to console.
42 57 limit = 16000
43 58 l = len(s)
44 59 start = 0
45 60 self.softspace = 0
46 61 while start < l:
47 62 end = start + limit
48 63 self.fp.write(s[start:end])
49 64 start = end
50 65 except IOError, inst:
51 66 if inst.errno != 0:
52 67 raise
53 68 self.close()
54 69 raise IOError(errno.EPIPE, 'Broken pipe')
55 70
56 71 def flush(self):
57 72 try:
58 73 return self.fp.flush()
59 74 except IOError, inst:
60 75 if inst.errno != errno.EINVAL:
61 76 raise
62 77 self.close()
63 78 raise IOError(errno.EPIPE, 'Broken pipe')
64 79
65 80 sys.__stdout__ = sys.stdout = winstdout(sys.stdout)
66 81
67 82 def _is_win_9x():
68 83 '''return true if run on windows 95, 98 or me.'''
69 84 try:
70 85 return sys.getwindowsversion()[3] == 1
71 86 except AttributeError:
72 87 return 'command' in os.environ.get('comspec', '')
73 88
74 89 def openhardlinks():
75 90 return not _is_win_9x()
76 91
77 92 def parsepatchoutput(output_line):
78 93 """parses the output produced by patch and returns the filename"""
79 94 pf = output_line[14:]
80 95 if pf[0] == '`':
81 96 pf = pf[1:-1] # Remove the quotes
82 97 return pf
83 98
84 99 def sshargs(sshcmd, host, user, port):
85 100 '''Build argument list for ssh or Plink'''
86 101 pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
87 102 args = user and ("%s@%s" % (user, host)) or host
88 103 return port and ("%s %s %s" % (args, pflag, port)) or args
89 104
90 105 def setflags(f, l, x):
91 106 pass
92 107
93 108 def checkexec(path):
94 109 return False
95 110
96 111 def checklink(path):
97 112 return False
98 113
99 114 def setbinary(fd):
100 115 # When run without console, pipes may expose invalid
101 116 # fileno(), usually set to -1.
102 117 fno = getattr(fd, 'fileno', None)
103 118 if fno is not None and fno() >= 0:
104 119 msvcrt.setmode(fno(), os.O_BINARY)
105 120
106 121 def pconvert(path):
107 122 return '/'.join(path.split(os.sep))
108 123
109 124 def localpath(path):
110 125 return path.replace('/', '\\')
111 126
112 127 def normpath(path):
113 128 return pconvert(os.path.normpath(path))
114 129
115 130 def realpath(path):
116 131 '''
117 132 Returns the true, canonical file system path equivalent to the given
118 133 path.
119 134 '''
120 135 # TODO: There may be a more clever way to do this that also handles other,
121 136 # less common file systems.
122 137 return os.path.normpath(os.path.normcase(os.path.realpath(path)))
123 138
124 139 def samestat(s1, s2):
125 140 return False
126 141
127 142 # A sequence of backslashes is special iff it precedes a double quote:
128 143 # - if there's an even number of backslashes, the double quote is not
129 144 # quoted (i.e. it ends the quoted region)
130 145 # - if there's an odd number of backslashes, the double quote is quoted
131 146 # - in both cases, every pair of backslashes is unquoted into a single
132 147 # backslash
133 148 # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
134 149 # So, to quote a string, we must surround it in double quotes, double
135 150 # the number of backslashes that preceed double quotes and add another
136 151 # backslash before every double quote (being careful with the double
137 152 # quote we've appended to the end)
138 153 _quotere = None
139 154 def shellquote(s):
140 155 global _quotere
141 156 if _quotere is None:
142 157 _quotere = re.compile(r'(\\*)("|\\$)')
143 158 return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
144 159
145 160 def quotecommand(cmd):
146 161 """Build a command string suitable for os.popen* calls."""
147 162 if sys.version_info < (2, 7, 1):
148 163 # Python versions since 2.7.1 do this extra quoting themselves
149 164 return '"' + cmd + '"'
150 165 return cmd
151 166
152 167 def popen(command, mode='r'):
153 168 # Work around "popen spawned process may not write to stdout
154 169 # under windows"
155 170 # http://bugs.python.org/issue1366
156 171 command += " 2> %s" % nulldev
157 172 return os.popen(quotecommand(command), mode)
158 173
159 174 def explainexit(code):
160 175 return _("exited with status %d") % code, code
161 176
162 177 # if you change this stub into a real check, please try to implement the
163 178 # username and groupname functions above, too.
164 179 def isowner(st):
165 180 return True
166 181
167 182 def findexe(command):
168 183 '''Find executable for command searching like cmd.exe does.
169 184 If command is a basename then PATH is searched for command.
170 185 PATH isn't searched if command is an absolute or relative path.
171 186 An extension from PATHEXT is found and added if not present.
172 187 If command isn't found None is returned.'''
173 188 pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
174 189 pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
175 190 if os.path.splitext(command)[1].lower() in pathexts:
176 191 pathexts = ['']
177 192
178 193 def findexisting(pathcommand):
179 194 'Will append extension (if needed) and return existing file'
180 195 for ext in pathexts:
181 196 executable = pathcommand + ext
182 197 if os.path.exists(executable):
183 198 return executable
184 199 return None
185 200
186 201 if os.sep in command:
187 202 return findexisting(command)
188 203
189 204 for path in os.environ.get('PATH', '').split(os.pathsep):
190 205 executable = findexisting(os.path.join(path, command))
191 206 if executable is not None:
192 207 return executable
193 208 return findexisting(os.path.expanduser(os.path.expandvars(command)))
194 209
195 210 def statfiles(files):
196 211 '''Stat each file in files and yield stat or None if file does not exist.
197 212 Cluster and cache stat per directory to minimize number of OS stat calls.'''
198 213 ncase = os.path.normcase
199 214 dircache = {} # dirname -> filename -> status | None if file does not exist
200 215 for nf in files:
201 216 nf = ncase(nf)
202 217 dir, base = os.path.split(nf)
203 218 if not dir:
204 219 dir = '.'
205 220 cache = dircache.get(dir, None)
206 221 if cache is None:
207 222 try:
208 223 dmap = dict([(ncase(n), s)
209 224 for n, k, s in osutil.listdir(dir, True)])
210 225 except OSError, err:
211 226 # handle directory not found in Python version prior to 2.5
212 227 # Python <= 2.4 returns native Windows code 3 in errno
213 228 # Python >= 2.5 returns ENOENT and adds winerror field
214 229 # EINVAL is raised if dir is not a directory.
215 230 if err.errno not in (3, errno.ENOENT, errno.EINVAL,
216 231 errno.ENOTDIR):
217 232 raise
218 233 dmap = {}
219 234 cache = dircache.setdefault(dir, dmap)
220 235 yield cache.get(base, None)
221 236
222 237 def username(uid=None):
223 238 """Return the name of the user with the given uid.
224 239
225 240 If uid is None, return the name of the current user."""
226 241 return None
227 242
228 243 def groupname(gid=None):
229 244 """Return the name of the group with the given gid.
230 245
231 246 If gid is None, return the name of the current group."""
232 247 return None
233 248
234 249 def _removedirs(name):
235 250 """special version of os.removedirs that does not remove symlinked
236 251 directories or junction points if they actually contain files"""
237 252 if osutil.listdir(name):
238 253 return
239 254 os.rmdir(name)
240 255 head, tail = os.path.split(name)
241 256 if not tail:
242 257 head, tail = os.path.split(head)
243 258 while head and tail:
244 259 try:
245 260 if osutil.listdir(head):
246 261 return
247 262 os.rmdir(head)
248 263 except (ValueError, OSError):
249 264 break
250 265 head, tail = os.path.split(head)
251 266
252 267 def unlinkpath(f):
253 268 """unlink and remove the directory if it is empty"""
254 269 unlink(f)
255 270 # try removing directories that might now be empty
256 271 try:
257 272 _removedirs(os.path.dirname(f))
258 273 except OSError:
259 274 pass
260 275
261 276 def rename(src, dst):
262 277 '''atomically rename file src to dst, replacing dst if it exists'''
263 278 try:
264 279 os.rename(src, dst)
265 280 except OSError, e:
266 281 if e.errno != errno.EEXIST:
267 282 raise
268 283 unlink(dst)
269 284 os.rename(src, dst)
270 285
271 286 def gethgcmd():
272 287 return [sys.executable] + sys.argv[:1]
273 288
274 289 def termwidth():
275 290 # cmd.exe does not handle CR like a unix console, the CR is
276 291 # counted in the line length. On 80 columns consoles, if 80
277 292 # characters are written, the following CR won't apply on the
278 293 # current line but on the new one. Keep room for it.
279 294 return 79
280 295
281 296 def groupmembers(name):
282 297 # Don't support groups on Windows for now
283 298 raise KeyError()
284 299
285 300 def isexec(f):
286 301 return False
287 302
288 from win32 import *
289
290 303 class cachestat(object):
291 304 def __init__(self, path):
292 305 pass
293 306
294 307 def cacheable(self):
295 308 return False
296 309
297 310 expandglobs = True
@@ -1,12 +1,11 b''
1 1 $ "$TESTDIR/hghave" pyflakes || exit 80
2 2 $ cd $(dirname $TESTDIR)
3 3 $ pyflakes mercurial hgext 2>&1 | $TESTDIR/filterpyflakes.py
4 4 mercurial/hgweb/server.py:*: 'activeCount' imported but unused (glob)
5 5 mercurial/commands.py:*: 'base85' imported but unused (glob)
6 6 mercurial/commands.py:*: 'bdiff' imported but unused (glob)
7 7 mercurial/commands.py:*: 'mpatch' imported but unused (glob)
8 8 mercurial/commands.py:*: 'osutil' imported but unused (glob)
9 9 hgext/inotify/linux/__init__.py:*: 'from _inotify import *' used; unable to detect undefined names (glob)
10 mercurial/windows.py:*: 'from win32 import *' used; unable to detect undefined names (glob)
11 10
12 11
General Comments 0
You need to be logged in to leave comments. Login now