|
1 | 1 | from abc import abstractmethod |
2 | 2 | from collections.abc import Sequence |
3 | 3 | from hashlib import sha256 |
4 | | -from typing import Union, Protocol, runtime_checkable, Sequence as TypedSequence |
| 4 | +from typing import ( |
| 5 | + Iterable, |
| 6 | + List, |
| 7 | + Union, |
| 8 | + Protocol, |
| 9 | + runtime_checkable, |
| 10 | + Sequence as TypedSequence, |
| 11 | +) |
5 | 12 |
|
6 | 13 | from .group import ( |
7 | 14 | ElementModPOrQ, |
@@ -69,25 +76,27 @@ def hash_elems(*a: CRYPTO_HASHABLE_ALL) -> ElementModQ: |
69 | 76 | # that's a bit Python-specific, and we'd rather make it easier for other languages |
70 | 77 | # to exactly match this hash function. |
71 | 78 |
|
72 | | - if not x: |
73 | | - # This case captures empty lists and None, nicely guaranteeing that we don't |
74 | | - # need to do a recursive call if the list is empty. So we need a string to |
75 | | - # feed in for both of these cases. "None" would be a Python-specific thing, |
76 | | - # so we'll go with the more JSON-ish "null". |
77 | | - hash_me = "null" |
78 | | - |
79 | | - elif isinstance(x, (ElementModP, ElementModQ)): |
| 79 | + if isinstance(x, (ElementModP, ElementModQ)): |
80 | 80 | hash_me = x.to_hex() |
81 | 81 | elif isinstance(x, CryptoHashable): |
82 | 82 | hash_me = x.crypto_hash().to_hex() |
83 | 83 | elif isinstance(x, str): |
84 | | - # strings are iterable, so it's important to handle them before the following check |
| 84 | + # strings are iterable, so it's important to handle them before list-like types |
85 | 85 | hash_me = x |
86 | | - elif isinstance(x, Sequence): |
| 86 | + elif isinstance(x, int): |
| 87 | + hash_me = str(x) |
| 88 | + elif not x: |
| 89 | + # This case captures empty lists and None, nicely guaranteeing that we don't |
| 90 | + # need to do a recursive call if the list is empty. So we need a string to |
| 91 | + # feed in for both of these cases. "None" would be a Python-specific thing, |
| 92 | + # so we'll go with the more JSON-ish "null". |
| 93 | + hash_me = "null" |
| 94 | + elif isinstance(x, (Sequence, List, Iterable)): |
87 | 95 | # The simplest way to deal with lists, tuples, and such are to crunch them recursively. |
88 | 96 | hash_me = hash_elems(*x).to_hex() |
89 | 97 | else: |
90 | 98 | hash_me = str(x) |
| 99 | + |
91 | 100 | h.update((hash_me + "|").encode("utf-8")) |
92 | 101 |
|
93 | 102 | # We don't need the checked version of int_to_q, because the |
|
0 commit comments