generate 10 000 unique examples for the levenshtein shortcircuit tests import argparse from functools import lrucache import json import os path from random import choices randrange this should be in sync with libtraceback py it s not importing those values because this script is being executed by pythonforregen and not by the intree build of python movecost 2 casecost 1 def substitutioncostcha chb if cha chb return 0 if cha lower chb lower return casecost return movecost lrucachenone def levenshteina b if not a or not b return lena lenb movecost option1 levenshteina 1 b 1 substitutioncosta1 b1 option2 levenshteina 1 b movecost option3 levenshteina b 1 movecost return minoption1 option2 option3 def main parser argparse argumentparserdescriptiondoc parser addargument outputpath metavar file typestr parser addargument overwrite dest overwrite action storeconst consttrue defaultfalse help overwrite an existing test file args parser parseargs outputpath os path realpathargs outputpath if not args overwrite and os path isfileoutputpath printfoutputpath already exists skipping regeneration print to force add overwrite to the invocation of this tool or delete the existing file return examples set create a lot of nonempty examples which should end up with a gausslike distribution for even costs moves and odd costs case substitutions while lenexamples 9990 a joinchoicesabcabc krandrange1 10 b joinchoicesabcabc krandrange1 10 expected levenshteina b examples adda b expected create one empty case each for strings between 0 and 9 in length for i in range10 b joinchoicesabcabc ki expected levenshtein b examples add b expected with openoutputpath w as f json dumpsortedexamples f indent2 if name main main this should be in sync with lib traceback py it s not importing those values because this script is being executed by python_for_regen and not by the in tree build of python create a lot of non empty examples which should end up with a gauss like distribution for even costs moves and odd costs case substitutions create one empty case each for strings between 0 and 9 in length
import argparse
from functools import lru_cache
import json
import os.path
from random import choices, randrange





_MOVE_COST = 2
_CASE_COST = 1


def _substitution_cost(ch_a, ch_b):
    if ch_a == ch_b:
        return 0
    if ch_a.lower() == ch_b.lower():
        return _CASE_COST
    return _MOVE_COST


@lru_cache(None)
def levenshtein(a, b):
    if not a or not b:
        return (len(a) + len(b)) * _MOVE_COST
    option1 = levenshtein(a[:-1], b[:-1]) + _substitution_cost(a[-1], b[-1])
    option2 = levenshtein(a[:-1], b) + _MOVE_COST
    option3 = levenshtein(a, b[:-1]) + _MOVE_COST
    return min(option1, option2, option3)


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('output_path', metavar='FILE', type=str)
    parser.add_argument('--overwrite', dest='overwrite', action='store_const',
                        const=True, default=False,
                        help='overwrite an existing test file')

    args = parser.parse_args()
    output_path = os.path.realpath(args.output_path)
    if not args.overwrite and os.path.isfile(output_path):
        print(f"{output_path} already exists, skipping regeneration.")
        print(
            "To force, add --overwrite to the invocation of this tool or"
            " delete the existing file."
        )
        return

    examples = set()
    
    
    while len(examples) < 9990:
        a = ''.join(choices("abcABC", k=randrange(1, 10)))
        b = ''.join(choices("abcABC", k=randrange(1, 10)))
        expected = levenshtein(a, b)
        examples.add((a, b, expected))
    
    for i in range(10):
        b = ''.join(choices("abcABC", k=i))
        expected = levenshtein("", b)
        examples.add(("", b, expected))
    with open(output_path, "w") as f:
        json.dump(sorted(examples), f, indent=2)


if __name__ == "__main__":
    main()