import itertools


def get_edit_sequences(seq, num_edits, bases=None):
    """Return all nucleotide sequences with a given hamming distance."""

    if num_edits > len(seq):
        raise ValueError('Asked to make make more edits (%d) than the length '
                         'of the sequence (%d nt).' % (num_edits, len(seq)))

    if bases is None:
        bases = set('ACGT')

    length = len(seq)
    all_bases = [bases for i in range(num_edits)]
    seq_list = [nt for nt in seq]
    mismatch = []   
    for comb in itertools.combinations(range(length), num_edits):
        for subs in itertools.product(*all_bases):
            mut = seq_list[:]
            valid = True
            for pos, nt in zip(comb, subs):
                if mut[pos] == nt:
                    valid = False
                    break
                mut[pos] = nt
            if valid:
                mismatch.append(''.join(mut))
    
    return sorted(mismatch)