Skip to content

Commit 356828f

Browse files
committed
introduce information for runtime type
1 parent 833fc2e commit 356828f

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

Lib/test/support/hashlib_helper.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,61 @@ def invalid_implementation_error(self, implementation):
198198
return AssertionError(msg)
199199

200200

201+
class _HashTypeInfo(_HashInfoBase):
202+
"""Dataclass containing information for hash functions types.
203+
204+
- *builtin* is the fully-qualified name for the builtin HACL* type,
205+
e.g., "_md5.MD5Type".
206+
207+
- *openssl* is the fully-qualified name for the OpenSSL wrapper type,
208+
e.g., "_hashlib.HASH".
209+
"""
210+
211+
def __init__(self, canonical_name, builtin, openssl):
212+
super().__init__(canonical_name)
213+
self.builtin = _HashInfoItem(builtin, strict=True)
214+
self.openssl = _HashInfoItem(openssl, strict=True)
215+
216+
def fullname(self, implementation):
217+
"""Get the fully qualified name of a given implementation.
218+
219+
This returns a string of the form "MODULE_NAME.OBJECT_NAME" or None
220+
if the hash function does not have a corresponding implementation.
221+
222+
*implementation* must be "builtin" or "openssl".
223+
"""
224+
return self[implementation].fullname
225+
226+
def module_name(self, implementation):
227+
"""Get the name of the module containing the hash object type."""
228+
return self[implementation].module_name
229+
230+
def object_type_name(self, implementation):
231+
"""Get the name of the hash object class name."""
232+
return self[implementation].member_name
233+
234+
def import_module(self, implementation, *, allow_skip=False):
235+
"""Import the module containing the hash object type.
236+
237+
On error, return None if *allow_skip* is false, or raise SkipNoHash.
238+
"""
239+
module = self[implementation].import_module()
240+
if allow_skip and module is None:
241+
raise SkipNoHash(self.canonical_name, implementation)
242+
return module
243+
244+
def import_object_type(self, implementation, *, allow_skip=False):
245+
"""Get the runtime hash object type.
246+
247+
On error, return None if *allow_skip* is false, or raise SkipNoHash.
248+
"""
249+
member = self[implementation].import_member()
250+
if allow_skip and member is None:
251+
raise SkipNoHash(self.name, implementation, interface="class")
252+
assert isinstance(member, type | None), member
253+
return member
254+
255+
201256
class _HashFuncInfo(_HashInfoBase):
202257
"""Dataclass containing information for hash functions constructors.
203258
@@ -247,6 +302,12 @@ def method_name(self, implementation):
247302
class _HashInfo:
248303
"""Dataclass containing information for supported hash functions.
249304
305+
- *builtin_object_type_fullname* is the fully-qualified name
306+
for the builtin HACL* type, e.g., "_md5.MD5Type".
307+
308+
- *openssl_object_type_fullname* is the fully-qualified name
309+
for the OpenSSL wrapper type, i.e. "_hashlib.HASH" or "_hashlib.HASHXOF".
310+
250311
- *builtin_method_fullname* is the fully-qualified name
251312
of the HACL* hash constructor function, e.g., "_md5.md5".
252313
@@ -262,11 +323,19 @@ class _HashInfo:
262323
def __init__(
263324
self,
264325
name,
326+
builtin_object_type_fullname,
327+
openssl_object_type_fullname,
265328
builtin_method_fullname,
266329
openssl_method_fullname=None,
267330
hashlib_method_fullname=None,
268331
):
269332
self.name = name
333+
334+
self.type = _HashTypeInfo(
335+
name,
336+
builtin_object_type_fullname,
337+
openssl_object_type_fullname,
338+
)
270339
self.func = _HashFuncInfo(
271340
name,
272341
builtin_method_fullname,
@@ -278,92 +347,126 @@ def __init__(
278347
_HASHINFO_DATABASE = MappingProxyType({
279348
HashId.md5: _HashInfo(
280349
HashId.md5,
350+
"_md5.MD5Type",
351+
"_hashlib.HASH",
281352
"_md5.md5",
282353
"_hashlib.openssl_md5",
283354
"hashlib.md5",
284355
),
285356
HashId.sha1: _HashInfo(
286357
HashId.sha1,
358+
"_sha1.SHA1Type",
359+
"_hashlib.HASH",
287360
"_sha1.sha1",
288361
"_hashlib.openssl_sha1",
289362
"hashlib.sha1",
290363
),
291364
HashId.sha224: _HashInfo(
292365
HashId.sha224,
366+
"_sha2.SHA224Type",
367+
"_hashlib.HASH",
293368
"_sha2.sha224",
294369
"_hashlib.openssl_sha224",
295370
"hashlib.sha224",
296371
),
297372
HashId.sha256: _HashInfo(
298373
HashId.sha256,
374+
"_sha2.SHA256Type",
375+
"_hashlib.HASH",
299376
"_sha2.sha256",
300377
"_hashlib.openssl_sha256",
301378
"hashlib.sha256",
302379
),
303380
HashId.sha384: _HashInfo(
304381
HashId.sha384,
382+
"_sha2.SHA384Type",
383+
"_hashlib.HASH",
305384
"_sha2.sha384",
306385
"_hashlib.openssl_sha384",
307386
"hashlib.sha384",
308387
),
309388
HashId.sha512: _HashInfo(
310389
HashId.sha512,
390+
"_sha2.SHA512Type",
391+
"_hashlib.HASH",
311392
"_sha2.sha512",
312393
"_hashlib.openssl_sha512",
313394
"hashlib.sha512",
314395
),
315396
HashId.sha3_224: _HashInfo(
316397
HashId.sha3_224,
317398
"_sha3.sha3_224",
399+
"_hashlib.HASH",
400+
"_sha3.sha3_224",
318401
"_hashlib.openssl_sha3_224",
319402
"hashlib.sha3_224",
320403
),
321404
HashId.sha3_256: _HashInfo(
322405
HashId.sha3_256,
323406
"_sha3.sha3_256",
407+
"_hashlib.HASH",
408+
"_sha3.sha3_256",
324409
"_hashlib.openssl_sha3_256",
325410
"hashlib.sha3_256",
326411
),
327412
HashId.sha3_384: _HashInfo(
328413
HashId.sha3_384,
329414
"_sha3.sha3_384",
415+
"_hashlib.HASH",
416+
"_sha3.sha3_384",
330417
"_hashlib.openssl_sha3_384",
331418
"hashlib.sha3_384",
332419
),
333420
HashId.sha3_512: _HashInfo(
334421
HashId.sha3_512,
335422
"_sha3.sha3_512",
423+
"_hashlib.HASH",
424+
"_sha3.sha3_512",
336425
"_hashlib.openssl_sha3_512",
337426
"hashlib.sha3_512",
338427
),
339428
HashId.shake_128: _HashInfo(
340429
HashId.shake_128,
341430
"_sha3.shake_128",
431+
"_hashlib.HASHXOF",
432+
"_sha3.shake_128",
342433
"_hashlib.openssl_shake_128",
343434
"hashlib.shake_128",
344435
),
345436
HashId.shake_256: _HashInfo(
346437
HashId.shake_256,
347438
"_sha3.shake_256",
439+
"_hashlib.HASHXOF",
440+
"_sha3.shake_256",
348441
"_hashlib.openssl_shake_256",
349442
"hashlib.shake_256",
350443
),
351444
HashId.blake2s: _HashInfo(
352445
HashId.blake2s,
353446
"_blake2.blake2s",
447+
"_hashlib.HASH",
448+
"_blake2.blake2s",
354449
None,
355450
"hashlib.blake2s",
356451
),
357452
HashId.blake2b: _HashInfo(
358453
HashId.blake2b,
359454
"_blake2.blake2b",
455+
"_hashlib.HASH",
456+
"_blake2.blake2b",
360457
None,
361458
"hashlib.blake2b",
362459
),
363460
})
364461
assert _HASHINFO_DATABASE.keys() == CANONICAL_DIGEST_NAMES
365462

366463

464+
def get_hash_type_info(name):
465+
info = _HASHINFO_DATABASE[name]
466+
assert isinstance(info, _HashInfo), info
467+
return info.type
468+
469+
367470
def get_hash_func_info(name):
368471
info = _HASHINFO_DATABASE[name]
369472
assert isinstance(info, _HashInfo), info

0 commit comments

Comments
 (0)