1
0
mirror of https://github.com/bitcoin/bips.git synced 2026-06-22 17:37:25 +00:00

BIP352: complete type annotations on bitcoin_utils class methods

Direct follow-up to PR #2154 (which annotated the free-function half
of bip-0352/bitcoin_utils.py) and 2f7117c ("BIP352: fix Any typing").
The four classes in this file — COutPoint, VinInfo, CScriptWitness,
and CTxInWitness — still had unannotated `__init__`, `serialize`,
`deserialize`, and `is_null` methods. mypy could not flow types
through the surrounding reference.py code that constructs and passes
these objects.

Annotate every method on all four classes:

- COutPoint:    __init__ (hash, n), serialize -> bytes, deserialize -> None
- VinInfo:      __init__ (typed Optional defaults for the three
                construct-on-None fields)
- CScriptWitness: __init__ -> None, is_null -> bool, plus an inline
                stack: List[bytes] declaration matching what the
                rest of the file already assumes
- CTxInWitness: __init__ -> None, deserialize -> "CTxInWitness"
                (forward ref since it returns self), is_null -> bool

Adds Optional to the existing typing import (List was already added
by #2154). No behavior changes.

Verified: mypy --ignore-missing-imports ./bip-0352/bitcoin_utils.py
reports "Success: no issues found in 1 source file"; round-trip
smoke tests on COutPoint serialize/deserialize, CScriptWitness
is_null with empty + non-empty stack, CTxInWitness deserialize
returning self, and VinInfo default-construction all match the
pre-change behavior.
This commit is contained in:
omipheo
2026-05-15 11:21:53 +02:00
parent 6deafd07ff
commit 1259a23acc

View File

@@ -3,7 +3,7 @@ import struct
from io import BytesIO from io import BytesIO
from ripemd160 import ripemd160 from ripemd160 import ripemd160
from secp256k1lab.secp256k1 import Scalar from secp256k1lab.secp256k1 import Scalar
from typing import List, Union from typing import List, Optional, Union
def from_hex(hex_string: str) -> BytesIO: def from_hex(hex_string: str) -> BytesIO:
@@ -65,17 +65,17 @@ def deser_string_vector(f: BytesIO) -> List[bytes]:
class COutPoint: class COutPoint:
__slots__ = ("hash", "n",) __slots__ = ("hash", "n",)
def __init__(self, hash=b"", n=0,): def __init__(self, hash: bytes = b"", n: int = 0) -> None:
self.hash = hash self.hash = hash
self.n = n self.n = n
def serialize(self): def serialize(self) -> bytes:
r = b"" r = b""
r += self.hash r += self.hash
r += struct.pack("<I", self.n) r += struct.pack("<I", self.n)
return r return r
def deserialize(self, f): def deserialize(self, f: BytesIO) -> None:
self.hash = f.read(32) self.hash = f.read(32)
self.n = struct.unpack("<I", f.read(4))[0] self.n = struct.unpack("<I", f.read(4))[0]
@@ -83,7 +83,14 @@ class COutPoint:
class VinInfo: class VinInfo:
__slots__ = ("outpoint", "scriptSig", "txinwitness", "prevout", "private_key") __slots__ = ("outpoint", "scriptSig", "txinwitness", "prevout", "private_key")
def __init__(self, outpoint=None, scriptSig=b"", txinwitness=None, prevout=b"", private_key=None): def __init__(
self,
outpoint: Optional["COutPoint"] = None,
scriptSig: bytes = b"",
txinwitness: Optional["CTxInWitness"] = None,
prevout: bytes = b"",
private_key: Optional[Scalar] = None,
) -> None:
if outpoint is None: if outpoint is None:
self.outpoint = COutPoint() self.outpoint = COutPoint()
else: else:
@@ -103,11 +110,11 @@ class VinInfo:
class CScriptWitness: class CScriptWitness:
__slots__ = ("stack",) __slots__ = ("stack",)
def __init__(self): def __init__(self) -> None:
# stack is a vector of strings # stack is a vector of strings
self.stack = [] self.stack: List[bytes] = []
def is_null(self): def is_null(self) -> bool:
if self.stack: if self.stack:
return False return False
return True return True
@@ -116,14 +123,14 @@ class CScriptWitness:
class CTxInWitness: class CTxInWitness:
__slots__ = ("scriptWitness",) __slots__ = ("scriptWitness",)
def __init__(self): def __init__(self) -> None:
self.scriptWitness = CScriptWitness() self.scriptWitness = CScriptWitness()
def deserialize(self, f: BytesIO): def deserialize(self, f: BytesIO) -> "CTxInWitness":
self.scriptWitness.stack = deser_string_vector(f) self.scriptWitness.stack = deser_string_vector(f)
return self return self
def is_null(self): def is_null(self) -> bool:
return self.scriptWitness.is_null() return self.scriptWitness.is_null()