Show More
@@ -20,10 +20,15 b' import sys' | |||||
20 | import traceback |
|
20 | import traceback | |
21 |
|
21 | |||
22 | from typing import ( |
|
22 | from typing import ( | |
|
23 | Any, | |||
|
24 | Callable, | |||
23 | Dict, |
|
25 | Dict, | |
24 | List, |
|
26 | List, | |
|
27 | NoReturn, | |||
25 | Optional, |
|
28 | Optional, | |
26 | Tuple, |
|
29 | Tuple, | |
|
30 | Type, | |||
|
31 | TypeVar, | |||
27 | Union, |
|
32 | Union, | |
28 | cast, |
|
33 | cast, | |
29 | ) |
|
34 | ) | |
@@ -57,21 +62,23 b' from .utils import (' | |||||
57 | urlutil, |
|
62 | urlutil, | |
58 | ) |
|
63 | ) | |
59 |
|
64 | |||
|
65 | _ConfigItems = Dict[Tuple[bytes, bytes], object] # {(section, name) : value} | |||
60 | # The **opts args of the various write() methods can be basically anything, but |
|
66 | # The **opts args of the various write() methods can be basically anything, but | |
61 | # there's no way to express it as "anything but str". So type it to be the |
|
67 | # there's no way to express it as "anything but str". So type it to be the | |
62 | # handful of known types that are used. |
|
68 | # handful of known types that are used. | |
63 | _MsgOpts = Union[bytes, bool, List["_PromptChoice"]] |
|
69 | _MsgOpts = Union[bytes, bool, List["_PromptChoice"]] | |
64 | _PromptChoice = Tuple[bytes, bytes] |
|
70 | _PromptChoice = Tuple[bytes, bytes] | |
|
71 | _Tui = TypeVar('_Tui', bound="ui") | |||
65 |
|
72 | |||
66 | urlreq = util.urlreq |
|
73 | urlreq = util.urlreq | |
67 |
|
74 | |||
68 | # for use with str.translate(None, _keepalnum), to keep just alphanumerics |
|
75 | # for use with str.translate(None, _keepalnum), to keep just alphanumerics | |
69 | _keepalnum = b''.join( |
|
76 | _keepalnum: bytes = b''.join( | |
70 | c for c in map(pycompat.bytechr, range(256)) if not c.isalnum() |
|
77 | c for c in map(pycompat.bytechr, range(256)) if not c.isalnum() | |
71 | ) |
|
78 | ) | |
72 |
|
79 | |||
73 | # The config knobs that will be altered (if unset) by ui.tweakdefaults. |
|
80 | # The config knobs that will be altered (if unset) by ui.tweakdefaults. | |
74 | tweakrc = b""" |
|
81 | tweakrc: bytes = b""" | |
75 | [ui] |
|
82 | [ui] | |
76 | # The rollback command is dangerous. As a rule, don't use it. |
|
83 | # The rollback command is dangerous. As a rule, don't use it. | |
77 | rollback = False |
|
84 | rollback = False | |
@@ -98,7 +105,7 b' showfunc = 1' | |||||
98 | word-diff = 1 |
|
105 | word-diff = 1 | |
99 | """ |
|
106 | """ | |
100 |
|
107 | |||
101 | samplehgrcs = { |
|
108 | samplehgrcs: Dict[bytes, bytes] = { | |
102 | b'user': b"""# example user config (see 'hg help config' for more info) |
|
109 | b'user': b"""# example user config (see 'hg help config' for more info) | |
103 | [ui] |
|
110 | [ui] | |
104 | # name and email, e.g. |
|
111 | # name and email, e.g. | |
@@ -187,7 +194,7 b' def _maybebytesurl(maybestr):' | |||||
187 | class httppasswordmgrdbproxy: |
|
194 | class httppasswordmgrdbproxy: | |
188 | """Delays loading urllib2 until it's needed.""" |
|
195 | """Delays loading urllib2 until it's needed.""" | |
189 |
|
196 | |||
190 | def __init__(self): |
|
197 | def __init__(self) -> None: | |
191 | self._mgr = None |
|
198 | self._mgr = None | |
192 |
|
199 | |||
193 | def _get_mgr(self): |
|
200 | def _get_mgr(self): | |
@@ -210,7 +217,7 b' class httppasswordmgrdbproxy:' | |||||
210 | ) |
|
217 | ) | |
211 |
|
218 | |||
212 |
|
219 | |||
213 | def _catchterm(*args): |
|
220 | def _catchterm(*args) -> NoReturn: | |
214 | raise error.SignalInterrupt |
|
221 | raise error.SignalInterrupt | |
215 |
|
222 | |||
216 |
|
223 | |||
@@ -219,11 +226,11 b' def _catchterm(*args):' | |||||
219 | _unset = object() |
|
226 | _unset = object() | |
220 |
|
227 | |||
221 | # _reqexithandlers: callbacks run at the end of a request |
|
228 | # _reqexithandlers: callbacks run at the end of a request | |
222 | _reqexithandlers = [] |
|
229 | _reqexithandlers: List = [] | |
223 |
|
230 | |||
224 |
|
231 | |||
225 | class ui: |
|
232 | class ui: | |
226 | def __init__(self, src=None): |
|
233 | def __init__(self, src: Optional["ui"] = None) -> None: | |
227 | """Create a fresh new ui object if no src given |
|
234 | """Create a fresh new ui object if no src given | |
228 |
|
235 | |||
229 | Use uimod.ui.load() to create a ui which knows global and user configs. |
|
236 | Use uimod.ui.load() to create a ui which knows global and user configs. | |
@@ -318,13 +325,13 b' class ui:' | |||||
318 | if k in self.environ: |
|
325 | if k in self.environ: | |
319 | self._exportableenviron[k] = self.environ[k] |
|
326 | self._exportableenviron[k] = self.environ[k] | |
320 |
|
327 | |||
321 | def _new_source(self): |
|
328 | def _new_source(self) -> None: | |
322 | self._ocfg.new_source() |
|
329 | self._ocfg.new_source() | |
323 | self._tcfg.new_source() |
|
330 | self._tcfg.new_source() | |
324 | self._ucfg.new_source() |
|
331 | self._ucfg.new_source() | |
325 |
|
332 | |||
326 | @classmethod |
|
333 | @classmethod | |
327 | def load(cls): |
|
334 | def load(cls: Type[_Tui]) -> _Tui: | |
328 | """Create a ui and load global and user configs""" |
|
335 | """Create a ui and load global and user configs""" | |
329 | u = cls() |
|
336 | u = cls() | |
330 | # we always trust global config files and environment variables |
|
337 | # we always trust global config files and environment variables | |
@@ -350,7 +357,7 b' class ui:' | |||||
350 | u._new_source() # anything after that is a different level |
|
357 | u._new_source() # anything after that is a different level | |
351 | return u |
|
358 | return u | |
352 |
|
359 | |||
353 | def _maybetweakdefaults(self): |
|
360 | def _maybetweakdefaults(self) -> None: | |
354 | if not self.configbool(b'ui', b'tweakdefaults'): |
|
361 | if not self.configbool(b'ui', b'tweakdefaults'): | |
355 | return |
|
362 | return | |
356 | if self._tweaked or self.plain(b'tweakdefaults'): |
|
363 | if self._tweaked or self.plain(b'tweakdefaults'): | |
@@ -370,17 +377,17 b' class ui:' | |||||
370 | if not self.hasconfig(section, name): |
|
377 | if not self.hasconfig(section, name): | |
371 | self.setconfig(section, name, value, b"<tweakdefaults>") |
|
378 | self.setconfig(section, name, value, b"<tweakdefaults>") | |
372 |
|
379 | |||
373 | def copy(self): |
|
380 | def copy(self: _Tui) -> _Tui: | |
374 | return self.__class__(self) |
|
381 | return self.__class__(self) | |
375 |
|
382 | |||
376 | def resetstate(self): |
|
383 | def resetstate(self) -> None: | |
377 | """Clear internal state that shouldn't persist across commands""" |
|
384 | """Clear internal state that shouldn't persist across commands""" | |
378 | if self._progbar: |
|
385 | if self._progbar: | |
379 | self._progbar.resetstate() # reset last-print time of progress bar |
|
386 | self._progbar.resetstate() # reset last-print time of progress bar | |
380 | self.httppasswordmgrdb = httppasswordmgrdbproxy() |
|
387 | self.httppasswordmgrdb = httppasswordmgrdbproxy() | |
381 |
|
388 | |||
382 | @contextlib.contextmanager |
|
389 | @contextlib.contextmanager | |
383 | def timeblockedsection(self, key): |
|
390 | def timeblockedsection(self, key: bytes): | |
384 | # this is open-coded below - search for timeblockedsection to find them |
|
391 | # this is open-coded below - search for timeblockedsection to find them | |
385 | starttime = util.timer() |
|
392 | starttime = util.timer() | |
386 | try: |
|
393 | try: | |
@@ -425,10 +432,10 b' class ui:' | |||||
425 | finally: |
|
432 | finally: | |
426 | self._uninterruptible = False |
|
433 | self._uninterruptible = False | |
427 |
|
434 | |||
428 | def formatter(self, topic, opts): |
|
435 | def formatter(self, topic: bytes, opts): | |
429 | return formatter.formatter(self, self, topic, opts) |
|
436 | return formatter.formatter(self, self, topic, opts) | |
430 |
|
437 | |||
431 | def _trusted(self, fp, f): |
|
438 | def _trusted(self, fp, f: bytes) -> bool: | |
432 | st = util.fstat(fp) |
|
439 | st = util.fstat(fp) | |
433 | if util.isowner(st): |
|
440 | if util.isowner(st): | |
434 | return True |
|
441 | return True | |
@@ -454,7 +461,7 b' class ui:' | |||||
454 |
|
461 | |||
455 | def read_resource_config( |
|
462 | def read_resource_config( | |
456 | self, name, root=None, trust=False, sections=None, remap=None |
|
463 | self, name, root=None, trust=False, sections=None, remap=None | |
457 | ): |
|
464 | ) -> None: | |
458 | try: |
|
465 | try: | |
459 | fp = resourceutil.open_resource(name[0], name[1]) |
|
466 | fp = resourceutil.open_resource(name[0], name[1]) | |
460 | except IOError: |
|
467 | except IOError: | |
@@ -468,7 +475,7 b' class ui:' | |||||
468 |
|
475 | |||
469 | def readconfig( |
|
476 | def readconfig( | |
470 | self, filename, root=None, trust=False, sections=None, remap=None |
|
477 | self, filename, root=None, trust=False, sections=None, remap=None | |
471 | ): |
|
478 | ) -> None: | |
472 | try: |
|
479 | try: | |
473 | fp = open(filename, 'rb') |
|
480 | fp = open(filename, 'rb') | |
474 | except IOError: |
|
481 | except IOError: | |
@@ -480,7 +487,7 b' class ui:' | |||||
480 |
|
487 | |||
481 | def _readconfig( |
|
488 | def _readconfig( | |
482 | self, filename, fp, root=None, trust=False, sections=None, remap=None |
|
489 | self, filename, fp, root=None, trust=False, sections=None, remap=None | |
483 | ): |
|
490 | ) -> None: | |
484 | with fp: |
|
491 | with fp: | |
485 | cfg = config.config() |
|
492 | cfg = config.config() | |
486 | trusted = sections or trust or self._trusted(fp, filename) |
|
493 | trusted = sections or trust or self._trusted(fp, filename) | |
@@ -496,7 +503,9 b' class ui:' | |||||
496 |
|
503 | |||
497 | self._applyconfig(cfg, trusted, root) |
|
504 | self._applyconfig(cfg, trusted, root) | |
498 |
|
505 | |||
499 | def applyconfig(self, configitems, source=b"", root=None): |
|
506 | def applyconfig( | |
|
507 | self, configitems: _ConfigItems, source=b"", root=None | |||
|
508 | ) -> None: | |||
500 | """Add configitems from a non-file source. Unlike with ``setconfig()``, |
|
509 | """Add configitems from a non-file source. Unlike with ``setconfig()``, | |
501 | they can be overridden by subsequent config file reads. The items are |
|
510 | they can be overridden by subsequent config file reads. The items are | |
502 | in the same format as ``configoverride()``, namely a dict of the |
|
511 | in the same format as ``configoverride()``, namely a dict of the | |
@@ -512,7 +521,7 b' class ui:' | |||||
512 |
|
521 | |||
513 | self._applyconfig(cfg, True, root) |
|
522 | self._applyconfig(cfg, True, root) | |
514 |
|
523 | |||
515 | def _applyconfig(self, cfg, trusted, root): |
|
524 | def _applyconfig(self, cfg, trusted, root) -> None: | |
516 | if self.plain(): |
|
525 | if self.plain(): | |
517 | for k in ( |
|
526 | for k in ( | |
518 | b'debug', |
|
527 | b'debug', | |
@@ -555,7 +564,7 b' class ui:' | |||||
555 | root = os.path.expanduser(b'~') |
|
564 | root = os.path.expanduser(b'~') | |
556 | self.fixconfig(root=root) |
|
565 | self.fixconfig(root=root) | |
557 |
|
566 | |||
558 | def fixconfig(self, root=None, section=None): |
|
567 | def fixconfig(self, root=None, section=None) -> None: | |
559 | if section in (None, b'paths'): |
|
568 | if section in (None, b'paths'): | |
560 | # expand vars and ~ |
|
569 | # expand vars and ~ | |
561 | # translate paths relative to root (or home) into absolute paths |
|
570 | # translate paths relative to root (or home) into absolute paths | |
@@ -618,12 +627,12 b' class ui:' | |||||
618 | self._ucfg.backup(section, item), |
|
627 | self._ucfg.backup(section, item), | |
619 | ) |
|
628 | ) | |
620 |
|
629 | |||
621 | def restoreconfig(self, data): |
|
630 | def restoreconfig(self, data) -> None: | |
622 | self._ocfg.restore(data[0]) |
|
631 | self._ocfg.restore(data[0]) | |
623 | self._tcfg.restore(data[1]) |
|
632 | self._tcfg.restore(data[1]) | |
624 | self._ucfg.restore(data[2]) |
|
633 | self._ucfg.restore(data[2]) | |
625 |
|
634 | |||
626 | def setconfig(self, section, name, value, source=b''): |
|
635 | def setconfig(self, section, name, value, source=b'') -> None: | |
627 | for cfg in (self._ocfg, self._tcfg, self._ucfg): |
|
636 | for cfg in (self._ocfg, self._tcfg, self._ucfg): | |
628 | cfg.set(section, name, value, source) |
|
637 | cfg.set(section, name, value, source) | |
629 | self.fixconfig(section=section) |
|
638 | self.fixconfig(section=section) | |
@@ -1009,7 +1018,7 b' class ui:' | |||||
1009 | for name, value in self.configitems(section, untrusted): |
|
1018 | for name, value in self.configitems(section, untrusted): | |
1010 | yield section, name, value |
|
1019 | yield section, name, value | |
1011 |
|
1020 | |||
1012 | def plain(self, feature=None): |
|
1021 | def plain(self, feature: Optional[bytes] = None) -> bool: | |
1013 | """is plain mode active? |
|
1022 | """is plain mode active? | |
1014 |
|
1023 | |||
1015 | Plain mode means that all configuration variables which affect |
|
1024 | Plain mode means that all configuration variables which affect | |
@@ -1083,7 +1092,7 b' class ui:' | |||||
1083 | ) |
|
1092 | ) | |
1084 | return user |
|
1093 | return user | |
1085 |
|
1094 | |||
1086 | def shortuser(self, user): |
|
1095 | def shortuser(self, user: bytes) -> bytes: | |
1087 | """Return a short representation of a user name or email address.""" |
|
1096 | """Return a short representation of a user name or email address.""" | |
1088 | if not self.verbose: |
|
1097 | if not self.verbose: | |
1089 | user = stringutil.shortuser(user) |
|
1098 | user = stringutil.shortuser(user) | |
@@ -1161,14 +1170,18 b' class ui:' | |||||
1161 | self._fmsgout, self._fmsgerr = _selectmsgdests(self) |
|
1170 | self._fmsgout, self._fmsgerr = _selectmsgdests(self) | |
1162 |
|
1171 | |||
1163 | @contextlib.contextmanager |
|
1172 | @contextlib.contextmanager | |
1164 | def silent(self, error=False, subproc=False, labeled=False): |
|
1173 | def silent( | |
|
1174 | self, error: bool = False, subproc: bool = False, labeled: bool = False | |||
|
1175 | ): | |||
1165 | self.pushbuffer(error=error, subproc=subproc, labeled=labeled) |
|
1176 | self.pushbuffer(error=error, subproc=subproc, labeled=labeled) | |
1166 | try: |
|
1177 | try: | |
1167 | yield |
|
1178 | yield | |
1168 | finally: |
|
1179 | finally: | |
1169 | self.popbuffer() |
|
1180 | self.popbuffer() | |
1170 |
|
1181 | |||
1171 | def pushbuffer(self, error=False, subproc=False, labeled=False): |
|
1182 | def pushbuffer( | |
|
1183 | self, error: bool = False, subproc: bool = False, labeled: bool = False | |||
|
1184 | ) -> None: | |||
1172 | """install a buffer to capture standard output of the ui object |
|
1185 | """install a buffer to capture standard output of the ui object | |
1173 |
|
1186 | |||
1174 | If error is True, the error output will be captured too. |
|
1187 | If error is True, the error output will be captured too. | |
@@ -1187,7 +1200,7 b' class ui:' | |||||
1187 | self._bufferstates.append((error, subproc, labeled)) |
|
1200 | self._bufferstates.append((error, subproc, labeled)) | |
1188 | self._bufferapplylabels = labeled |
|
1201 | self._bufferapplylabels = labeled | |
1189 |
|
1202 | |||
1190 | def popbuffer(self): |
|
1203 | def popbuffer(self) -> bytes: | |
1191 | '''pop the last buffer and return the buffered output''' |
|
1204 | '''pop the last buffer and return the buffered output''' | |
1192 | self._bufferstates.pop() |
|
1205 | self._bufferstates.pop() | |
1193 | if self._bufferstates: |
|
1206 | if self._bufferstates: | |
@@ -1197,20 +1210,20 b' class ui:' | |||||
1197 |
|
1210 | |||
1198 | return b"".join(self._buffers.pop()) |
|
1211 | return b"".join(self._buffers.pop()) | |
1199 |
|
1212 | |||
1200 | def _isbuffered(self, dest): |
|
1213 | def _isbuffered(self, dest) -> bool: | |
1201 | if dest is self._fout: |
|
1214 | if dest is self._fout: | |
1202 | return bool(self._buffers) |
|
1215 | return bool(self._buffers) | |
1203 | if dest is self._ferr: |
|
1216 | if dest is self._ferr: | |
1204 | return bool(self._bufferstates and self._bufferstates[-1][0]) |
|
1217 | return bool(self._bufferstates and self._bufferstates[-1][0]) | |
1205 | return False |
|
1218 | return False | |
1206 |
|
1219 | |||
1207 | def canwritewithoutlabels(self): |
|
1220 | def canwritewithoutlabels(self) -> bool: | |
1208 | '''check if write skips the label''' |
|
1221 | '''check if write skips the label''' | |
1209 | if self._buffers and not self._bufferapplylabels: |
|
1222 | if self._buffers and not self._bufferapplylabels: | |
1210 | return True |
|
1223 | return True | |
1211 | return self._colormode is None |
|
1224 | return self._colormode is None | |
1212 |
|
1225 | |||
1213 | def canbatchlabeledwrites(self): |
|
1226 | def canbatchlabeledwrites(self) -> bool: | |
1214 | '''check if write calls with labels are batchable''' |
|
1227 | '''check if write calls with labels are batchable''' | |
1215 | # Windows color printing is special, see ``write``. |
|
1228 | # Windows color printing is special, see ``write``. | |
1216 | return self._colormode != b'win32' |
|
1229 | return self._colormode != b'win32' | |
@@ -1369,7 +1382,7 b' class ui:' | |||||
1369 | util.timer() - starttime |
|
1382 | util.timer() - starttime | |
1370 | ) * 1000 |
|
1383 | ) * 1000 | |
1371 |
|
1384 | |||
1372 | def _isatty(self, fh): |
|
1385 | def _isatty(self, fh) -> bool: | |
1373 | if self.configbool(b'ui', b'nontty'): |
|
1386 | if self.configbool(b'ui', b'nontty'): | |
1374 | return False |
|
1387 | return False | |
1375 | return procutil.isatty(fh) |
|
1388 | return procutil.isatty(fh) | |
@@ -1407,10 +1420,10 b' class ui:' | |||||
1407 | finally: |
|
1420 | finally: | |
1408 | self.restorefinout(fin, fout) |
|
1421 | self.restorefinout(fin, fout) | |
1409 |
|
1422 | |||
1410 | def disablepager(self): |
|
1423 | def disablepager(self) -> None: | |
1411 | self._disablepager = True |
|
1424 | self._disablepager = True | |
1412 |
|
1425 | |||
1413 | def pager(self, command): |
|
1426 | def pager(self, command: bytes) -> None: | |
1414 | """Start a pager for subsequent command output. |
|
1427 | """Start a pager for subsequent command output. | |
1415 |
|
1428 | |||
1416 | Commands which produce a long stream of output should call |
|
1429 | Commands which produce a long stream of output should call | |
@@ -1491,7 +1504,7 b' class ui:' | |||||
1491 | # warning about a missing pager command. |
|
1504 | # warning about a missing pager command. | |
1492 | self.disablepager() |
|
1505 | self.disablepager() | |
1493 |
|
1506 | |||
1494 | def _runpager(self, command, env=None): |
|
1507 | def _runpager(self, command: bytes, env=None) -> bool: | |
1495 | """Actually start the pager and set up file descriptors. |
|
1508 | """Actually start the pager and set up file descriptors. | |
1496 |
|
1509 | |||
1497 | This is separate in part so that extensions (like chg) can |
|
1510 | This is separate in part so that extensions (like chg) can | |
@@ -1571,7 +1584,7 b' class ui:' | |||||
1571 | self._exithandlers.append((func, args, kwargs)) |
|
1584 | self._exithandlers.append((func, args, kwargs)) | |
1572 | return func |
|
1585 | return func | |
1573 |
|
1586 | |||
1574 | def interface(self, feature): |
|
1587 | def interface(self, feature: bytes) -> bytes: | |
1575 | """what interface to use for interactive console features? |
|
1588 | """what interface to use for interactive console features? | |
1576 |
|
1589 | |||
1577 | The interface is controlled by the value of `ui.interface` but also by |
|
1590 | The interface is controlled by the value of `ui.interface` but also by | |
@@ -1626,12 +1639,12 b' class ui:' | |||||
1626 | defaultinterface = b"text" |
|
1639 | defaultinterface = b"text" | |
1627 | i = self.config(b"ui", b"interface") |
|
1640 | i = self.config(b"ui", b"interface") | |
1628 | if i in alldefaults: |
|
1641 | if i in alldefaults: | |
1629 | defaultinterface = i |
|
1642 | defaultinterface = cast(bytes, i) # cast to help pytype | |
1630 |
|
1643 | |||
1631 | choseninterface = defaultinterface |
|
1644 | choseninterface: bytes = defaultinterface | |
1632 | f = self.config(b"ui", b"interface.%s" % feature) |
|
1645 | f = self.config(b"ui", b"interface.%s" % feature) | |
1633 | if f in availableinterfaces: |
|
1646 | if f in availableinterfaces: | |
1634 | choseninterface = f |
|
1647 | choseninterface = cast(bytes, f) # cast to help pytype | |
1635 |
|
1648 | |||
1636 | if i is not None and defaultinterface != i: |
|
1649 | if i is not None and defaultinterface != i: | |
1637 | if f is not None: |
|
1650 | if f is not None: | |
@@ -1671,7 +1684,7 b' class ui:' | |||||
1671 |
|
1684 | |||
1672 | return i |
|
1685 | return i | |
1673 |
|
1686 | |||
1674 | def termwidth(self): |
|
1687 | def termwidth(self) -> int: | |
1675 | """how wide is the terminal in columns?""" |
|
1688 | """how wide is the terminal in columns?""" | |
1676 | if b'COLUMNS' in encoding.environ: |
|
1689 | if b'COLUMNS' in encoding.environ: | |
1677 | try: |
|
1690 | try: | |
@@ -1918,14 +1931,14 b' class ui:' | |||||
1918 |
|
1931 | |||
1919 | def edit( |
|
1932 | def edit( | |
1920 | self, |
|
1933 | self, | |
1921 | text, |
|
1934 | text: bytes, | |
1922 | user, |
|
1935 | user: bytes, | |
1923 | extra=None, |
|
1936 | extra: Optional[Dict[bytes, Any]] = None, # TODO: value type of bytes? | |
1924 | editform=None, |
|
1937 | editform=None, | |
1925 | pending=None, |
|
1938 | pending=None, | |
1926 | repopath=None, |
|
1939 | repopath: Optional[bytes] = None, | |
1927 | action=None, |
|
1940 | action: Optional[bytes] = None, | |
1928 | ): |
|
1941 | ) -> bytes: | |
1929 | if action is None: |
|
1942 | if action is None: | |
1930 | self.develwarn( |
|
1943 | self.develwarn( | |
1931 | b'action is None but will soon be a required ' |
|
1944 | b'action is None but will soon be a required ' | |
@@ -1994,13 +2007,13 b' class ui:' | |||||
1994 |
|
2007 | |||
1995 | def system( |
|
2008 | def system( | |
1996 | self, |
|
2009 | self, | |
1997 | cmd, |
|
2010 | cmd: bytes, | |
1998 | environ=None, |
|
2011 | environ=None, | |
1999 | cwd=None, |
|
2012 | cwd: Optional[bytes] = None, | |
2000 | onerr=None, |
|
2013 | onerr: Optional[Callable[[bytes], Exception]] = None, | |
2001 | errprefix=None, |
|
2014 | errprefix: Optional[bytes] = None, | |
2002 | blockedtag=None, |
|
2015 | blockedtag: Optional[bytes] = None, | |
2003 | ): |
|
2016 | ) -> int: | |
2004 | """execute shell command with appropriate output stream. command |
|
2017 | """execute shell command with appropriate output stream. command | |
2005 | output will be redirected if fout is not stdout. |
|
2018 | output will be redirected if fout is not stdout. | |
2006 |
|
2019 | |||
@@ -2027,12 +2040,12 b' class ui:' | |||||
2027 | raise onerr(errmsg) |
|
2040 | raise onerr(errmsg) | |
2028 | return rc |
|
2041 | return rc | |
2029 |
|
2042 | |||
2030 | def _runsystem(self, cmd, environ, cwd, out): |
|
2043 | def _runsystem(self, cmd: bytes, environ, cwd: Optional[bytes], out) -> int: | |
2031 | """actually execute the given shell command (can be overridden by |
|
2044 | """actually execute the given shell command (can be overridden by | |
2032 | extensions like chg)""" |
|
2045 | extensions like chg)""" | |
2033 | return procutil.system(cmd, environ=environ, cwd=cwd, out=out) |
|
2046 | return procutil.system(cmd, environ=environ, cwd=cwd, out=out) | |
2034 |
|
2047 | |||
2035 | def traceback(self, exc=None, force=False): |
|
2048 | def traceback(self, exc=None, force: bool = False): | |
2036 | """print exception traceback if traceback printing enabled or forced. |
|
2049 | """print exception traceback if traceback printing enabled or forced. | |
2037 | only to call in exception handler. returns true if traceback |
|
2050 | only to call in exception handler. returns true if traceback | |
2038 | printed.""" |
|
2051 | printed.""" | |
@@ -2130,7 +2143,7 b' class ui:' | |||||
2130 | """Returns a logger of the given name; or None if not registered""" |
|
2143 | """Returns a logger of the given name; or None if not registered""" | |
2131 | return self._loggers.get(name) |
|
2144 | return self._loggers.get(name) | |
2132 |
|
2145 | |||
2133 | def setlogger(self, name, logger): |
|
2146 | def setlogger(self, name, logger) -> None: | |
2134 | """Install logger which can be identified later by the given name |
|
2147 | """Install logger which can be identified later by the given name | |
2135 |
|
2148 | |||
2136 | More than one loggers can be registered. Use extension or module |
|
2149 | More than one loggers can be registered. Use extension or module | |
@@ -2138,7 +2151,7 b' class ui:' | |||||
2138 | """ |
|
2151 | """ | |
2139 | self._loggers[name] = logger |
|
2152 | self._loggers[name] = logger | |
2140 |
|
2153 | |||
2141 | def log(self, event, msgfmt, *msgargs, **opts): |
|
2154 | def log(self, event, msgfmt, *msgargs, **opts) -> None: | |
2142 | """hook for logging facility extensions |
|
2155 | """hook for logging facility extensions | |
2143 |
|
2156 | |||
2144 | event should be a readily-identifiable subsystem, which will |
|
2157 | event should be a readily-identifiable subsystem, which will | |
@@ -2239,7 +2252,7 b' class ui:' | |||||
2239 | return self._exportableenviron |
|
2252 | return self._exportableenviron | |
2240 |
|
2253 | |||
2241 | @contextlib.contextmanager |
|
2254 | @contextlib.contextmanager | |
2242 | def configoverride(self, overrides, source=b""): |
|
2255 | def configoverride(self, overrides: _ConfigItems, source: bytes = b""): | |
2243 | """Context manager for temporary config overrides |
|
2256 | """Context manager for temporary config overrides | |
2244 | `overrides` must be a dict of the following structure: |
|
2257 | `overrides` must be a dict of the following structure: | |
2245 | {(section, name) : value}""" |
|
2258 | {(section, name) : value}""" | |
@@ -2257,7 +2270,7 b' class ui:' | |||||
2257 | if (b'ui', b'quiet') in overrides: |
|
2270 | if (b'ui', b'quiet') in overrides: | |
2258 | self.fixconfig(section=b'ui') |
|
2271 | self.fixconfig(section=b'ui') | |
2259 |
|
2272 | |||
2260 | def estimatememory(self): |
|
2273 | def estimatememory(self) -> Optional[int]: | |
2261 | """Provide an estimate for the available system memory in Bytes. |
|
2274 | """Provide an estimate for the available system memory in Bytes. | |
2262 |
|
2275 | |||
2263 | This can be overriden via ui.available-memory. It returns None, if |
|
2276 | This can be overriden via ui.available-memory. It returns None, if | |
@@ -2292,7 +2305,7 b' def haveprogbar() -> bool:' | |||||
2292 | return _progresssingleton is not None |
|
2305 | return _progresssingleton is not None | |
2293 |
|
2306 | |||
2294 |
|
2307 | |||
2295 | def _selectmsgdests(ui): |
|
2308 | def _selectmsgdests(ui: ui): | |
2296 | name = ui.config(b'ui', b'message-output') |
|
2309 | name = ui.config(b'ui', b'message-output') | |
2297 | if name == b'channel': |
|
2310 | if name == b'channel': | |
2298 | if ui.fmsg: |
|
2311 | if ui.fmsg: |
General Comments 0
You need to be logged in to leave comments.
Login now