JHSN
JHSN

Reputation: 91

Python random.Random(bytearray) TypeError: unhashable type

In Python3, random.Random(seed) allows to seed using a bytearray.

class Random(_random.Random):
    ...
    def __init__(self, x=None):
        self.seed(x)
        ...

    def seed(self, a=None, version=2):
        ...
        if version == 2 and isinstance(a, (str, bytes, bytearray)):
            if isinstance(a, str):
                a = a.encode()
            a += _sha512(a).digest()
            a = int.from_bytes(a, 'big')
        ...

When you try

>>> random.Random().__init__(bytearray([1, 2, 3]))

or

>>> r = random.Random()
>>> r.seed(bytearray([1, 2, 3]))

it will work without exception.

But when you try this, the result is inconsistent.

>>> random.Random(bytearray([1, 2, 3]))
TypeError: unhashable type: 'bytearray'

I compiled and debuged python 3.7.0 binary, when tried to init a PRNG with a bytearray, it will invoke random_seed method in Modules/_randommodule.c and directly raise a typeerror here. Why?

Upvotes: 8

Views: 875

Answers (2)

JHSN
JHSN

Reputation: 91

BlackJack's answer enlightened me. I read the C source code of the _random.Random.__new__ method carefully.

The _random.Random.__new__ method (random_new in C) invokes _random.Random.seed method (random_seed in C) with the same arguments. If the args in the random_seed function contains a non-int object as a seed, it will try to get the hash value of the object. So it will raise a type error when the object is a bytearray.

Thus, _random.Random doesn't specially handle seeding with a bytearray but its subclass random.Random did, which seems like an incompatible python bug.

Upvotes: 1

BlackJack
BlackJack

Reputation: 4689

The exception doesn't come from the Random.__init__() method but from the __new__() method, which is called before __init__():

>>> random.Random.__new__(random.Random, bytearray([1,2,3]))
TypeError: unhashable type: 'bytearray'
>>> random.Random.__new__(random.Random, bytes([1,2,3]))
<random.Random at 0x1b0cd78>

Upvotes: 2

Related Questions