From 94a59af45cbd1b7ae4354a590b5d235c163ddb1b Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 14 Sep 2013 09:22:51 +0200 Subject: [PATCH] fix cname uniquification for string constants --- Cython/Compiler/Code.py | 18 ++++++++++-------- tests/run/strliterals.pyx | 7 ++++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index 074506d..eae988d 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -847,7 +847,7 @@ class GlobalState(object): # In time, hopefully the literals etc. will be # supplied directly instead. # - # const_cname_counters dict global counters for constant identifiers + # const_cnames_used set global index of unique constant identifiers # # parts {string:CCodeWriter} @@ -903,7 +903,7 @@ class GlobalState(object): self.module_node = module_node # because some utility code generation needs it # (generating backwards-compatible Get/ReleaseBuffer - self.const_cname_counters = {} + self.const_cnames_used = set() self.string_const_index = {} self.pyunicode_ptr_const_index = {} self.int_const_index = {} @@ -1109,12 +1109,14 @@ class GlobalState(object): if hasattr(value, 'decode'): value = value.decode('ASCII', 'ignore') value = replace_identifier('_', value)[:32].strip('_') - c = self.const_cname_counters - c[value] = c.get(value, 0) + 1 - if c[value] == 1: - return "%s%s%s" % (Naming.const_prefix, prefix, value) - else: - return "%s%s%s_%d" % (Naming.const_prefix, prefix, value, c[value]) + used = self.const_cnames_used + counter = 1 + name_suffix = value + while name_suffix in used: + counter += 1 + name_suffix = '%s_%d' % (value, counter) + used.add(name_suffix) + return "%s%s%s" % (Naming.const_prefix, prefix, name_suffix) def add_cached_builtin_decl(self, entry): if entry.is_builtin and entry.is_const: diff --git a/tests/run/strliterals.pyx b/tests/run/strliterals.pyx index 0aaf9fc..cbf760b 100644 --- a/tests/run/strliterals.pyx +++ b/tests/run/strliterals.pyx @@ -148,6 +148,9 @@ __doc__ = ur""" ... sys.version_info[0] >= 3 and ord(str_uescape[-2]) or str_uescape[-12:-1]) True + >>> same_cname + [b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3'] + >>> newlines 'Aaa\n' @@ -165,7 +168,7 @@ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '").replace(u" U'", u" '").replace(u" ur'", u" r'").replace(u" uR'", u" R'").replace(u" Ur'", u" r'").replace(u" UR'", u" R'") else: - __doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'") + __doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'").replace(u"[b'", u"['") s1 = "abc\x11" s2 = r"abc\x11" @@ -191,6 +194,8 @@ uresc = ur'\12\'\"\\' bytes_uescape = b'\u1234\U12345678\u\u1\u12\uX' str_uescape = '\u0063\U00012345\N{SNOWMAN}\x42' +same_cname = [b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3'] + newlines = "Aaa\n" # T640, long literals with escapes -- 2.7.4