Skip to content

Commit 04749c1

Browse files
Merge branch 'RustPython:main' into 4845
2 parents c03d3a5 + 0284059 commit 04749c1

File tree

150 files changed

+4726
-1961
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+4726
-1961
lines changed

.github/workflows/ci.yaml

+9-4
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ jobs:
124124
- name: Set up the Windows environment
125125
shell: bash
126126
run: |
127-
choco install llvm openssl
128-
echo "OPENSSL_DIR=C:\Program Files\OpenSSL-Win64" >>$GITHUB_ENV
127+
choco install llvm openssl --no-progress
128+
echo "OPENSSL_DIR=C:\Program Files\OpenSSL" >>$GITHUB_ENV
129129
if: runner.os == 'Windows'
130130
- name: Set up the Mac environment
131131
run: brew install autoconf automake libtool
@@ -263,8 +263,8 @@ jobs:
263263
- name: Set up the Windows environment
264264
shell: bash
265265
run: |
266-
choco install llvm openssl
267-
echo "OPENSSL_DIR=C:\Program Files\OpenSSL-Win64" >>$GITHUB_ENV
266+
choco install llvm openssl --no-progress
267+
echo "OPENSSL_DIR=C:\Program Files\OpenSSL" >>$GITHUB_ENV
268268
if: runner.os == 'Windows'
269269
- name: Set up the Mac environment
270270
run: brew install autoconf automake libtool openssl@3
@@ -308,6 +308,11 @@ jobs:
308308
run: |
309309
target/release/rustpython -m ensurepip
310310
target/release/rustpython -c "import pip"
311+
- if: runner.os != 'Windows'
312+
name: Check if pip inside venv is functional
313+
run: |
314+
target/release/rustpython -m venv testvenv
315+
testvenv/bin/rustpython -m pip install wheel
311316
- name: Check whats_left is not broken
312317
run: python -I whats_left.py
313318

