Delete rand.py (#675)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7b2f4db..213c397 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -14,6 +14,10 @@
 
 - Dropped support for Python 3.3.
   `#677 <https://github.com/pyca/pyopenssl/pull/677>`_
+- Removed the deprecated ``OpenSSL.rand`` module.
+  This is being done ahead of our normal deprecation schedule due to its lack of use and the fact that it was becoming a maintenance burden.
+  ``os.urandom()`` should be used instead.
+  `#675 <https://github.com/pyca/pyopenssl/pull/675>`_
 
 
 Deprecations:
diff --git a/src/OpenSSL/__init__.py b/src/OpenSSL/__init__.py
index b827e3c..810d00d 100644
--- a/src/OpenSSL/__init__.py
+++ b/src/OpenSSL/__init__.py
@@ -5,7 +5,7 @@
 pyOpenSSL - A simple wrapper around the OpenSSL library
 """
 
-from OpenSSL import rand, crypto, SSL
+from OpenSSL import crypto, SSL
 from OpenSSL.version import (
     __author__, __copyright__, __email__, __license__, __summary__, __title__,
     __uri__, __version__,
@@ -13,7 +13,7 @@
 
 
 __all__ = [
-    "SSL", "crypto", "rand",
+    "SSL", "crypto",
 
     "__author__", "__copyright__", "__email__", "__license__", "__summary__",
     "__title__", "__uri__", "__version__",
diff --git a/src/OpenSSL/rand.py b/src/OpenSSL/rand.py
deleted file mode 100644
index e2f6373..0000000
--- a/src/OpenSSL/rand.py
+++ /dev/null
@@ -1,169 +0,0 @@
-"""
-PRNG management routines, thin wrappers.
-"""
-
-import warnings
-from functools import partial
-
-from six import integer_types as _integer_types
-
-from OpenSSL._util import (
-    ffi as _ffi,
-    lib as _lib,
-    exception_from_error_queue as _exception_from_error_queue,
-    path_string as _path_string)
-
-
-warnings.warn(
-    "OpenSSL.rand is deprecated - you should use os.urandom instead",
-    DeprecationWarning, stacklevel=3
-)
-
-
-class Error(Exception):
-    """
-    An error occurred in an :mod:`OpenSSL.rand` API.
-
-    If the current RAND method supports any errors, this is raised when needed.
-    The default method does not raise this when the entropy pool is depleted.
-
-    Whenever this exception is raised directly, it has a list of error messages
-    from the OpenSSL error queue, where each item is a tuple *(lib, function,
-    reason)*. Here *lib*, *function* and *reason* are all strings, describing
-    where and what the problem is.
-
-    See :manpage:`err(3)` for more information.
-    """
-
-
-_raise_current_error = partial(_exception_from_error_queue, Error)
-
-_unspecified = object()
-
-_builtin_bytes = bytes
-
-
-def bytes(num_bytes):
-    """
-    Get some random bytes from the PRNG as a string.
-
-    This is a wrapper for the C function ``RAND_bytes``.
-
-    :param num_bytes: The number of bytes to fetch.
-
-    :return: A string of random bytes.
-    """
-    if not isinstance(num_bytes, _integer_types):
-        raise TypeError("num_bytes must be an integer")
-
-    if num_bytes < 0:
-        raise ValueError("num_bytes must not be negative")
-
-    result_buffer = _ffi.new("unsigned char[]", num_bytes)
-    result_code = _lib.RAND_bytes(result_buffer, num_bytes)
-    if result_code == -1:
-        # TODO: No tests for this code path.  Triggering a RAND_bytes failure
-        # might involve supplying a custom ENGINE?  That's hard.
-        _raise_current_error()
-
-    return _ffi.buffer(result_buffer)[:]
-
-
-def add(buffer, entropy):
-    """
-    Mix bytes from *string* into the PRNG state.
-
-    The *entropy* argument is (the lower bound of) an estimate of how much
-    randomness is contained in *string*, measured in bytes.
-
-    For more information, see e.g. :rfc:`1750`.
-
-    :param buffer: Buffer with random data.
-    :param entropy: The entropy (in bytes) measurement of the buffer.
-
-    :return: :obj:`None`
-    """
-    if not isinstance(buffer, _builtin_bytes):
-        raise TypeError("buffer must be a byte string")
-
-    if not isinstance(entropy, int):
-        raise TypeError("entropy must be an integer")
-
-    # TODO Nothing tests this call actually being made, or made properly.
-    _lib.RAND_add(buffer, len(buffer), entropy)
-
-
-def seed(buffer):
-    """
-    Equivalent to calling :func:`add` with *entropy* as the length of *buffer*.
-
-    :param buffer: Buffer with random data
-
-    :return: :obj:`None`
-    """
-    if not isinstance(buffer, _builtin_bytes):
-        raise TypeError("buffer must be a byte string")
-
-    # TODO Nothing tests this call actually being made, or made properly.
-    _lib.RAND_seed(buffer, len(buffer))
-
-
-def status():
-    """
-    Check whether the PRNG has been seeded with enough data.
-
-    :return: 1 if the PRNG is seeded enough, 0 otherwise.
-    """
-    return _lib.RAND_status()
-
-
-def cleanup():
-    """
-    Erase the memory used by the PRNG.
-
-    This is a wrapper for the C function ``RAND_cleanup``.
-
-    :return: :obj:`None`
-    """
-    # TODO Nothing tests this call actually being made, or made properly.
-    _lib.RAND_cleanup()
-
-
-def load_file(filename, maxbytes=_unspecified):
-    """
-    Read *maxbytes* of data from *filename* and seed the PRNG with it.
-
-    Read the whole file if *maxbytes* is not specified or negative.
-
-    :param filename: The file to read data from (``bytes`` or ``unicode``).
-    :param maxbytes: (optional) The number of bytes to read.    Default is to
-        read the entire file.
-
-    :return: The number of bytes read
-    """
-    filename = _path_string(filename)
-
-    if maxbytes is _unspecified:
-        maxbytes = -1
-    elif not isinstance(maxbytes, int):
-        raise TypeError("maxbytes must be an integer")
-
-    return _lib.RAND_load_file(filename, maxbytes)
-
-
-def write_file(filename):
-    """
-    Write a number of random bytes (currently 1024) to the file *path*.  This
-    file can then be used with :func:`load_file` to seed the PRNG again.
-
-    :param filename: The file to write data to (``bytes`` or ``unicode``).
-
-    :return: The number of bytes written.
-    """
-    filename = _path_string(filename)
-    return _lib.RAND_write_file(filename)
-
-
-# TODO There are no tests for the RAND strings being loaded, whatever that
-# means.
-_lib.ERR_load_RAND_strings()
diff --git a/tests/test_rand.py b/tests/test_rand.py
deleted file mode 100644
index 41a4f27..0000000
--- a/tests/test_rand.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (c) Frederick Dean
-# See LICENSE for details.
-
-"""
-Unit tests for `OpenSSL.rand`.
-"""
-
-import os
-import stat
-import sys
-
-import pytest
-
-from OpenSSL import rand
-
-from .util import NON_ASCII
-
-
-class TestRand(object):
-
-    @pytest.mark.parametrize('args', [
-        (None,),
-        (b"foo",),
-    ])
-    def test_bytes_wrong_args(self, args):
-        """
-        `OpenSSL.rand.bytes` raises `TypeError` if called with a non-`int`
-        argument.
-        """
-        with pytest.raises(TypeError):
-            rand.bytes(*args)
-
-    def test_insufficient_memory(self):
-        """
-        `OpenSSL.rand.bytes` raises `MemoryError` or `OverflowError` if more
-        bytes are requested than will fit in memory.
-        """
-        with pytest.raises((MemoryError, OverflowError)):
-            rand.bytes(sys.maxsize + 1)
-
-    def test_bytes(self):
-        """
-        Verify that we can obtain bytes from rand_bytes() and that they are
-        different each time.  Test the parameter of rand_bytes() for
-        bad values.
-        """
-        b1 = rand.bytes(50)
-        assert len(b1) == 50
-        b2 = rand.bytes(num_bytes=50)  # parameter by name
-        assert b1 != b2  # Hip, Hip, Horay! FIPS complaince
-        b3 = rand.bytes(num_bytes=0)
-        assert len(b3) == 0
-        with pytest.raises(ValueError) as exc:
-            rand.bytes(-1)
-        assert str(exc.value) == "num_bytes must not be negative"
-
-    @pytest.mark.parametrize('args', [
-        (b"foo", None),
-        (None, 3),
-    ])
-    def test_add_wrong_args(self, args):
-        """
-        `OpenSSL.rand.add` raises `TypeError` if called with arguments not of
-        type `str` and `int`.
-        """
-        with pytest.raises(TypeError):
-            rand.add(*args)
-
-    def test_add(self):
-        """
-        `OpenSSL.rand.add` adds entropy to the PRNG.
-        """
-        rand.add(b'hamburger', 3)
-
-    @pytest.mark.parametrize('args', [
-        (None,),
-        (42,),
-    ])
-    def test_seed_wrong_args(self, args):
-        """
-        `OpenSSL.rand.seed` raises `TypeError` if called with
-        a non-`str` argument.
-        """
-        with pytest.raises(TypeError):
-            rand.seed(*args)
-
-    def test_seed(self):
-        """
-        `OpenSSL.rand.seed` adds entropy to the PRNG.
-        """
-        rand.seed(b'milk shake')
-
-    def test_status(self):
-        """
-        `OpenSSL.rand.status` returns `1` if the PRNG has sufficient entropy,
-        `0` otherwise.
-        """
-        # It's hard to know what it is actually going to return.  Different
-        # OpenSSL random engines decide differently whether they have enough
-        # entropy or not.
-        assert rand.status() in (0, 1)
-
-    def test_cleanup(self):
-        """
-        `OpenSSL.rand.cleanup` releases the memory used by the PRNG and
-        returns `None`.
-        """
-        assert rand.cleanup() is None
-
-    @pytest.mark.parametrize('args', [
-        ("foo", None),
-        (None, 1),
-    ])
-    def test_load_file_wrong_args(self, args):
-        """
-        `OpenSSL.rand.load_file` raises `TypeError` when with arguments
-        not of type `str` and `int`.
-        """
-        with pytest.raises(TypeError):
-            rand.load_file(*args)
-
-    @pytest.mark.parametrize('args', [
-        None,
-        1,
-    ])
-    def test_write_file_wrong_args(self, args):
-        """
-        `OpenSSL.rand.write_file` raises `TypeError` when called with
-        a non-`str` argument.
-        """
-        with pytest.raises(TypeError):
-            rand.write_file(*args)
-
-    def _read_write_test(self, path):
-        """
-        Verify that ``rand.write_file`` and ``rand.load_file`` can be used.
-        """
-        # Create the file so cleanup is more straightforward
-        with open(path, "w"):
-            pass
-
-        try:
-            # Write random bytes to a file
-            rand.write_file(path)
-
-            # Verify length of written file
-            size = os.stat(path)[stat.ST_SIZE]
-            assert size == 1024
-
-            # Read random bytes from file
-            rand.load_file(path)
-            rand.load_file(path, 4)  # specify a length
-        finally:
-            # Cleanup
-            os.unlink(path)
-
-    def test_bytes_paths(self, tmpfile):
-        """
-        Random data can be saved and loaded to files with paths specified as
-        bytes.
-        """
-        path = tmpfile
-        path += NON_ASCII.encode(sys.getfilesystemencoding())
-        self._read_write_test(path)
-
-    def test_unicode_paths(self, tmpfile):
-        """
-        Random data can be saved and loaded to files with paths specified as
-        unicode.
-        """
-        path = tmpfile.decode('utf-8') + NON_ASCII
-        self._read_write_test(path)