Thu, 17 Mar 2022 11:00:05 +0100 tests: fix glob pattern for dynamic timer alignment
pacien <pacien.trangirard@pacien.net> [Thu, 17 Mar 2022 11:00:05 +0100] rev 49055
tests: fix glob pattern for dynamic timer alignment The number of space characters varies depending on the number of digits of the timer, making some tests fail on slow machines in an unintended way: ```diff --- /build/mercurial-6.1/tests/test-merge-halt.t +++ /build/mercurial-6.1/tests/test-merge-halt.t.err @@ -210,6 +210,6 @@ merge halted after failed merge (see hg resolve) [240] $ hg shelve --list - default (* ago) changes to: foo (glob) + default (11s ago) changes to: foo $ hg unshelve --abort unshelve of 'default' aborted ERROR: test-merge-halt.t output changed ``` Differential Revision: https://phab.mercurial-scm.org/D12381
Tue, 15 Mar 2022 09:26:26 +0100 branching: merge stable into default
Raphaël Gomès <rgomes@octobus.net> [Tue, 15 Mar 2022 09:26:26 +0100] rev 49054
branching: merge stable into default
Mon, 14 Mar 2022 12:24:34 -0700 tests: fix formatting issue in run-tests.py after c194e93d1ebc
Kyle Lippincott <spectral@google.com> [Mon, 14 Mar 2022 12:24:34 -0700] rev 49053
tests: fix formatting issue in run-tests.py after c194e93d1ebc Differential Revision: https://phab.mercurial-scm.org/D12375
Wed, 09 Mar 2022 15:41:39 -0800 import-checker: allow symbol imports from typing module
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 09 Mar 2022 15:41:39 -0800] rev 49052
import-checker: allow symbol imports from typing module As we add typing annotations, we'll want to use a lot of symbols from the `typing` module. Typing `typing` all the time will be annoying. Let's allow symbol imports from this module. While I was here, I changed some comments from "whitelist" to "allow list" as the former is non-inclusive terminology. Differential Revision: https://phab.mercurial-scm.org/D12365
Tue, 08 Mar 2022 19:11:03 -0800 pycompat: remove json.loads polyfill for Python 3.5
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 08 Mar 2022 19:11:03 -0800] rev 49051
pycompat: remove json.loads polyfill for Python 3.5 We no longer support Python 3.5 so this can be deleted. Differential Revision: https://phab.mercurial-scm.org/D12364
Tue, 08 Mar 2022 19:10:19 -0800 pycompat: remove check for Python >= 3.6
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 08 Mar 2022 19:10:19 -0800] rev 49050
pycompat: remove check for Python >= 3.6 We dropped support for Python 3.5 so this is always true. Differential Revision: https://phab.mercurial-scm.org/D12363
Tue, 08 Mar 2022 19:09:35 -0800 hgdemandimport: delete check for Python 3.5
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 08 Mar 2022 19:09:35 -0800] rev 49049
hgdemandimport: delete check for Python 3.5 We dropped support for Python 3.5. So we no longer need to do this. Differential Revision: https://phab.mercurial-scm.org/D12362
Tue, 08 Mar 2022 19:08:35 -0800 hg: always import hgdemandimport
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 08 Mar 2022 19:08:35 -0800] rev 49048
hg: always import hgdemandimport The deleted if condition is always true now that we dropped Python 2 and 3.5. Differential Revision: https://phab.mercurial-scm.org/D12361
Wed, 09 Mar 2022 21:26:58 -0800 tests: support another error case when detecting ipv4/ipv6 support
Kyle Lippincott <spectral@google.com> [Wed, 09 Mar 2022 21:26:58 -0800] rev 49047
tests: support another error case when detecting ipv4/ipv6 support I encountered this on Linux in a VM environment with a rather strange networking setup (both on the host and in the VM). Differential Revision: https://phab.mercurial-scm.org/D12371
Wed, 09 Mar 2022 16:44:48 +0100 debugdiscovery: fix a typo in the help
Pierre-Yves David <pierre-yves.david@octobus.net> [Wed, 09 Mar 2022 16:44:48 +0100] rev 49046
debugdiscovery: fix a typo in the help Differential Revision: https://phab.mercurial-scm.org/D12372
Wed, 09 Mar 2022 11:28:51 +0100 rust-hg-cypython: upgrade dependencies
Raphaël Gomès <rgomes@octobus.net> [Wed, 09 Mar 2022 11:28:51 +0100] rev 49045
rust-hg-cypython: upgrade dependencies This upgrades all dependencies to their latest version. This is routinely done to keep-up. Differential Revision: https://phab.mercurial-scm.org/D12359
Wed, 09 Mar 2022 11:22:22 +0100 rust-hg-core: upgrade dependencies
Raphaël Gomès <rgomes@octobus.net> [Wed, 09 Mar 2022 11:22:22 +0100] rev 49044
rust-hg-core: upgrade dependencies This upgrades all dependencies to their latest version, except `clap` and `zstd` whose latest versions do not support our minimum supported Rust version 1.48.0. Same as for `rhg`, it contains security fix for `regex` which does not affect us too much, but doesn't hurt, and the rest of the upgrades are there simply to keep up. Differential Revision: https://phab.mercurial-scm.org/D12358
Wed, 09 Mar 2022 11:17:09 +0100 rhg: upgrade dependencies
Raphaël Gomès <rgomes@octobus.net> [Wed, 09 Mar 2022 11:17:09 +0100] rev 49043
rhg: upgrade dependencies This upgrades all dependencies to their latest version, except `clap`, which is upgraded to the last 2.x series version, since 3.x does not support our minimum supported Rust version of 1.48.0. This contains a security fix for `regex` which does not affect us too much, but doesn't hurt, and the rest of the upgrades are there simply to keep up. Differential Revision: https://phab.mercurial-scm.org/D12357
Fri, 04 Mar 2022 10:28:46 +0900 chgserver: remove Python 2 file descriptor logic
Yuya Nishihara <yuya@tcha.org> [Fri, 04 Mar 2022 10:28:46 +0900] rev 49042
chgserver: remove Python 2 file descriptor logic Follows up 0bb28b7736bc "chgserver: remove Python 2 support code." On Python 2, we had to close newfp prior to restoring the original file description since "delete newfp" would otherwise close the file descriptor shared with the long-lived fp: in attachio(): newfp = os.fdopen(fp.fileno(), mode, bufsize) in _restoreio(): newfp.close() # temporarily close newfp.fileno() (= fp.fileno()) os.dup2(fd, fp.fileno()) # reopen fp.fileno() with original fd On the other hand, we shouldn't call newfp.close() on Python 3 since any function calls are proxied to the underlying file object by procutil.LineBufferedWrapper.
Tue, 08 Feb 2022 15:51:52 +0100 dirstate-tree: optimize HashMap lookups with raw_entry_mut
Simon Sapin <simon.sapin@octobus.net> [Tue, 08 Feb 2022 15:51:52 +0100] rev 49041
dirstate-tree: optimize HashMap lookups with raw_entry_mut This switches to using `HashMap` from the hashbrown crate, in order to use its `raw_entry_mut` method. The standard library’s `HashMap` is also based on this same crate, but `raw_entry_mut` is not yet stable there: https://github.com/rust-lang/rust/issues/56167 Using version 0.9 because 0.10 is yanked and 0.11 requires Rust 1.49 This replaces in `DirstateMap::get_or_insert_node` a call to `HashMap<K, V>::entry` with `K = WithBasename<Cow<'on_disk, HgPath>>`. `entry` takes and consumes an "owned" `key: K` parameter, in case a new entry ends up inserted. This key is converted by `to_cow` from a value that borrows the `'path` lifetime. When this function is called by `Dirstate::new_v1`, `'path` is in fact the same as `'on_disk` so `to_cow` can return an owned key that contains `Cow::Borrowed`. For other callers, `to_cow` needs to create a `Cow::Owned` and thus make a costly heap memory allocation. This is wasteful if this key was already present in the map. Even when inserting a new node this is typically the case for its ancestor nodes (assuming most directories have numerous descendants). Differential Revision: https://phab.mercurial-scm.org/D12317
Fri, 04 Mar 2022 13:33:55 +0100 heptapod-ci: remove useless mentions of Python 3
Raphaël Gomès <rgomes@octobus.net> [Fri, 04 Mar 2022 13:33:55 +0100] rev 49040
heptapod-ci: remove useless mentions of Python 3 Now that we don't have Python 2 jobs, we can go with shorter names. Differential Revision: https://phab.mercurial-scm.org/D12354
Fri, 04 Mar 2022 13:01:13 -0800 revlog: remove unused `rank` variable from D12209
Martin von Zweigbergk <martinvonz@google.com> [Fri, 04 Mar 2022 13:01:13 -0800] rev 49039
revlog: remove unused `rank` variable from D12209 Differential Revision: https://phab.mercurial-scm.org/D12355
Mon, 21 Feb 2022 13:10:22 -0700 demandimport: delete demandimportpy2 module
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 13:10:22 -0700] rev 49038
demandimport: delete demandimportpy2 module We no longer support Python 2. Differential Revision: https://phab.mercurial-scm.org/D12353
Mon, 21 Feb 2022 13:08:28 -0700 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 13:08:28 -0700] rev 49037
py3: use class X: instead of class X(object): The inheritance from object is implied in Python 3. So this should be equivalent. This change was generated via an automated search and replace. So there may have been some accidental changes. Differential Revision: https://phab.mercurial-scm.org/D12352
Mon, 21 Feb 2022 13:03:43 -0700 check-code: remove ban on old-style classes
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 13:03:43 -0700] rev 49036
check-code: remove ban on old-style classes In Python 3, `class foo:` is equivalent to `class foo(object):`. So we can allow the former form now. Differential Revision: https://phab.mercurial-scm.org/D12351
Mon, 21 Feb 2022 12:46:27 -0700 tests: remove Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:46:27 -0700] rev 49035
tests: remove Python 2 support code Differential Revision: https://phab.mercurial-scm.org/D12350
Mon, 21 Feb 2022 12:44:41 -0700 tests: remove Python < 3 check
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:44:41 -0700] rev 49034
tests: remove Python < 3 check We require Python 3 now. Differential Revision: https://phab.mercurial-scm.org/D12349
Tue, 01 Mar 2022 20:53:52 -0800 cborutil: remove Python 2 definition of _elementtointeger()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:53:52 -0800] rev 49033
cborutil: remove Python 2 definition of _elementtointeger() Differential Revision: https://phab.mercurial-scm.org/D12348
Mon, 21 Feb 2022 12:42:48 -0700 py3: stop using util.iterfile()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:42:48 -0700] rev 49032
py3: stop using util.iterfile() The Python 3 implementation is a no-op. So this is equivalent. We still keep util.iterfile() around for backwards API compatibility to help the Python 3 migration. It can be deleted in a future release. Differential Revision: https://phab.mercurial-scm.org/D12347
Thu, 03 Mar 2022 07:56:47 -0800 util: remove iterfile() variant for buggy EINTR handling
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Mar 2022 07:56:47 -0800] rev 49031
util: remove iterfile() variant for buggy EINTR handling The workaround for Python 2 is no longer needed. So we can delete some code. Differential Revision: https://phab.mercurial-scm.org/D12346
Mon, 21 Feb 2022 12:36:57 -0700 statprof: remove superfluous sys.version_info check
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:36:57 -0700] rev 49030
statprof: remove superfluous sys.version_info check Always true since we require Python 3 now. Differential Revision: https://phab.mercurial-scm.org/D12345
Mon, 21 Feb 2022 12:36:04 -0700 policy: remove Python 2.7 compatibility code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:36:04 -0700] rev 49029
policy: remove Python 2.7 compatibility code Differential Revision: https://phab.mercurial-scm.org/D12344
Mon, 21 Feb 2022 12:35:29 -0700 lsprof: remove some Python 2.7 compatibility code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:35:29 -0700] rev 49028
lsprof: remove some Python 2.7 compatibility code Differential Revision: https://phab.mercurial-scm.org/D12343
Mon, 21 Feb 2022 12:34:22 -0700 url: remove Python 2.7 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 12:34:22 -0700] rev 49027
url: remove Python 2.7 support code Differential Revision: https://phab.mercurial-scm.org/D12342
Tue, 01 Mar 2022 20:52:32 -0800 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:52:32 -0800] rev 49026
py3: replace pycompat.itervalues(x) with x.values() pycompat.itervalues(x) just calls x.values(). So this is equivalent. The rewrite was perfomed via an automated search and replace. Differential Revision: https://phab.mercurial-scm.org/D12341
Mon, 21 Feb 2022 11:24:57 -0700 py3: use str instead of pycompat.unicode
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:24:57 -0700] rev 49025
py3: use str instead of pycompat.unicode pycompat.unicode is an alias to str. Differential Revision: https://phab.mercurial-scm.org/D12340
Tue, 08 Mar 2022 10:58:22 +0100 ui: use input() directly
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 08 Mar 2022 10:58:22 +0100] rev 49024
ui: use input() directly pycompat.rawinput() is an alias to input() Differential Revision: https://phab.mercurial-scm.org/D12339
Tue, 01 Mar 2022 20:50:34 -0800 py3: use int instead of pycompat.long
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:50:34 -0800] rev 49023
py3: use int instead of pycompat.long pycompat.long is aliased to int. So this should have no change in functionality. Differential Revision: https://phab.mercurial-scm.org/D12338
Mon, 21 Feb 2022 11:13:37 -0700 verify: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:13:37 -0700] rev 49022
verify: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12336
Mon, 21 Feb 2022 11:13:15 -0700 templatekw: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:13:15 -0700] rev 49021
templatekw: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12335
Mon, 21 Feb 2022 11:12:47 -0700 templatefuncs: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:12:47 -0700] rev 49020
templatefuncs: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12334
Mon, 21 Feb 2022 11:12:26 -0700 revlog: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:12:26 -0700] rev 49019
revlog: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12333
Mon, 21 Feb 2022 11:11:59 -0700 merge: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:11:59 -0700] rev 49018
merge: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12332
Mon, 21 Feb 2022 11:11:27 -0700 manifest: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:11:27 -0700] rev 49017
manifest: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12331
Mon, 21 Feb 2022 11:10:47 -0700 localrepo: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:10:47 -0700] rev 49016
localrepo: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12330
Mon, 21 Feb 2022 11:10:27 -0700 keepalive: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:10:27 -0700] rev 49015
keepalive: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12329
Mon, 21 Feb 2022 11:10:08 -0700 help: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:10:08 -0700] rev 49014
help: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12328
Mon, 21 Feb 2022 11:09:30 -0700 dirstate: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:09:30 -0700] rev 49013
dirstate: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12327
Mon, 21 Feb 2022 11:08:53 -0700 debugcommands: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:08:53 -0700] rev 49012
debugcommands: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12326
Tue, 01 Mar 2022 20:47:37 -0800 config: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:47:37 -0800] rev 49011
config: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12325
Mon, 21 Feb 2022 11:08:04 -0700 commands: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:08:04 -0700] rev 49010
commands: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12324
Mon, 21 Feb 2022 11:07:29 -0700 remotefilelog: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:07:29 -0700] rev 49009
remotefilelog: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12323
Mon, 21 Feb 2022 11:06:46 -0700 lfs: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:06:46 -0700] rev 49008
lfs: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12322
Tue, 01 Mar 2022 20:46:06 -0800 largefiles: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:46:06 -0800] rev 49007
largefiles: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12321
Mon, 21 Feb 2022 11:05:42 -0700 infinitepush: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 11:05:42 -0700] rev 49006
infinitepush: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12320
Tue, 01 Mar 2022 20:44:59 -0800 convert: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:44:59 -0800] rev 49005
convert: remove pycompat.iteritems() Differential Revision: https://phab.mercurial-scm.org/D12319
Thu, 03 Mar 2022 18:28:30 -0800 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Mar 2022 18:28:30 -0800] rev 49004
global: bulk replace simple pycompat.iteritems(x) with x.items() pycompat.iteritems() just calls .items(). This commit applies a regular expression search and replace to convert simple instances of pycompat.iteritems() with .items(). There are still a handful of calls to pycompat.iteritems() remaining. But these all have more complicated expressions that I wasn't comfortable performing an automated replace on. In addition, some simple replacements were withheld because they broke pytype. These will be handled by their own changesets. Differential Revision: https://phab.mercurial-scm.org/D12318
Thu, 03 Mar 2022 17:39:20 -0800 worker: silence type error when calling pickle
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Mar 2022 17:39:20 -0800] rev 49003
worker: silence type error when calling pickle pytype is complaining that the argument to `pickle.load()` is not an `IO`. pytype isn't wrong: `_blockingreader` doesn't implement `io.RawIOBase`, only `read()` and `readline()`. But it appears this is enough for pickle. So we silence the false positive. This fixes a regression introduced by D12304 / cc0e059d2af8: worker: remove Python 2 support code. Differential Revision: https://phab.mercurial-scm.org/D12337
Mon, 21 Feb 2022 10:53:09 -0700 stringutil: remove Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 10:53:09 -0700] rev 49002
stringutil: remove Python 2 support code Differential Revision: https://phab.mercurial-scm.org/D12314
Mon, 21 Feb 2022 10:52:27 -0700 procutil: delete Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 10:52:27 -0700] rev 49001
procutil: delete Python 2 support code This entailed deleting a function for Python 2 support and renaming the Python 3 function to match the exported symbol name. Differential Revision: https://phab.mercurial-scm.org/D12313
Tue, 01 Mar 2022 20:37:09 -0800 revlogutils: unconditionally pass version to random seed
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 01 Mar 2022 20:37:09 -0800] rev 49000
revlogutils: unconditionally pass version to random seed Differential Revision: https://phab.mercurial-scm.org/D12312
Mon, 21 Feb 2022 10:48:45 -0700 revlogutils: remove Python 2 variant for iter_seed
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 10:48:45 -0700] rev 48999
revlogutils: remove Python 2 variant for iter_seed Differential Revision: https://phab.mercurial-scm.org/D12311
Mon, 21 Feb 2022 10:47:31 -0700 charencode: remove Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 10:47:31 -0700] rev 48998
charencode: remove Python 2 support code Differential Revision: https://phab.mercurial-scm.org/D12310
Mon, 21 Feb 2022 10:47:08 -0700 hgweb: remove Python 2 support code
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 21 Feb 2022 10:47:08 -0700] rev 48997
hgweb: remove Python 2 support code Differential Revision: https://phab.mercurial-scm.org/D12309
Thu, 03 Mar 2022 08:06:37 -0800 hgweb: remove Python 3 conditional
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Mar 2022 08:06:37 -0800] rev 48996
hgweb: remove Python 3 conditional We probably have a better tobytes() implementation somewhere in pycompat. But I don't want to bloat scope of this commit. Differential Revision: https://phab.mercurial-scm.org/D12308
(0) -30000 -10000 -3000 -1000 -300 -100 -60 +60 +100 +300 +1000 tip