# HG changeset patch # User Paul Boddie # Date 1481126526 -3600 # Node ID 93eb0a0ab92fa64d00e751bd8e5f8db9ee753610 # Parent 5c51c957f560a0de682f41928a833ae5996cc6c4 Detect and avoid encoded name conflicts. diff -r 5c51c957f560 -r 93eb0a0ab92f encoders.py --- a/encoders.py Wed Dec 07 17:00:12 2016 +0100 +++ b/encoders.py Wed Dec 07 17:02:06 2016 +0100 @@ -344,6 +344,10 @@ return "__constvalue%d" % n +# Track all encoded paths, detecting and avoiding conflicts. + +all_encoded_paths = {} + def encode_path(path): "Encode 'path' as an output program object, translating special symbols." @@ -351,7 +355,26 @@ if path in reserved_words: return "__%s" % path else: - return path.replace("#", "__").replace("$", "__").replace(".", "_") + part_encoded = path.replace("#", "__").replace("$", "__") + encoded = part_encoded.replace(".", "_") + + # Test for a conflict with the encoding of a different path, re-encoding + # if necessary. + + previous = all_encoded_paths.get(encoded) + replacement = "_" + + while previous: + if path == previous: + return encoded + replacement += "_" + encoded = part_encoded.replace(".", replacement) + previous = all_encoded_paths.get(encoded) + + # Store any new or re-encoded path. + + all_encoded_paths[encoded] = path + return encoded def encode_predefined_reference(path): diff -r 5c51c957f560 -r 93eb0a0ab92f tests/name_encoding.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/name_encoding.py Wed Dec 07 17:02:06 2016 +0100 @@ -0,0 +1,14 @@ +class C: + def f(self): + return 1 + +def C_f(): + return 2 + +def C__f(): + return 3 + +c = C() +print c.f() +print C_f() +print C__f()