1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt
4
5from astroid import nodes
6from astroid.brain.helpers import register_module_extender
7from astroid.builder import parse
8from astroid.manager import AstroidManager
9
10
11def _hashlib_transform() -> nodes.Module:
12 init_signature = "value='', usedforsecurity=True"
13 digest_signature = "self"
14 shake_digest_signature = "self, length"
15
16 template = """
17 class %(name)s:
18 def __init__(self, %(init_signature)s): pass
19 def digest(%(digest_signature)s):
20 return %(digest)s
21 def copy(self):
22 return self
23 def update(self, value): pass
24 def hexdigest(%(digest_signature)s):
25 return ''
26 @property
27 def name(self):
28 return %(name)r
29 @property
30 def block_size(self):
31 return 1
32 @property
33 def digest_size(self):
34 return 1
35 """
36
37 algorithms_with_signature = dict.fromkeys(
38 [
39 "md5",
40 "sha1",
41 "sha224",
42 "sha256",
43 "sha384",
44 "sha512",
45 "sha3_224",
46 "sha3_256",
47 "sha3_384",
48 "sha3_512",
49 ],
50 (init_signature, digest_signature),
51 )
52
53 blake2b_signature = (
54 "data=b'', *, digest_size=64, key=b'', salt=b'', "
55 "person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, "
56 "node_depth=0, inner_size=0, last_node=False, usedforsecurity=True"
57 )
58
59 blake2s_signature = (
60 "data=b'', *, digest_size=32, key=b'', salt=b'', "
61 "person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, "
62 "node_depth=0, inner_size=0, last_node=False, usedforsecurity=True"
63 )
64
65 shake_algorithms = dict.fromkeys(
66 ["shake_128", "shake_256"],
67 (init_signature, shake_digest_signature),
68 )
69 algorithms_with_signature.update(shake_algorithms)
70
71 algorithms_with_signature.update(
72 {
73 "blake2b": (blake2b_signature, digest_signature),
74 "blake2s": (blake2s_signature, digest_signature),
75 }
76 )
77
78 classes = "".join(
79 template
80 % {
81 "name": hashfunc,
82 "digest": 'b""',
83 "init_signature": init_signature,
84 "digest_signature": digest_signature,
85 }
86 for hashfunc, (
87 init_signature,
88 digest_signature,
89 ) in algorithms_with_signature.items()
90 )
91
92 return parse(classes)
93
94
95def register(manager: AstroidManager) -> None:
96 register_module_extender(manager, "hashlib", _hashlib_transform)