Cython:ctypedef char数组引发模糊错误

时间:2018-07-24 13:04:23

标签: arrays cython

为什么这样做:

In [17]: %%cython -f
    ...: from libc.string cimport memcpy
    ...:
    ...: DEF KLEN = 5
    ...: DEF TRP_KLEN = KLEN * 3
    ...:
    ...: cdef:
    ...:     unsigned char k[KLEN]
    ...:     unsigned char kk[TRP_KLEN]
    ...: kk = bytearray(b'12345abcde!@#$%')
    ...: memcpy(&k, &kk[5], KLEN)
    ...: print(k)
b'abcde'

与此同时:

In [16]: %%cython -f
    ...: from libc.string cimport memcpy
    ...: 
    ...: DEF KLEN = 5
    ...: DEF TRP_KLEN = KLEN * 3
    ...: ctypedef unsigned char SingleKey[KLEN]
    ...: ctypedef unsigned char TripleKey[TRP_KLEN]
    ...: 
    ...: cdef:
    ...:     SingleKey k
    ...:     TripleKey kk
    ...: kk = bytearray(b'12345abcde!@#$%')
    ...: memcpy(&k, &kk[5], KLEN)
    ...: print(k)

抛出一个晦涩的错误,它没有直接提及我的代码:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-16-a4bb608248b0> in <module>()
----> 1 get_ipython().run_cell_magic('cython', '-f', "from libc.string cimport memcpy\n\nDEF KLEN = 5\nDEF TRP_KLEN = KLEN * 3\nctypedef unsigned char SingleKey[KLEN]\nctypedef unsigned char DoubleKey[TRP_KLEN]\n\ncdef:\n    SingleKey k[KLEN]\n    DoubleKey kk[TRP_KLEN]\nkk = bytearray(b'12345abcde!@#$%')\nmemcpy(&k, &kk[5], KLEN)\nprint(k)")

/usr/lib/python3.6/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2165             magic_arg_s = self.var_expand(line, stack_depth)
   2166             with self.builtin_trap:
-> 2167                 result = fn(magic_arg_s, cell)
   2168             return result
   2169

<decorator-gen-118> in cython(self, line, cell)

/usr/lib/python3.6/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
    185     # but it's overkill for just that one bit of state.
    186     def magic_deco(arg):
--> 187         call = lambda f, *a, **k: f(*a, **k)
    188
    189         if callable(arg):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Build/IpythonMagic.py in cython(self, line, cell)
    318         extension = None
    319         if need_cythonize:
--> 320             extensions = self._cythonize(module_name, code, lib_dir, args, quiet=args.quiet)
    321             assert len(extensions) == 1
    322             extension = extensions[0]

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Build/IpythonMagic.py in _cythonize(self, module_name, code, lib_dir, args, quiet)
    426             elif sys.version_info[0] >= 3:
    427                 opts['language_level'] = 3
--> 428             return cythonize([extension], **opts)
    429         except CompileError:
    430             return None

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Build/Dependencies.py in cythonize(module_list, exclude, nthreads, aliases, quiet, force, language, exclude_failures, **options)
   1024     if not nthreads:
   1025         for args in to_compile:
-> 1026             cythonize_one(*args)
   1027
   1028     if exclude_failures:

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Build/Dependencies.py in cythonize_one(pyx_file, c_file, fingerprint, quiet, options, raise_on_failure, embedded_metadata, full_module_name, progress)
   1127     any_failures = 0
   1128     try:
