@@ -133,6 +133,7 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
133
133
134
134
from multiformats.multicodec import Multicodec
135
135
from multiformats.multibase import Multibase
136
+ from multiformats.multihash import Multihash, _validate_raw_digest_size
136
137
from multiformats.varint import BytesLike, byteslike
137
138
138
139
_CIDSubclass = TypeVar("_CIDSubclass", bound="CID")
@@ -144,8 +145,7 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
144
145
if len(cid) == 46 and cid.startswith("Qm"):
145
146
# CIDv0 to be decoded as base58btc
146
147
return base58btc.decode(cid), multibase.get("base58btc")
147
- b = multibase.decode(cid)
148
- mb = multibase.from_str(cid)
148
+ mb, b = multibase.decode_raw(cid)
149
149
if b[0] == 0x12:
150
150
# CIDv0 may not be multibase encoded (0x12 is the first byte of sha2-256 multihashes)
151
151
# CIDv18 (first byte 18=0x12) will be skipped to prevent ambiguity
@@ -168,29 +168,27 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
168
168
multicodec.validate_multicodec(codec)
169
169
return codec
170
170
171
- def _CID_validate_multihash(hashfun: Union[str, int, Multicodec ]) -> Multicodec :
171
+ def _CID_validate_multihash(hashfun: Union[str, int, Multihash ]) -> Multihash :
172
172
if isinstance(hashfun, str):
173
173
hashfun = multihash.get(hashfun)
174
174
elif isinstance(hashfun, int):
175
175
hashfun = multihash.get(code=hashfun)
176
176
else:
177
- multihash.validate_multihash(hashfun)
177
+ pass
178
178
return hashfun
179
179
180
- def _CID_validate_raw_digest(raw_digest: Union[str, BytesLike], hashfun: Multicodec ) -> bytes:
180
+ def _CID_validate_raw_digest(raw_digest: Union[str, BytesLike], hashfun: Multihash ) -> bytes:
181
181
if isinstance(raw_digest, str):
182
182
raw_digest = bytes.fromhex(raw_digest)
183
183
else:
184
184
validate(raw_digest, BytesLike)
185
185
if not isinstance(raw_digest, bytes):
186
186
raw_digest = bytes(raw_digest)
187
- _, _, max_digest_size = multihash.implementation(hashfun)
188
- if max_digest_size is not None and len(raw_digest) > max_digest_size:
189
- raise ValueError(f"Digest size {len(raw_digest)} exceeds max digest size {max_digest_size} "
190
- f"for multihash multicodec {hashfun.name}")
187
+ _, max_digest_size = hashfun.implementation
188
+ _validate_raw_digest_size(hashfun.name, raw_digest, max_digest_size)
191
189
return raw_digest
192
190
193
- def _CID_validate_multihash_digest(digest: Union[str, BytesLike]) -> Tuple[Multicodec , bytes]:
191
+ def _CID_validate_multihash_digest(digest: Union[str, BytesLike]) -> Tuple[Multihash , bytes]:
194
192
if isinstance(digest, str):
195
193
digest = bytes.fromhex(digest)
196
194
raw_digest: BytesLike
@@ -199,7 +197,7 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
199
197
raw_digest = _CID_validate_raw_digest(raw_digest, hashfun)
200
198
return hashfun, raw_digest
201
199
202
- def _CID_validate_version(version: int, base: Multibase, codec: Multicodec, hashfun: Multicodec ) -> int:
200
+ def _CID_validate_version(version: int, base: Multibase, codec: Multicodec, hashfun: Multihash ) -> int:
203
201
if version in (2, 3):
204
202
raise ValueError("CID versions 2 and 3 are reserved for future use.")
205
203
if version not in (0, 1):
@@ -277,7 +275,7 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
277
275
_base: Multibase
278
276
_version: CIDVersion
279
277
_codec: Multicodec
280
- _hashfun: Multicodec
278
+ _hashfun: Multihash
281
279
_digest: bytes
282
280
283
281
__slots__ = ("__weakref__", "_base", "_version", "_codec", "_hashfun", "_digest")
@@ -286,17 +284,17 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
286
284
base: Union[str, Multibase],
287
285
version: int,
288
286
codec: Union[str, int, Multicodec],
289
- digest: Union[str, BytesLike, Tuple[Union[str, int, Multicodec ], Union[str, BytesLike]]],
287
+ digest: Union[str, BytesLike, Tuple[Union[str, int, Multihash ], Union[str, BytesLike]]],
290
288
) -> _CIDSubclass:
291
289
# pylint: disable = too-many-arguments
292
290
base = _CID_validate_multibase(base)
293
291
codec = _CID_validate_multicodec(codec)
294
292
raw_digest: Union[str, bytes]
295
- hashfun: Union[str, int, Multicodec ]
293
+ hashfun: Union[str, int, Multihash ]
296
294
if isinstance(digest, (str,)+byteslike):
297
295
hashfun, raw_digest = _CID_validate_multihash_digest(digest)
298
296
else:
299
- validate(digest, Tuple[Union[str, int, Multicodec ], Union[str, BytesLike]])
297
+ validate(digest, Tuple[Union[str, int, Multihash ], Union[str, BytesLike]])
300
298
hashfun, raw_digest = digest
301
299
hashfun = _CID_validate_multihash(hashfun)
302
300
raw_digest = _CID_validate_raw_digest(raw_digest, hashfun)
@@ -310,8 +308,8 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
310
308
base: Multibase,
311
309
version: int,
312
310
codec: Multicodec,
313
- hashfun: Multicodec ,
314
- digest: Union[bytes, Tuple[Multicodec , bytes]],
311
+ hashfun: Multihash ,
312
+ digest: Union[bytes, Tuple[Multihash , bytes]],
315
313
) -> _CIDSubclass:
316
314
# pylint: disable = too-many-arguments
317
315
instance = super().__new__(CID_subclass)
@@ -328,7 +326,7 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
328
326
if not isinstance(raw_digest, bytes):
329
327
raw_digest = bytes(raw_digest)
330
328
assert _hashfun == hashfun, "You passed different multihashes to a _new_instance call with digest as a pair."
331
- instance._digest = multihash .encode(raw_digest, hashfun )
329
+ instance._digest = hashfun .encode(raw_digest)
332
330
return cast(_CIDSubclass, instance)
333
331
334
332
@property
@@ -386,9 +384,9 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
386
384
return self._codec
387
385
388
386
@property
389
- def hashfun(self) -> Multicodec :
387
+ def hashfun(self) -> Multihash :
390
388
"""
391
- Multihash codec used to produce the multihash digest.
389
+ Multihash used to produce the multihash digest.
392
390
393
391
Example usage:
394
392
@@ -563,13 +561,19 @@ <h1 class="title">Module <code>multiformats.cid</code></h1>
563
561
d = self.digest
564
562
return f"CID({repr(mb)}, {v}, {repr(mc)}, {repr(d.hex())})"
565
563
564
+ @property
565
+ def _as_tuple(self) -> Tuple[Type["CID"], Multibase, int, Multicodec, bytes]:
566
+ return (CID, self.base, self.version, self.codec, self.digest)
567
+
568
+ def __hash__(self) -> int:
569
+ return hash(self._as_tuple)
570
+
566
571
def __eq__(self, other: Any) -> bool:
567
572
if self is other:
568
573
return True
569
574
if not isinstance(other, CID):
570
- return False
571
- return (self.base == other.base and self.version == other.version
572
- and self.codec == other.codec and self.digest == other.digest)
575
+ return NotImplemented
576
+ return self._as_tuple == other._as_tuple
573
577
574
578
@staticmethod
575
579
def decode(cid: Union[str, BytesLike]) -> "CID":
@@ -765,7 +769,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
765
769
< dl >
766
770
< dt id ="multiformats.cid.CID "> < code class ="flex name class ">
767
771
< span > class < span class ="ident "> CID</ span > </ span >
768
- < span > (</ span > < span > base: Union[str, < a title ="multiformats.multibase.Multibase " href ="multibase/index.html#multiformats.multibase.Multibase "> Multibase</ a > ], version: int, codec: Union[str, int, < a title ="multiformats.multicodec.Multicodec " href ="multicodec/index.html#multiformats.multicodec.Multicodec "> Multicodec</ a > ], digest: Union[str, bytes, bytearray, memoryview, Tuple[Union[str, int, < a title ="multiformats.multicodec.Multicodec " href ="multicodec /index.html#multiformats.multicodec.Multicodec " > Multicodec </ a > ], Union[str, bytes, bytearray, memoryview]]])</ span >
772
+ < span > (</ span > < span > base: Union[str, < a title ="multiformats.multibase.Multibase " href ="multibase/index.html#multiformats.multibase.Multibase "> Multibase</ a > ], version: int, codec: Union[str, int, < a title ="multiformats.multicodec.Multicodec " href ="multicodec/index.html#multiformats.multicodec.Multicodec "> Multicodec</ a > ], digest: Union[str, bytes, bytearray, memoryview, Tuple[Union[str, int, < a title ="multiformats.multihash.Multihash " href ="multihash /index.html#multiformats.multihash.Multihash " > Multihash </ a > ], Union[str, bytes, bytearray, memoryview]]])</ span >
769
773
</ code > </ dt >
770
774
< dd >
771
775
< div class ="desc "> < p > Container class for < a href ="https://github.com/multiformats/cid "> Content IDentifiers</ a > .
@@ -874,7 +878,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
874
878
_base: Multibase
875
879
_version: CIDVersion
876
880
_codec: Multicodec
877
- _hashfun: Multicodec
881
+ _hashfun: Multihash
878
882
_digest: bytes
879
883
880
884
__slots__ = ("__weakref__", "_base", "_version", "_codec", "_hashfun", "_digest")
@@ -883,17 +887,17 @@ <h2 class="section-title" id="header-classes">Classes</h2>
883
887
base: Union[str, Multibase],
884
888
version: int,
885
889
codec: Union[str, int, Multicodec],
886
- digest: Union[str, BytesLike, Tuple[Union[str, int, Multicodec ], Union[str, BytesLike]]],
890
+ digest: Union[str, BytesLike, Tuple[Union[str, int, Multihash ], Union[str, BytesLike]]],
887
891
) -> _CIDSubclass:
888
892
# pylint: disable = too-many-arguments
889
893
base = _CID_validate_multibase(base)
890
894
codec = _CID_validate_multicodec(codec)
891
895
raw_digest: Union[str, bytes]
892
- hashfun: Union[str, int, Multicodec ]
896
+ hashfun: Union[str, int, Multihash ]
893
897
if isinstance(digest, (str,)+byteslike):
894
898
hashfun, raw_digest = _CID_validate_multihash_digest(digest)
895
899
else:
896
- validate(digest, Tuple[Union[str, int, Multicodec ], Union[str, BytesLike]])
900
+ validate(digest, Tuple[Union[str, int, Multihash ], Union[str, BytesLike]])
897
901
hashfun, raw_digest = digest
898
902
hashfun = _CID_validate_multihash(hashfun)
899
903
raw_digest = _CID_validate_raw_digest(raw_digest, hashfun)
@@ -907,8 +911,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
907
911
base: Multibase,
908
912
version: int,
909
913
codec: Multicodec,
910
- hashfun: Multicodec ,
911
- digest: Union[bytes, Tuple[Multicodec , bytes]],
914
+ hashfun: Multihash ,
915
+ digest: Union[bytes, Tuple[Multihash , bytes]],
912
916
) -> _CIDSubclass:
913
917
# pylint: disable = too-many-arguments
914
918
instance = super().__new__(CID_subclass)
@@ -925,7 +929,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
925
929
if not isinstance(raw_digest, bytes):
926
930
raw_digest = bytes(raw_digest)
927
931
assert _hashfun == hashfun, "You passed different multihashes to a _new_instance call with digest as a pair."
928
- instance._digest = multihash .encode(raw_digest, hashfun )
932
+ instance._digest = hashfun .encode(raw_digest)
929
933
return cast(_CIDSubclass, instance)
930
934
931
935
@property
@@ -983,9 +987,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
983
987
return self._codec
984
988
985
989
@property
986
- def hashfun(self) -> Multicodec :
990
+ def hashfun(self) -> Multihash :
987
991
"""
988
- Multihash codec used to produce the multihash digest.
992
+ Multihash used to produce the multihash digest.
989
993
990
994
Example usage:
991
995
@@ -1160,13 +1164,19 @@ <h2 class="section-title" id="header-classes">Classes</h2>
1160
1164
d = self.digest
1161
1165
return f"CID({repr(mb)}, {v}, {repr(mc)}, {repr(d.hex())})"
1162
1166
1167
+ @property
1168
+ def _as_tuple(self) -> Tuple[Type["CID"], Multibase, int, Multicodec, bytes]:
1169
+ return (CID, self.base, self.version, self.codec, self.digest)
1170
+
1171
+ def __hash__(self) -> int:
1172
+ return hash(self._as_tuple)
1173
+
1163
1174
def __eq__(self, other: Any) -> bool:
1164
1175
if self is other:
1165
1176
return True
1166
1177
if not isinstance(other, CID):
1167
- return False
1168
- return (self.base == other.base and self.version == other.version
1169
- and self.codec == other.codec and self.digest == other.digest)
1178
+ return NotImplemented
1179
+ return self._as_tuple == other._as_tuple
1170
1180
1171
1181
@staticmethod
1172
1182
def decode(cid: Union[str, BytesLike]) -> "CID":
@@ -1766,9 +1776,9 @@ <h3>Instance variables</h3>
1766
1776
return self._digest</ code > </ pre >
1767
1777
</ details >
1768
1778
</ dd >
1769
- < dt id ="multiformats.cid.CID.hashfun "> < code class ="name "> var < span class ="ident "> hashfun</ span > : < a title ="multiformats.multicodec.Multicodec " href ="multicodec /index.html#multiformats.multicodec.Multicodec " > Multicodec </ a > </ code > </ dt >
1779
+ < dt id ="multiformats.cid.CID.hashfun "> < code class ="name "> var < span class ="ident "> hashfun</ span > : < a title ="multiformats.multihash.Multihash " href ="multihash /index.html#multiformats.multihash.Multihash " > Multihash </ a > </ code > </ dt >
1770
1780
< dd >
1771
- < div class ="desc "> < p > Multihash codec used to produce the multihash digest.</ p >
1781
+ < div class ="desc "> < p > Multihash used to produce the multihash digest.</ p >
1772
1782
< p > Example usage:</ p >
1773
1783
< pre > < code class ="language-py "> >>> s = "zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA"
1774
1784
>>> cid = CID.decode(s)
@@ -1781,9 +1791,9 @@ <h3>Instance variables</h3>
1781
1791
< span > Expand source code</ span >
1782
1792
</ summary >
1783
1793
< pre > < code class ="python "> @property
1784
- def hashfun(self) -> Multicodec :
1794
+ def hashfun(self) -> Multihash :
1785
1795
"""
1786
- Multihash codec used to produce the multihash digest.
1796
+ Multihash used to produce the multihash digest.
1787
1797
1788
1798
Example usage:
1789
1799
0 commit comments