Mercurial > hg
view mercurial/dirstateutils/docket.py @ 51723:9367571fea21
cext: correct the argument handling of `b85encode()`
The type stub indicated that this argument is `Optional`, which implies None is
allowed. I don't see in the documentation where that's the case for `i`[1], and
trying it in `hg debugshell` resulted in the method failing with a TypeError. I
guess it was typed as an `int` argument because the `p` format unit wasn't added
until Python 3.3[2].
In any event, 2 clients in core (`pvec` and `obsolete`) call this with no
argument supplied, and `mdiff` calls it with True. So I guess we've avoided the
None arg case, and when no arg is supplied, it defaults to the 0 initialization
of the `pad` variable in C. Since the `p` format unit accepts both `int` and
None, as well as `bool`, I'm not bothering to bump the module version- this code
is more permissive than it was, in addition to being more correct.
Interestingly, when I first imported the `cext` and `pure` methods in the same
manner as the previous commit, it dropped the `Optional` part of the argument
type when generating `util.pyi`. No idea why.
[1] https://docs.python.org/3/c-api/arg.html#numbers
[2] https://docs.python.org/3/c-api/arg.html#other-objects
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sat, 20 Jul 2024 01:55:09 -0400 |
parents | 642e31cb55f0 |
children | f4733654f144 |
line wrap: on
line source
# dirstatedocket.py - docket file for dirstate-v2 # # Copyright Mercurial Contributors # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. import struct from ..revlogutils import docket as docket_mod from . import v2 V2_FORMAT_MARKER = b"dirstate-v2\n" # * 12 bytes: format marker # * 32 bytes: node ID of the working directory's first parent # * 32 bytes: node ID of the working directory's second parent # * {TREE_METADATA_SIZE} bytes: tree metadata, parsed separately # * 4 bytes: big-endian used size of the data file # * 1 byte: length of the data file's UUID # * variable: data file's UUID # # Node IDs are null-padded if shorter than 32 bytes. # A data file shorter than the specified used size is corrupted (truncated) HEADER = struct.Struct( ">{}s32s32s{}sLB".format(len(V2_FORMAT_MARKER), v2.TREE_METADATA_SIZE) ) class DirstateDocket: data_filename_pattern = b'dirstate.%s' def __init__(self, parents, data_size, tree_metadata, uuid): self.parents = parents self.data_size = data_size self.tree_metadata = tree_metadata self.uuid = uuid @classmethod def with_new_uuid(cls, parents, data_size, tree_metadata): return cls(parents, data_size, tree_metadata, docket_mod.make_uid()) @classmethod def parse(cls, data, nodeconstants): if not data: parents = (nodeconstants.nullid, nodeconstants.nullid) return cls(parents, 0, b'', None) marker, p1, p2, meta, data_size, uuid_size = HEADER.unpack_from(data) if marker != V2_FORMAT_MARKER: raise ValueError("expected dirstate-v2 marker") uuid = data[HEADER.size : HEADER.size + uuid_size] p1 = p1[: nodeconstants.nodelen] p2 = p2[: nodeconstants.nodelen] return cls((p1, p2), data_size, meta, uuid) def serialize(self): p1, p2 = self.parents header = HEADER.pack( V2_FORMAT_MARKER, p1, p2, self.tree_metadata, self.data_size, len(self.uuid), ) return header + self.uuid def data_filename(self): return self.data_filename_pattern % self.uuid