##// END OF EJS Templates
typing: add type hints to most mercurial/pycompat.py functions...
Matt Harbison -
r50702:c5a06cc3 default
parent child Browse files
Show More
@@ -29,12 +29,22 b' import tempfile'
29 import xmlrpc.client as xmlrpclib
29 import xmlrpc.client as xmlrpclib
30
30
31 from typing import (
31 from typing import (
32 Any,
33 AnyStr,
34 BinaryIO,
35 Dict,
32 Iterable,
36 Iterable,
33 Iterator,
37 Iterator,
34 List,
38 List,
39 Mapping,
40 NoReturn,
35 Optional,
41 Optional,
42 Sequence,
43 Tuple,
36 Type,
44 Type,
37 TypeVar,
45 TypeVar,
46 cast,
47 overload,
38 )
48 )
39
49
40 ispy3 = sys.version_info[0] >= 3
50 ispy3 = sys.version_info[0] >= 3
@@ -46,6 +56,8 b' if not globals(): # hide this from non-'
46
56
47 TYPE_CHECKING = typing.TYPE_CHECKING
57 TYPE_CHECKING = typing.TYPE_CHECKING
48
58
59 _GetOptResult = Tuple[List[Tuple[bytes, bytes]], List[bytes]]
60 _T0 = TypeVar('_T0')
49 _Tbytestr = TypeVar('_Tbytestr', bound='bytestr')
61 _Tbytestr = TypeVar('_Tbytestr', bound='bytestr')
50
62
51
63
@@ -56,7 +68,7 b' def future_set_exception_info(f, exc_inf'
56 FileNotFoundError = builtins.FileNotFoundError
68 FileNotFoundError = builtins.FileNotFoundError
57
69
58
70
59 def identity(a):
71 def identity(a: _T0) -> _T0:
60 return a
72 return a
61
73
62
74
@@ -250,6 +262,17 b' def iterbytestr(s: Iterable[int]) -> Ite'
250 return map(bytechr, s)
262 return map(bytechr, s)
251
263
252
264
265 if TYPE_CHECKING:
266
267 @overload
268 def maybebytestr(s: bytes) -> bytestr:
269 ...
270
271 @overload
272 def maybebytestr(s: _T0) -> _T0:
273 ...
274
275
253 def maybebytestr(s):
276 def maybebytestr(s):
254 """Promote bytes to bytestr"""
277 """Promote bytes to bytestr"""
255 if isinstance(s, bytes):
278 if isinstance(s, bytes):
@@ -257,7 +280,7 b' def maybebytestr(s):'
257 return s
280 return s
258
281
259
282
260 def sysbytes(s):
283 def sysbytes(s: AnyStr) -> bytes:
261 """Convert an internal str (e.g. keyword, __doc__) back to bytes
284 """Convert an internal str (e.g. keyword, __doc__) back to bytes
262
285
263 This never raises UnicodeEncodeError, but only ASCII characters
286 This never raises UnicodeEncodeError, but only ASCII characters
@@ -268,7 +291,7 b' def sysbytes(s):'
268 return s.encode('utf-8')
291 return s.encode('utf-8')
269
292
270
293
271 def sysstr(s):
294 def sysstr(s: AnyStr) -> str:
272 """Return a keyword str to be passed to Python functions such as
295 """Return a keyword str to be passed to Python functions such as
273 getattr() and str.encode()
296 getattr() and str.encode()
274
297
@@ -281,26 +304,26 b' def sysstr(s):'
281 return s.decode('latin-1')
304 return s.decode('latin-1')
282
305
283
306
284 def strurl(url):
307 def strurl(url: AnyStr) -> str:
285 """Converts a bytes url back to str"""
308 """Converts a bytes url back to str"""
286 if isinstance(url, bytes):
309 if isinstance(url, bytes):
287 return url.decode('ascii')
310 return url.decode('ascii')
288 return url
311 return url
289
312
290
313
291 def bytesurl(url):
314 def bytesurl(url: AnyStr) -> bytes:
292 """Converts a str url to bytes by encoding in ascii"""
315 """Converts a str url to bytes by encoding in ascii"""
293 if isinstance(url, str):
316 if isinstance(url, str):
294 return url.encode('ascii')
317 return url.encode('ascii')
295 return url
318 return url
296
319
297
320
298 def raisewithtb(exc, tb):
321 def raisewithtb(exc: BaseException, tb) -> NoReturn:
299 """Raise exception with the given traceback"""
322 """Raise exception with the given traceback"""
300 raise exc.with_traceback(tb)
323 raise exc.with_traceback(tb)
301
324
302
325
303 def getdoc(obj):
326 def getdoc(obj: object) -> Optional[bytes]:
304 """Get docstring as bytes; may be None so gettext() won't confuse it
327 """Get docstring as bytes; may be None so gettext() won't confuse it
305 with _('')"""
328 with _('')"""
306 doc = builtins.getattr(obj, '__doc__', None)
329 doc = builtins.getattr(obj, '__doc__', None)
@@ -326,14 +349,22 b' xrange = builtins.range'
326 unicode = str
349 unicode = str
327
350
328
351
329 def open(name, mode=b'r', buffering=-1, encoding=None):
352 def open(
353 name,
354 mode: AnyStr = b'r',
355 buffering: int = -1,
356 encoding: Optional[str] = None,
357 ) -> Any:
358 # TODO: assert binary mode, and cast result to BinaryIO?
330 return builtins.open(name, sysstr(mode), buffering, encoding)
359 return builtins.open(name, sysstr(mode), buffering, encoding)
331
360
332
361
333 safehasattr = _wrapattrfunc(builtins.hasattr)
362 safehasattr = _wrapattrfunc(builtins.hasattr)
334
363
335
364
336 def _getoptbwrapper(orig, args, shortlist, namelist):
365 def _getoptbwrapper(
366 orig, args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
367 ) -> _GetOptResult:
337 """
368 """
338 Takes bytes arguments, converts them to unicode, pass them to
369 Takes bytes arguments, converts them to unicode, pass them to
339 getopt.getopt(), convert the returned values back to bytes and then
370 getopt.getopt(), convert the returned values back to bytes and then
@@ -349,7 +380,7 b' def _getoptbwrapper(orig, args, shortlis'
349 return opts, args
380 return opts, args
350
381
351
382
352 def strkwargs(dic):
383 def strkwargs(dic: Mapping[bytes, _T0]) -> Dict[str, _T0]:
353 """
384 """
354 Converts the keys of a python dictonary to str i.e. unicodes so that
385 Converts the keys of a python dictonary to str i.e. unicodes so that
355 they can be passed as keyword arguments as dictionaries with bytes keys
386 they can be passed as keyword arguments as dictionaries with bytes keys
@@ -359,7 +390,7 b' def strkwargs(dic):'
359 return dic
390 return dic
360
391
361
392
362 def byteskwargs(dic):
393 def byteskwargs(dic: Mapping[str, _T0]) -> Dict[bytes, _T0]:
363 """
394 """
364 Converts keys of python dictionaries to bytes as they were converted to
395 Converts keys of python dictionaries to bytes as they were converted to
365 str to pass that dictonary as a keyword argument on Python 3.
396 str to pass that dictonary as a keyword argument on Python 3.
@@ -369,7 +400,9 b' def byteskwargs(dic):'
369
400
370
401
371 # TODO: handle shlex.shlex().
402 # TODO: handle shlex.shlex().
372 def shlexsplit(s, comments=False, posix=True):
403 def shlexsplit(
404 s: bytes, comments: bool = False, posix: bool = True
405 ) -> List[bytes]:
373 """
406 """
374 Takes bytes argument, convert it to str i.e. unicodes, pass that into
407 Takes bytes argument, convert it to str i.e. unicodes, pass that into
375 shlex.split(), convert the returned value to bytes and return that for
408 shlex.split(), convert the returned value to bytes and return that for
@@ -392,38 +425,51 b" isposix: bool = osname == b'posix'"
392 iswindows: bool = osname == b'nt'
425 iswindows: bool = osname == b'nt'
393
426
394
427
395 def getoptb(args, shortlist, namelist):
428 def getoptb(
429 args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
430 ) -> _GetOptResult:
396 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
431 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
397
432
398
433
399 def gnugetoptb(args, shortlist, namelist):
434 def gnugetoptb(
435 args: Sequence[bytes], shortlist: bytes, namelist: Sequence[bytes]
436 ) -> _GetOptResult:
400 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
437 return _getoptbwrapper(getopt.gnu_getopt, args, shortlist, namelist)
401
438
402
439
403 def mkdtemp(suffix=b'', prefix=b'tmp', dir=None):
440 def mkdtemp(
441 suffix: bytes = b'', prefix: bytes = b'tmp', dir: Optional[bytes] = None
442 ) -> bytes:
404 return tempfile.mkdtemp(suffix, prefix, dir)
443 return tempfile.mkdtemp(suffix, prefix, dir)
405
444
406
445
407 # text=True is not supported; use util.from/tonativeeol() instead
446 # text=True is not supported; use util.from/tonativeeol() instead
408 def mkstemp(suffix=b'', prefix=b'tmp', dir=None):
447 def mkstemp(
448 suffix: bytes = b'', prefix: bytes = b'tmp', dir: Optional[bytes] = None
449 ) -> Tuple[int, bytes]:
409 return tempfile.mkstemp(suffix, prefix, dir)
450 return tempfile.mkstemp(suffix, prefix, dir)
410
451
411
452
412 # TemporaryFile does not support an "encoding=" argument on python2.
453 # TemporaryFile does not support an "encoding=" argument on python2.
413 # This wrapper file are always open in byte mode.
454 # This wrapper file are always open in byte mode.
414 def unnamedtempfile(mode=None, *args, **kwargs):
455 def unnamedtempfile(mode: Optional[bytes] = None, *args, **kwargs) -> BinaryIO:
415 if mode is None:
456 if mode is None:
416 mode = 'w+b'
457 mode = 'w+b'
417 else:
458 else:
418 mode = sysstr(mode)
459 mode = sysstr(mode)
419 assert 'b' in mode
460 assert 'b' in mode
420 return tempfile.TemporaryFile(mode, *args, **kwargs)
461 return cast(BinaryIO, tempfile.TemporaryFile(mode, *args, **kwargs))
421
462
422
463
423 # NamedTemporaryFile does not support an "encoding=" argument on python2.
464 # NamedTemporaryFile does not support an "encoding=" argument on python2.
424 # This wrapper file are always open in byte mode.
465 # This wrapper file are always open in byte mode.
425 def namedtempfile(
466 def namedtempfile(
426 mode=b'w+b', bufsize=-1, suffix=b'', prefix=b'tmp', dir=None, delete=True
467 mode: bytes = b'w+b',
468 bufsize: int = -1,
469 suffix: bytes = b'',
470 prefix: bytes = b'tmp',
471 dir: Optional[bytes] = None,
472 delete: bool = True,
427 ):
473 ):
428 mode = sysstr(mode)
474 mode = sysstr(mode)
429 assert 'b' in mode
475 assert 'b' in mode
General Comments 0
You need to be logged in to leave comments. Login now