# Buggy code
def _shred_file_custom(self, tmp_path):
    """ "Destroy a file, when shred (core-utils) is not available

    Unix `shred' destroys files "so that they can be recovered only with great difficulty with
    specialised hardware, if at all". It is based on the method from the paper
    "Secure Deletion of Data from Magnetic and Solid-State Memory",
    Proceedings of the Sixth USENIX Security Symposium (San Jose, California, July 22-25, 1996).

    We do not go to that length to re-implement shred in Python; instead, overwriting with a block
    of random data should suffice.

    See https://github.com/ansible/ansible/pull/13700 .
    """

    file_len = os.path.getsize(tmp_path)
    max_chunk_len = min(1024 * 1024 * 2, file_len)

    passes = 3
    with open(tmp_path, "wb") as fh:
        for _ in range(passes):
            fh.seek(0, 0)
            # get a random chunk of data, each pass with other length
            chunk_len = random.randint(max_chunk_len / 2, max_chunk_len)
            data = os.urandom(chunk_len)

            for _ in range(0, file_len // chunk_len):
                fh.write(data)
            fh.write(data[: file_len % chunk_len])

            assert (
                fh.tell() == file_len
            )  # FIXME remove this assert once we have unittests to check its accuracy
            os.fsync(fh)


# Traceback (ValueError)
Unexpected Exception: non-integer arg 1 for randrange()
the full traceback was:

Traceback (most recent call last):
File "/Users/guy/Library/ansible/bin/ansible-vault", line 85, in <module>
sys.exit(cli.run())
File "/Users/guy/Library/ansible/lib/ansible/cli/vault.py", line 119, in run
self.execute()
File "/Users/guy/Library/ansible/lib/ansible/cli/__init__.py", line 99, in execute
fn()
File "/Users/guy/Library/ansible/lib/ansible/cli/vault.py", line 155, in execute_edit
self.editor.edit_file(f)
File "/Users/guy/Library/ansible/lib/ansible/parsing/vault/__init__.py", line 355, in edit_file
self._edit_file_helper(filename, existing_data=plaintext, force_save=False)
File "/Users/guy/Library/ansible/lib/ansible/parsing/vault/__init__.py", line 306, in _edit_file_helper
self._shred_file(tmp_path)
File "/Users/guy/Library/ansible/lib/ansible/parsing/vault/__init__.py", line 282, in _shred_file
self._shred_file_custom(tmp_path)
File "/Users/guy/Library/ansible/lib/ansible/parsing/vault/__init__.py", line 246, in _shred_file_custom
chunk_len = random.randint(max_chunk_len/2, max_chunk_len)
File "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 242, in randint
return self.randrange(a, b+1)
File "/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 187, in randrange
raise ValueError, "non-integer arg 1 for randrange()"
ValueError: non-integer arg 1 for randrange()

# Fixed code
def _shred_file_custom(self, tmp_path):
    """ "Destroy a file, when shred (core-utils) is not available

    Unix `shred' destroys files "so that they can be recovered only with great difficulty with
    specialised hardware, if at all". It is based on the method from the paper
    "Secure Deletion of Data from Magnetic and Solid-State Memory",
    Proceedings of the Sixth USENIX Security Symposium (San Jose, California, July 22-25, 1996).

    We do not go to that length to re-implement shred in Python; instead, overwriting with a block
    of random data should suffice.

    See https://github.com/ansible/ansible/pull/13700 .
    """

    file_len = os.path.getsize(tmp_path)
    max_chunk_len = min(1024 * 1024 * 2, file_len)

    passes = 3
    with open(tmp_path, "wb") as fh:
        for _ in range(passes):
            fh.seek(0, 0)
            # get a random chunk of data, each pass with other length
            chunk_len = random.randint(max_chunk_len // 2, max_chunk_len)
            data = os.urandom(chunk_len)

            for _ in range(0, file_len // chunk_len):
                fh.write(data)
            fh.write(data[: file_len % chunk_len])

            assert (
                fh.tell() == file_len
            )  # FIXME remove this assert once we have unittests to check its accuracy
            os.fsync(fh)