mercurial/node.py
author Matt Harbison <matt_harbison@yahoo.com>
Sat, 28 Sep 2024 19:12:18 -0400
changeset 51929 f2832de2a46c
parent 51859 f4733654f144
permissions -rw-r--r--
interfaces: introduce and use a protocol class for the `bdiff` module This is allowed by PEP 544[1], and we basically follow the example there. The class here is copied from `mercurial.pure.bdiff`, and the implementation removed. There are several modules that have a few different implementations, and the implementation chosen is controlled by `HGMODULEPOLICY`. The module is loaded via `mercurial/policy.py`, and has been inferred by pytype as `Any` up to this point. Therefore it and PyCharm were blind to all functions on the module, and their signatures. Also, having multiple instances of the same module allows their signatures to get out of sync. Introducing a protocol class allows the loaded module that is stored in a variable to be given type info, which cascades through the various places it is used. This change alters 11 *.pyi files, for example. In theory, this would also allow us to ensure the various implementations of the same module are kept in alignment- simply import the module in a test module, attempt to pass it to a function that uses the corresponding protocol as an argument, and run pytype on it. In practice, this doesn't work (yet). PyCharm (erroneously) flags imported modules being passed where a protocol class is used[2]. Pytype has problems the other way- it fails to detect when a module that doesn't adhere to the protocol is passed to a protocol argument. The good news is that mypy properly detects this case. The bad news is that mypy spews a bunch of other errors when importing even simple modules, like the various `bdiff` modules. Therefore I'm punting on the tests for now because the type info around a loaded module in PyCharm is a clear win by itself. [1] https://peps.python.org/pep-0544/#modules-as-implementations-of-protocols [2] https://youtrack.jetbrains.com/issue/PY-58679/Support-modules-implementing-protocols
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     1
# node.py - basic nodeid manipulation for mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Rapha?l Gom?s <rgomes@octobus.net>
parents: 46780
diff changeset
     3
# Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     4
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8226
diff changeset
     6
# GNU General Public License version 2 or any later version.
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
     7
51859
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 49248
diff changeset
     8
from __future__ import annotations
25962
738314da6c75 node: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25737
diff changeset
     9
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3578
diff changeset
    10
import binascii
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
    11
26980
18f50b8cbf1e node: add 'nullhex', hex-encoded nullid
Siddharth Agarwal <sid0@fb.com>
parents: 25962
diff changeset
    12
# This ugly style has a noticeable effect in manifest parsing
18f50b8cbf1e node: add 'nullhex', hex-encoded nullid
Siddharth Agarwal <sid0@fb.com>
parents: 25962
diff changeset
    13
hex = binascii.hexlify
49248
63fd0282ad40 node: stop converting binascii.Error to TypeError in bin()
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
    14
bin = binascii.unhexlify
26980
18f50b8cbf1e node: add 'nullhex', hex-encoded nullid
Siddharth Agarwal <sid0@fb.com>
parents: 25962
diff changeset
    15
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 39195
diff changeset
    16
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    17
def short(node):
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    18
    return hex(node[:6])
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    19
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents:
diff changeset
    20
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    21
nullrev = -1
30360
0298a07f64d9 dirstate: change placeholder hash length to 20 bytes
Durham Goode <durham@fb.com>
parents: 28585
diff changeset
    22
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    23
# pseudo identifier for working directory
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    24
# (experimental, so don't add too many dependencies on it)
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 39195
diff changeset
    25
wdirrev = 0x7FFFFFFF
25737
1a5211f2f87f node: define experimental identifiers for working directory
Yuya Nishihara <yuya@tcha.org>
parents: 10263
diff changeset
    26
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 39195
diff changeset
    27
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
    28
class sha1nodeconstants:
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    29
    nodelen = 20
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    30
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    31
    # In hex, this is '0000000000000000000000000000000000000000'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    32
    nullid = b"\0" * nodelen
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    33
    nullhex = hex(nullid)
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    34
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    35
    # Phony node value to stand-in for new files in some uses of
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    36
    # manifests.
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    37
    # In hex, this is '2121212121212121212121212121212121212121'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    38
    newnodeid = b'!!!!!!!!!!!!!!!!!!!!'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    39
    # In hex, this is '3030303030303030303030303030306164646564'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    40
    addednodeid = b'000000000000000added'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    41
    # In hex, this is '3030303030303030303030306d6f646966696564'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    42
    modifiednodeid = b'000000000000modified'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    43
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    44
    wdirfilenodeids = {newnodeid, addednodeid, modifiednodeid}
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    45
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    46
    # pseudo identifier for working directory
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    47
    # (experimental, so don't add too many dependencies on it)
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    48
    # In hex, this is 'ffffffffffffffffffffffffffffffffffffffff'
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    49
    wdirid = b"\xff" * nodelen
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    50
    wdirhex = hex(wdirid)
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    51
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    52
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    53
# legacy starting point for porting modules
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    54
nullid = sha1nodeconstants.nullid
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    55
nullhex = sha1nodeconstants.nullhex
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    56
newnodeid = sha1nodeconstants.newnodeid
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    57
addednodeid = sha1nodeconstants.addednodeid
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    58
modifiednodeid = sha1nodeconstants.modifiednodeid
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    59
wdirfilenodeids = sha1nodeconstants.wdirfilenodeids
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    60
wdirid = sha1nodeconstants.wdirid
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 43077
diff changeset
    61
wdirhex = sha1nodeconstants.wdirhex