def polyfill_random(generator, size, dtype='float32', out=None):
    """Sample random floats from a generator in different numpy versions.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to sample from. Both ``RandomState`` and ``Generator``
        support ``random()``, but with different interfaces.

    size : int or tuple of ints, optional
        See :func:`numpy.random.Generator.random`.

    dtype : {str, dtype}, optional
        See :func:`numpy.random.Generator.random`.

    out : ndarray, optional
        See :func:`numpy.random.Generator.random`.


    Returns
    -------
    float or ndarray of floats
        See :func:`numpy.random.Generator.random`.

    """
    if hasattr(generator, 'random_sample'):
        result = generator.random_sample(size=size).astype(dtype)
        if out is not None:
            assert out.dtype.name == result.dtype.name, "Expected out array to have the same dtype as random_sample()'s result array. Got %s (out) and %s (result) instead." % (
                out.dtype.name, result.dtype.name)
            out[...] = result
        return result
    return generator.random(size=size, dtype=dtype, out=out)
