Skip to content

Commit 2d87577

Browse files
authored
bpo-40286: Remove C implementation of Random.randbytes() (GH-19797)
Remove _random.Random.randbytes(): the C implementation of randbytes(). Implement the method in Python to ease subclassing: randbytes() now directly reuses getrandbits().
1 parent e3dfb9b commit 2d87577

File tree

4 files changed

+10
-87
lines changed

4 files changed

+10
-87
lines changed

Lib/random.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ def setstate(self, state):
192192
## ---- Methods below this point do not need to be overridden when
193193
## ---- subclassing for the purpose of using a different core generator.
194194

195+
## -------------------- bytes methods ---------------------
196+
197+
def randbytes(self, n):
198+
"""Generate n random bytes."""
199+
return self.getrandbits(n * 8).to_bytes(n, 'little')
200+
195201
## -------------------- pickle support -------------------
196202

197203
# Issue 17489: Since __reduce__ was defined to fix #759889 this is no
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove ``_random.Random.randbytes()``: the C implementation of
2+
``randbytes()``. Implement the method in Python to ease subclassing:
3+
``randbytes()`` now directly reuses ``getrandbits()``.

Modules/_randommodule.c

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -513,50 +513,6 @@ _random_Random_getrandbits_impl(RandomObject *self, int k)
513513
return result;
514514
}
515515

516-
/*[clinic input]
517-
518-
_random.Random.randbytes
519-
520-
self: self(type="RandomObject *")
521-
n: Py_ssize_t
522-
/
523-
524-
Generate n random bytes.
525-
[clinic start generated code]*/
526-
527-
static PyObject *
528-
_random_Random_randbytes_impl(RandomObject *self, Py_ssize_t n)
529-
/*[clinic end generated code: output=67a28548079a17ea input=7ba658a24150d233]*/
530-
{
531-
if (n < 0) {
532-
PyErr_SetString(PyExc_ValueError,
533-
"number of bytes must be non-negative");
534-
return NULL;
535-
}
536-
537-
PyObject *bytes = PyBytes_FromStringAndSize(NULL, n);
538-
if (bytes == NULL) {
539-
return NULL;
540-
}
541-
uint8_t *ptr = (uint8_t *)PyBytes_AS_STRING(bytes);
542-
543-
for (; n; ptr += 4, n -= 4) {
544-
uint32_t word = genrand_uint32(self);
545-
#if PY_BIG_ENDIAN
546-
/* Convert to little endian */
547-
word = _Py_bswap32(word);
548-
#endif
549-
if (n < 4) {
550-
/* Drop least significant bits */
551-
memcpy(ptr, (uint8_t *)&word + (4 - n), n);
552-
break;
553-
}
554-
memcpy(ptr, &word, 4);
555-
}
556-
557-
return bytes;
558-
}
559-
560516
static PyObject *
561517
random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
562518
{
@@ -586,7 +542,6 @@ static PyMethodDef random_methods[] = {
586542
_RANDOM_RANDOM_GETSTATE_METHODDEF
587543
_RANDOM_RANDOM_SETSTATE_METHODDEF
588544
_RANDOM_RANDOM_GETRANDBITS_METHODDEF
589-
_RANDOM_RANDOM_RANDBYTES_METHODDEF
590545
{NULL, NULL} /* sentinel */
591546
};
592547

Modules/clinic/_randommodule.c.h

Lines changed: 1 addition & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)