-> 1129         result = compile_single(pyx_file, options, full_module_name=full_module_name)
   1130         if result.num_errors > 0:
   1131             any_failures = 1

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Main.py in compile_single(source, options, full_module_name)
    647     recursion.
    648     """
--> 649     return run_pipeline(source, options, full_module_name)
    650
    651

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Main.py in run_pipeline(source, options, full_module_name, context)
    497
    498     context.setup_errors(options, result)
--> 499     err, enddata = Pipeline.run_pipeline(pipeline, source)
    500     context.teardown_errors(err, options, result)
    501     return result

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Pipeline.py in run_pipeline(pipeline, source, printtree)
    352                             exec("def %s(phase, data): return phase(data)" % phase_name, exec_ns)
    353                             run = _pipeline_entry_points[phase_name] = exec_ns[phase_name]
--> 354                     data = run(phase, data)
    355                     if DebugFlags.debug_verbose_pipeline:
    356                         print("    %.3f seconds" % (time() - t))

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Pipeline.py in run(phase, data)
    332
    333     def run(phase, data):
--> 334         return phase(data)
    335
    336     error = None

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Pipeline.py in generate_pyx_code_stage(module_node)
     50 def generate_pyx_code_stage_factory(options, result):
     51     def generate_pyx_code_stage(module_node):
---> 52         module_node.process_implementation(options, result)
     53         result.compilation_source = module_node.compilation_source
     54         return result

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/ModuleNode.py in process_implementation(self, options, result)
    140         self.find_referenced_modules(env, self.referenced_modules, {})
    141         self.sort_cdef_classes(env)
--> 142         self.generate_c_code(env, options, result)
    143         self.generate_h_code(env, options, result)
    144         self.generate_api_code(env, options, result)

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/ModuleNode.py in generate_c_code(self, env, options, result)
    376         # generate normal variable and function definitions
    377         self.generate_variable_definitions(env, code)
--> 378         self.body.generate_function_definitions(env, code)
    379         code.mark_pos(None)
    380         self.generate_typeobj_definitions(env, code)

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
    436         #print "StatListNode.generate_function_definitions" ###
    437         for stat in self.stats:
--> 438             stat.generate_function_definitions(env, code)
    439
    440     def generate_execution_code(self, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
   9242                 entry.cname = cname
   9243
-> 9244         self.node.generate_function_definitions(env, code)
   9245
   9246     def generate_execution_code(self, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
   1974         # ----- Function body -----
   1975         # -------------------------
-> 1976         self.generate_function_body(env, code)
   1977
   1978         code.mark_pos(self.pos, trace=False)

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_function_body(self, env, code)
   1736
   1737     def generate_function_body(self, env, code):
-> 1738         self.body.generate_execution_code(code)
   1739
   1740     def generate_function_definitions(self, env, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
    442         for stat in self.stats:
    443             code.mark_pos(stat.pos)
--> 444             stat.generate_execution_code(code)
    445
    446     def annotate(self, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
   6185         for i, if_clause in enumerate(self.if_clauses):
   6186             self._set_branch_hint(if_clause, if_clause.body)
-> 6187             if_clause.generate_execution_code(code, end_label, is_last=i == last)
   6188         if self.else_clause:
   6189             code.mark_pos(self.else_clause.pos)

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code, end_label, is_last)
   6247         self.condition.generate_disposal_code(code)
   6248         self.condition.free_temps(code)
-> 6249         self.body.generate_execution_code(code)
   6250         code.mark_pos(self.pos, trace=False)
   6251         if not (is_last or self.body.is_terminator):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
    442         for stat in self.stats:
    443             code.mark_pos(stat.pos)
--> 444             stat.generate_execution_code(code)
    445
    446     def annotate(self, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/UtilNodes.py in generate_execution_code(self, code)
    324     def generate_execution_code(self, code):
    325         self.setup_temp_expr(code)
--> 326         self.body.generate_execution_code(code)
    327         self.teardown_temp_expr(code)
    328

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
   6605         self.item.generate_evaluation_code(code)
   6606         self.target.generate_assignment_code(self.item, code)
-> 6607         self.body.generate_execution_code(code)
   6608         code.mark_pos(self.pos)
   6609         code.put_label(code.continue_label)

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
    442         for stat in self.stats:
    443             code.mark_pos(stat.pos)
--> 444             stat.generate_execution_code(code)
    445
    446     def annotate(self, code):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
   5100     def generate_execution_code(self, code):
   5101         code.mark_pos(self.pos)
-> 5102         self.generate_rhs_evaluation_code(code)
   5103         self.generate_assignment_code(code)
   5104

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/Nodes.py in generate_rhs_evaluation_code(self, code)
   5387
   5388     def generate_rhs_evaluation_code(self, code):
-> 5389         self.rhs.generate_evaluation_code(code)
   5390
   5391     def generate_assignment_code(self, code, overloaded_assignment=False):

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/ExprNodes.py in generate_evaluation_code(self, code)
    718             self.allocate_temp_result(code)
    719
--> 720         self.generate_result_code(code)
    721         if self.is_temp and not (self.type.is_string or self.type.is_pyunicode_ptr):
    722             # If we are temp we do not need to wait until this node is disposed

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/ExprNodes.py in generate_result_code(self, code)
  13135
  13136         code.putln(self.type.from_py_call_code(
> 13137             self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
  13138         if self.type.is_pyobject:
  13139             code.put_gotref(self.py_result())

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/PyrexTypes.py in from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function, error_condition)
    512             source_code, result_code, error_pos, code,
    513             from_py_function or self.from_py_function,
--> 514             error_condition or self.error_condition(result_code)
    515         )
    516

~/code/lsup/virtualenv/lib/python3.6/site-packages/Cython/Compiler/PyrexTypes.py in from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function, error_condition)
   2481     def from_py_call_code(self, source_code, result_code, error_pos, code,
   2482                           from_py_function=None, error_condition=None):
-> 2483         assert not error_condition, '%s: %s' % (error_pos, error_condition)
   2484         call_code = "%s(%s, %s, %s)" % (
   2485             from_py_function or self.from_py_function,

AssertionError: (<StringSourceDescriptor:carray.from_py>, 87, 19): (!__pyx_t_11) && PyErr_Occurred()

这在我的1000多行程序中尤其成问题,在那里我不得不找出导致问题的原因。删除已分配的char数组的所有ctypedefs均会删除该错误,但我想知道是什么引起的。

谢谢。

更新

注意:这不是一个以NUL终止的字符串,而是一个字节序列,该字节序列可能在任何地方都有NUL。这就是为什么我使用memcpy而不是字符串函数或常规=分配的原因。

0 个答案:

没有答案