Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/pyvex/utils.py: 72%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import struct
2from typing import Any, Callable, Dict, Tuple
4try:
5 import _md5 as md5lib
6except ImportError:
7 import hashlib as md5lib
10md5_unpacker = struct.Struct("4I")
13def stable_hash(t: Tuple) -> int:
14 cnt = _dump_tuple(t)
15 hd = md5lib.md5(cnt).digest()
16 return md5_unpacker.unpack(hd)[0] # 32 bits
19def _dump_tuple(t: Tuple) -> bytes:
20 cnt = b""
21 for item in t:
22 if item is not None:
23 type_ = type(item)
24 if type_ in _DUMP_BY_TYPE:
25 cnt += _DUMP_BY_TYPE[type_](item)
26 else:
27 cnt += struct.pack("<Q", hash(item) & 0xFFFF_FFFF_FFFF_FFFF)
28 cnt += b"\xf0"
29 return cnt
32def _dump_str(t: str) -> bytes:
33 return t.encode("ascii")
36def _dump_int(t: int) -> bytes:
37 prefix = b"" if t >= 0 else b"-"
38 t = abs(t)
39 if t <= 0xFFFF:
40 return prefix + struct.pack("<H", t)
41 elif t <= 0xFFFF_FFFF:
42 return prefix + struct.pack("<I", t)
43 elif t <= 0xFFFF_FFFF_FFFF_FFFF:
44 return prefix + struct.pack("<Q", t)
45 else:
46 cnt = b""
47 while t > 0:
48 cnt += _dump_int(t & 0xFFFF_FFFF_FFFF_FFFF)
49 t >>= 64
50 return prefix + cnt
53def _dump_type(t: type) -> bytes:
54 return t.__name__.encode("ascii")
57_DUMP_BY_TYPE: Dict[type, Callable[[Any], bytes]] = {
58 tuple: _dump_tuple,
59 str: _dump_str,
60 int: _dump_int,
61 type: _dump_type,
62}