diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 1d77cec4a49..5f97feb5b74 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -3490,8 +3490,12 @@ def create_to_py_utility_code(self, env): def arg_name_part(arg): return "%s%s" % (len(arg.name), punycodify_name(arg.name)) if arg.name else "0" arg_names = [ arg_name_part(arg) for arg in self.args ] - arg_names = "_".join(arg_names) + arg_names = cap_length("_".join(arg_names)) safe_typename = type_identifier(self, pyrex=True) + # Note that the length here is slightly bigger than twice the default cap in + # "cap_length" (since the length is capped in both arg_names and the type_identifier) + # but since this is significantly shorter than compilers should be able to handle, + # that is acceptable. to_py_function = "__Pyx_CFunc_%s_to_py_%s" % (safe_typename, arg_names) for arg in self.args: @@ -5486,8 +5490,8 @@ def type_identifier_from_declaration(decl, scope = None): _type_identifier_cache[key] = safe return safe -def cap_length(s, max_prefix=63, max_len=1024): - if len(s) <= max_prefix: +def cap_length(s, max_len=63): + if len(s) <= max_len: return s hash_prefix = hashlib.sha256(s.encode('ascii')).hexdigest()[:6] return '%s__%s__etc' % (hash_prefix, s[:max_len-17]) diff --git a/Cython/Compiler/Tests/TestTypes.py b/Cython/Compiler/Tests/TestTypes.py index 3d83a95ce26..3209cf5a5eb 100644 --- a/Cython/Compiler/Tests/TestTypes.py +++ b/Cython/Compiler/Tests/TestTypes.py @@ -59,9 +59,9 @@ def test_type_identifier_for_declaration(self): ("const &&&std::vector", "const__fwref__refstd__in_vector"), ("const &&std::vector", "const__fwrefstd__in_vector"), ("void (*func)(int x, float y)", - "975d51__void__lParen__ptrfunc__rParen__lParenint__space_x__comma_float__space_y__rParen__etc"), + "975d51__void__lParen__ptrfunc__rParen__lParenint__spac__etc"), ("float ** (*func)(int x, int[:] y)", - "31883a__float__ptr__ptr__lParen__ptrfunc__rParen__lParenint__space_x__comma_int__lArr__D__rArry__rParen__etc"), + "31883a__float__ptr__ptr__lParen__ptrfunc__rParen__lPar__etc"), ] self._test_escape(function_name, test_data) @@ -71,3 +71,5 @@ def _test_escape(self, func_name, test_data=TEST_DATA): escaped_value = escape(declaration) self.assertEqual(escaped_value, expected, "%s('%s') == '%s' != '%s'" % ( func_name, declaration, escaped_value, expected)) + # test that the length has been successfully capped + self.assertLessEqual(len(escaped_value), 64)