.vscode/launch.json

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
"preLaunchTask": "Build RustPython Debug",
1818
"program": "target/debug/rustpython",
1919
"args": [],
20+
"env": {
21+
"RUST_BACKTRACE": "1"
22+
},
2023
"cwd": "${workspaceFolder}"
2124
},
2225
{

Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/concurrent/futures/thread.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def _python_exit():
3737
threading._register_atexit(_python_exit)
3838

3939
# At fork, reinitialize the `_global_shutdown_lock` lock in the child process
40-
if hasattr(os, 'register_at_fork'):
40+
# TODO RUSTPYTHON - _at_fork_reinit is not implemented yet
41+
if hasattr(os, 'register_at_fork') and hasattr(_global_shutdown_lock, '_at_fork_reinit'):
4142
os.register_at_fork(before=_global_shutdown_lock.acquire,
4243
after_in_child=_global_shutdown_lock._at_fork_reinit,
4344
after_in_parent=_global_shutdown_lock.release)

Lib/hashlib.py

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
#. Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org)
2+
# Licensed to PSF under a Contributor Agreement.
3+
#
4+
5+
__doc__ = """hashlib module - A common interface to many hash functions.
6+
7+
new(name, data=b'', **kwargs) - returns a new hash object implementing the
8+
given hash function; initializing the hash
9+
using the given binary data.
10+
11+
Named constructor functions are also available, these are faster
12+
than using new(name):
13+
14+
md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(),
15+
sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256.
16+
17+
More algorithms may be available on your platform but the above are guaranteed
18+
to exist. See the algorithms_guaranteed and algorithms_available attributes
19+
to find out what algorithm names can be passed to new().
20+
21+
NOTE: If you want the adler32 or crc32 hash functions they are available in
22+
the zlib module.
23+
24+
Choose your hash function wisely. Some have known collision weaknesses.
25+
sha384 and sha512 will be slow on 32 bit platforms.
26+
27+
Hash objects have these methods:
28+
- update(data): Update the hash object with the bytes in data. Repeated calls
29+
are equivalent to a single call with the concatenation of all
30+
the arguments.
31+
- digest(): Return the digest of the bytes passed to the update() method
32+
so far as a bytes object.
33+
- hexdigest(): Like digest() except the digest is returned as a string
34+
of double length, containing only hexadecimal digits.
35+
- copy(): Return a copy (clone) of the hash object. This can be used to
36+
efficiently compute the digests of datas that share a common
37+
initial substring.
38+
39+
For example, to obtain the digest of the byte string 'Nobody inspects the
40+
spammish repetition':
41+
42+
>>> import hashlib
43+
>>> m = hashlib.md5()
44+
>>> m.update(b"Nobody inspects")
45+
>>> m.update(b" the spammish repetition")
46+
>>> m.digest()
47+
b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
48+
49+
More condensed:
50+
51+
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
52+
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
53+
54+
"""
55+
56+
# This tuple and __get_builtin_constructor() must be modified if a new
57+
# always available algorithm is added.
58+
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512',
59+
'blake2b', 'blake2s',
60+
'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512',
61+
'shake_128', 'shake_256')
62+
63+
64+
algorithms_guaranteed = set(__always_supported)
65+
algorithms_available = set(__always_supported)
66+
67+
__all__ = __always_supported + ('new', 'algorithms_guaranteed',
68+
'algorithms_available', 'pbkdf2_hmac', 'file_digest')
69+
70+
71+
__builtin_constructor_cache = {}
72+
73+
# Prefer our blake2 implementation
74+
# OpenSSL 1.1.0 comes with a limited implementation of blake2b/s. The OpenSSL
75+
# implementations neither support keyed blake2 (blake2 MAC) nor advanced
76+
# features like salt, personalization, or tree hashing. OpenSSL hash-only
77+
# variants are available as 'blake2b512' and 'blake2s256', though.
78+
__block_openssl_constructor = {
79+
'blake2b', 'blake2s',
80+
}
81+
82+
def __get_builtin_constructor(name):
83+
cache = __builtin_constructor_cache
84+
constructor = cache.get(name)
85+
if constructor is not None:
86+
return constructor
87+
try:
88+
if name in {'SHA1', 'sha1'}:
89+
import _sha1
90+
cache['SHA1'] = cache['sha1'] = _sha1.sha1
91+
elif name in {'MD5', 'md5'}:
92+
import _md5
93+
cache['MD5'] = cache['md5'] = _md5.md5
94+
elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}:
95+
import _sha256
96+
cache['SHA224'] = cache['sha224'] = _sha256.sha224
97+
cache['SHA256'] = cache['sha256'] = _sha256.sha256
98+
elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}:
99+
import _sha512
100+
cache['SHA384'] = cache['sha384'] = _sha512.sha384
101+
cache['SHA512'] = cache['sha512'] = _sha512.sha512
102+
elif name in {'blake2b', 'blake2s'}:
103+
import _blake2
104+
cache['blake2b'] = _blake2.blake2b
105+
cache['blake2s'] = _blake2.blake2s
106+
elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512'}:
107+
import _sha3
108+
cache['sha3_224'] = _sha3.sha3_224
109+
cache['sha3_256'] = _sha3.sha3_256
110+
cache['sha3_384'] = _sha3.sha3_384
111+
cache['sha3_512'] = _sha3.sha3_512
112+
elif name in {'shake_128', 'shake_256'}:
113+
import _sha3
114+
cache['shake_128'] = _sha3.shake_128
115+
cache['shake_256'] = _sha3.shake_256
116+
except ImportError:
117+
pass # no extension module, this hash is unsupported.'''
118+
119+
constructor = cache.get(name)
120+
if constructor is not None:
121+
return constructor
122+
123+
raise ValueError('unsupported hash type ' + name)
124+
125+
126+
def __get_openssl_constructor(name):
127+
if name in __block_openssl_constructor:
128+
# Prefer our builtin blake2 implementation.
129+
return __get_builtin_constructor(name)
130+
try:
131+
# MD5, SHA1, and SHA2 are in all supported OpenSSL versions
132+
# SHA3/shake are available in OpenSSL 1.1.1+
133+
f = getattr(_hashlib, 'openssl_' + name)
134+
# Allow the C module to raise ValueError. The function will be
135+
# defined but the hash not actually available. Don't fall back to
136+
# builtin if the current security policy blocks a digest, bpo#40695.
137+
f(usedforsecurity=False)
138+
# Use the C function directly (very fast)
139+
return f
140+
except (AttributeError, ValueError):
141+
return __get_builtin_constructor(name)
142+
143+
144+
def __py_new(name, data=b'', **kwargs):
145+
"""new(name, data=b'', **kwargs) - Return a new hashing object using the
146+
named algorithm; optionally initialized with data (which must be
147+
a bytes-like object).
148+
"""
149+
return __get_builtin_constructor(name)(data, **kwargs)
150+
151+
152+
def __hash_new(name, data=b'', **kwargs):
153+
"""new(name, data=b'') - Return a new hashing object using the named algorithm;
154+
optionally initialized with data (which must be a bytes-like object).
155+
"""
156+
if name in __block_openssl_constructor:
157+
# Prefer our builtin blake2 implementation.
158+
return __get_builtin_constructor(name)(data, **kwargs)
159+
try:
160+
return _hashlib.new(name, data, **kwargs)
161+
except ValueError:
162+
# If the _hashlib module (OpenSSL) doesn't support the named
163+
# hash, try using our builtin implementations.
164+
# This allows for SHA224/256 and SHA384/512 support even though
165+
# the OpenSSL library prior to 0.9.8 doesn't provide them.
166+
return __get_builtin_constructor(name)(data)
167+
168+
169+
try:
170+
import _hashlib
171+
new = __hash_new
172+
__get_hash = __get_openssl_constructor
173+
# TODO: RUSTPYTHON set in _hashlib instance PyFrozenSet algorithms_available
174+
'''algorithms_available = algorithms_available.union(
175+
_hashlib.openssl_md_meth_names)'''
176+
except ImportError:
177+
_hashlib = None
178+
new = __py_new
179+
__get_hash = __get_builtin_constructor
180+
181+
try:
182+
# OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
183+
from _hashlib import pbkdf2_hmac
184+
except ImportError:
185+
from warnings import warn as _warn
186+
_trans_5C = bytes((x ^ 0x5C) for x in range(256))
187+
_trans_36 = bytes((x ^ 0x36) for x in range(256))
188+
189+
def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
190+
"""Password based key derivation function 2 (PKCS #5 v2.0)
191+
192+
This Python implementations based on the hmac module about as fast
193+
as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster
194+
for long passwords.
195+
"""
196+
_warn(
197+
"Python implementation of pbkdf2_hmac() is deprecated.",
198+
category=DeprecationWarning,
199+
stacklevel=2
200+
)
201+
if not isinstance(hash_name, str):
202+
raise TypeError(hash_name)
203+
204+
if not isinstance(password, (bytes, bytearray)):
205+
password = bytes(memoryview(password))
206+
if not isinstance(salt, (bytes, bytearray)):
207+
salt = bytes(memoryview(salt))
208+
209+
# Fast inline HMAC implementation
210+
inner = new(hash_name)
211+
outer = new(hash_name)
212+
blocksize = getattr(inner, 'block_size', 64)
213+
if len(password) > blocksize:
214+
password = new(hash_name, password).digest()
215+
password = password + b'\x00' * (blocksize - len(password))
216+
inner.update(password.translate(_trans_36))
217+
outer.update(password.translate(_trans_5C))
218+
219+
def prf(msg, inner=inner, outer=outer):
220+
# PBKDF2_HMAC uses the password as key. We can re-use the same
221+
# digest objects and just update copies to skip initialization.
222+
icpy = inner.copy()
223+
ocpy = outer.copy()
224+
icpy.update(msg)
225+
ocpy.update(icpy.digest())
226+
return ocpy.digest()
227+
228+
if iterations < 1:
229+
raise ValueError(iterations)
230+
if dklen is None:
231+
dklen = outer.digest_size
232+
if dklen < 1:
233+
raise ValueError(dklen)
234+
235+
dkey = b''
236+
loop = 1
237+
from_bytes = int.from_bytes
238+
while len(dkey) < dklen:
239+
prev = prf(salt + loop.to_bytes(4))
240+
# endianness doesn't matter here as long to / from use the same
241+
rkey = from_bytes(prev)
242+
for i in range(iterations - 1):
243+
prev = prf(prev)
244+
# rkey = rkey ^ prev
245+
rkey ^= from_bytes(prev)
246+
loop += 1
247+
dkey += rkey.to_bytes(inner.digest_size)
248+
249+
return dkey[:dklen]
250+
251+
try:
252+
# OpenSSL's scrypt requires OpenSSL 1.1+
253+
from _hashlib import scrypt
254+
except ImportError:
255+
pass
256+
257+
258+
def file_digest(fileobj, digest, /, *, _bufsize=2**18):
259+
"""Hash the contents of a file-like object. Returns a digest object.
260+
261+
*fileobj* must be a file-like object opened for reading in binary mode.
262+
It accepts file objects from open(), io.BytesIO(), and SocketIO objects.
263+
The function may bypass Python's I/O and use the file descriptor *fileno*
264+
directly.
265+
266+
*digest* must either be a hash algorithm name as a *str*, a hash
267+
constructor, or a callable that returns a hash object.
268+
"""
269+
# On Linux we could use AF_ALG sockets and sendfile() to archive zero-copy
270+
# hashing with hardware acceleration.
271+
if isinstance(digest, str):
272+
digestobj = new(digest)
273+
else:
274+
digestobj = digest()
275+
276+
if hasattr(fileobj, "getbuffer"):
277+
# io.BytesIO object, use zero-copy buffer
278+
digestobj.update(fileobj.getbuffer())
279+
return digestobj
280+
281+
# Only binary files implement readinto().
282+
if not (
283+
hasattr(fileobj, "readinto")
284+
and hasattr(fileobj, "readable")
285+
and fileobj.readable()
286+
):
287+
raise ValueError(
288+
f"'{fileobj!r}' is not a file-like object in binary reading mode."
289+
)
290+
291+
# binary file, socket.SocketIO object
292+
# Note: socket I/O uses different syscalls than file I/O.
293+
buf = bytearray(_bufsize) # Reusable buffer to reduce allocations.
294+
view = memoryview(buf)
295+
while True:
296+
size = fileobj.readinto(buf)
297+
if size == 0:
298+
break # EOF
299+
digestobj.update(view[:size])
300+
301+
return digestobj
302+
303+
304+
for __func_name in __always_supported:
305+
# try them all, some may not work due to the OpenSSL
306+
# version not supporting that algorithm.
307+
try:
308+
globals()[__func_name] = __get_hash(__func_name)
309+
except ValueError:
310+
import logging
311+
logging.exception('code for hash %s was not found.', __func_name)
312+
313+
314+
# Cleanup locals()
315+
del __always_supported, __func_name, __get_hash
316+
del __py_new, __hash_new, __get_openssl_constructor

0 commit comments

Comments
 (0)