Skip to content

Avoid dramatic changes in the resulting .c file when the input .pyx file changes only slightly. #49

Merged
merged 1 commit into from Sep 7, 2013
+20 −17
View
37 Cython/Compiler/Code.py
@@ -341,10 +341,10 @@ def __init__(self, cname, type):
self.type = type
cython.declare(possible_unicode_identifier=object, possible_bytes_identifier=object,
- nice_identifier=object, find_alphanums=object)
+ replace_identifier=object, find_alphanums=object)
possible_unicode_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
possible_bytes_identifier = re.compile(r"(?![0-9])\w+$".encode('ASCII')).match
-nice_identifier = re.compile(r'\A[a-zA-Z0-9_]+\Z').match
+replace_identifier = re.compile(r'[^a-zA-Z0-9_]+').sub
find_alphanums = re.compile('([a-zA-Z0-9]+)').findall
class StringConst(object):
@@ -457,7 +457,7 @@ class GlobalState(object):
# In time, hopefully the literals etc. will be
# supplied directly instead.
#
- # const_cname_counter int global counter for constant identifiers
+ # const_cname_counters dict global counters for constant identifiers
#
# parts {string:CCodeWriter}
@@ -510,7 +510,7 @@ def __init__(self, writer, emit_linenums=False):
self.emit_linenums = emit_linenums
self.parts = {}
- self.const_cname_counter = 1
+ self.const_cname_counters = {}
self.string_const_index = {}
self.int_const_index = {}
self.py_constants = []
@@ -634,9 +634,9 @@ def get_int_const(self, str_value, longness=False):
c = self.new_int_const(str_value, longness)
return c
- def get_py_const(self, type, prefix='', cleanup_level=None):
+ def get_py_const(self, type, prefix='', cleanup_level=None, value=''):
# create a new Python object constant
- const = self.new_py_const(type, prefix)
+ const = self.new_py_const(type, prefix, value=value)
if cleanup_level is not None \
and cleanup_level <= Options.generate_cleanup_code:
cleanup_writer = self.parts['cleanup_globals']
@@ -685,8 +685,8 @@ def new_int_const(self, value, longness):
self.int_const_index[(value, longness)] = c
return c
- def new_py_const(self, type, prefix=''):
- cname = self.new_const_cname(prefix)
+ def new_py_const(self, type, prefix='', value=''):
+ cname = self.new_const_cname(prefix, value=value)
c = PyObjectConst(cname, type)
self.py_constants.append(c)
return c
@@ -696,12 +696,9 @@ def new_string_const_cname(self, bytes_value, intern=None):
try:
value = bytes_value.decode('ASCII')
except UnicodeError:
- return self.new_const_cname()
+ return self.new_const_cname(value=bytes_value)
- if len(value) < 20 and nice_identifier(value):
- return "%s_%s" % (Naming.const_prefix, value)
- else:
- return self.new_const_cname()
+ return self.new_const_cname(value=value)
def new_int_const_cname(self, value, longness):
if longness:
@@ -710,10 +707,16 @@ def new_int_const_cname(self, value, longness):
cname = cname.replace('-', 'neg_').replace('.','_')
return cname
- def new_const_cname(self, prefix=''):
- n = self.const_cname_counter
- self.const_cname_counter += 1
- return "%s%s%d" % (Naming.const_prefix, prefix, n)
+ def new_const_cname(self, prefix='', value=''):
+ if hasattr(value, 'decode'):
+ value = value.decode('ASCII', 'ignore')
+ value = replace_identifier('_', value)[:32].strip('_')
+ c = self.const_cname_counters
+ c[value] = c.setdefault(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])
def add_cached_builtin_decl(self, entry):
if entry.is_builtin and entry.is_const:
Something went wrong with that request. Please try again.