New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

struct-based type checking of structured numpy arrays is impossible if the dtype contains "object" #1841

Open
sjdv1982 opened this Issue Aug 24, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@sjdv1982

sjdv1982 commented Aug 24, 2017

IPython notebook attached as .zip
cython-bug-notebook.zip

%load_ext Cython
%%cython -a
import numpy as np
cimport numpy as np
from cpython.ref cimport PyObject

cdef struct Coordinate:
    float x
    float y
    float z

cdef struct Test:
    PyObject *coor #Coordinate array
    float a
    float b

dCoordinate0 = [('x', '<f4'), ('y', '<f4'), ('z', '<f4')]
dCoordinate = np.dtype(dCoordinate0, align=True)

dTest0 =[('coor', object), ('a', '<f4'), ('b', '<f4')]
dTest = np.dtype(dTest0, align=True)

def print_test():
    cdef Coordinate[:] coor2
    coor = np.zeros((1), dtype=dCoordinate)
    coor["x"] = 999
    coor2 = coor
    print(coor2[0].x)
    print("success test 1")
    
    cdef np.ndarray[Test,ndim=1] test2
    test = np.zeros((1), dtype=dTest)
    test["coor"] = coor
    test2 = test
    coor3 = <object> test2[0].coor
    print(coor3)
    print("success test 2")
    
  
---------------------------------------------------------------------------

AssertionError                            Traceback (most recent call last)

<ipython-input-9-2e531d306b24> in <module>()
----> 1 get_ipython().run_cell_magic('cython', '-a', 'import numpy as np\ncimport numpy as np\nfrom cpython.ref cimport PyObject\n\ncdef struct Coordinate:\n    float x\n    float y\n    float z\n\ncdef struct Test:\n    PyObject *coor #Coordinate array\n    float a\n    float b\n\ndCoordinate0 = [(\'x\', \'<f4\'), (\'y\', \'<f4\'), (\'z\', \'<f4\')]\ndCoordinate = np.dtype(dCoordinate0, align=True)\n\ndTest0 =[(\'coor\', object), (\'a\', \'<f4\'), (\'b\', \'<f4\')]\ndTest = np.dtype(dTest0, align=True)\n\ndef print_test():\n    cdef Coordinate[:] coor2\n    coor = np.zeros((1), dtype=dCoordinate)\n    coor["x"] = 999\n    coor2 = coor\n    print(coor2[0].x)\n    print("success test 1")\n    \n    cdef np.ndarray[Test,ndim=1] test2\n    test = np.zeros((1), dtype=dTest)\n    test["coor"] = coor\n    test2 = test\n    coor3 = <object> test2[0].coor\n    print(coor3)\n    print("success test 2")\n    \n  ')


/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2113             magic_arg_s = self.var_expand(line, stack_depth)
   2114             with self.builtin_trap:
-> 2115                 result = fn(magic_arg_s, cell)
   2116             return result
   2117 


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


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


/usr/local/lib/python3.5/dist-packages/Cython/Build/IpythonMagic.py in cython(self, line, cell)
    282                 elif sys.version_info[0] > 2:
    283                     opts['language_level'] = 3
--> 284                 build_extension.extensions = cythonize([extension], **opts)
    285             except CompileError:
    286                 return


/usr/local/lib/python3.5/dist-packages/Cython/Build/Dependencies.py in cythonize(module_list, exclude, nthreads, aliases, quiet, force, language, exclude_failures, **options)
    932     if not nthreads:
    933         for args in to_compile:
--> 934             cythonize_one(*args)
    935 
    936     if exclude_failures:


/usr/local/lib/python3.5/dist-packages/Cython/Build/Dependencies.py in cythonize_one(pyx_file, c_file, fingerprint, quiet, options, raise_on_failure, embedded_metadata, progress)
   1037     any_failures = 0
   1038     try:
-> 1039         result = compile([pyx_file], options)
   1040         if result.num_errors > 0:
   1041             any_failures = 1


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Main.py in compile(source, options, full_module_name, **kwds)
    684         return compile_single(source, options, full_module_name)
    685     else:
--> 686         return compile_multiple(source, options)
    687 
    688 #------------------------------------------------------------------------


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Main.py in compile_multiple(sources, options)
    662                     sys.stderr.write("Compiling %s\n" % source)
    663 
--> 664                 result = run_pipeline(source, options, context=context)
    665                 results.add(source, result)
    666                 # Compiling multiple sources in one context doesn't quite


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Main.py in run_pipeline(source, options, full_module_name, context)
    492 
    493     context.setup_errors(options, result)
--> 494     err, enddata = Pipeline.run_pipeline(pipeline, source)
    495     context.teardown_errors(err, options, result)
    496     return result


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Pipeline.py in run_pipeline(pipeline, source, printtree)
    338                     if not printtree and isinstance(phase, PrintTree):
    339                         continue
--> 340                     data = phase(data)
    341                     if DebugFlags.debug_verbose_pipeline:
    342                         print("    %.3f seconds" % (time() - t))


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Pipeline.py in generate_pyx_code_stage(module_node)
     51 def generate_pyx_code_stage_factory(options, result):
     52     def generate_pyx_code_stage(module_node):
---> 53         module_node.process_implementation(options, result)
     54         result.compilation_source = module_node.compilation_source
     55         return result


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/ModuleNode.py in process_implementation(self, options, result)
    135         self.find_referenced_modules(env, self.referenced_modules, {})
    136         self.sort_cdef_classes(env)
--> 137         self.generate_c_code(env, options, result)
    138         self.generate_h_code(env, options, result)
    139         self.generate_api_code(env, options, result)


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/ModuleNode.py in generate_c_code(self, env, options, result)
    363         # generate normal variable and function definitions
    364         self.generate_variable_definitions(env, code)
--> 365         self.body.generate_function_definitions(env, code)
    366         code.mark_pos(None)
    367         self.generate_typeobj_definitions(env, code)


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
    434         #print "StatListNode.generate_function_definitions" ###
    435         for stat in self.stats:
--> 436             stat.generate_function_definitions(env, code)
    437 
    438     def generate_execution_code(self, code):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
    434         #print "StatListNode.generate_function_definitions" ###
    435         for stat in self.stats:
--> 436             stat.generate_function_definitions(env, code)
    437 
    438     def generate_execution_code(self, code):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
   3064             self.py_wrapper.func_cname = self.entry.func_cname
   3065             self.py_wrapper.generate_function_definitions(env, code)
-> 3066         FuncDefNode.generate_function_definitions(self, env, code)
   3067 
   3068     def generate_function_header(self, code, with_pymethdef, proto_only=0):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_function_definitions(self, env, code)
   1930         # ----- Function body -----
   1931         # -------------------------
-> 1932         self.generate_function_body(env, code)
   1933 
   1934         code.mark_pos(self.pos, trace=False)


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_function_body(self, env, code)
   1697 
   1698     def generate_function_body(self, env, code):
-> 1699         self.body.generate_execution_code(code)
   1700 
   1701     def generate_function_definitions(self, env, code):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
    440         for stat in self.stats:
    441             code.mark_pos(stat.pos)
--> 442             stat.generate_execution_code(code)
    443 
    444     def annotate(self, code):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_execution_code(self, code)
   4791         code.mark_pos(self.pos)
   4792         self.generate_rhs_evaluation_code(code)
-> 4793         self.generate_assignment_code(code)
   4794 
   4795 


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Nodes.py in generate_assignment_code(self, code, overloaded_assignment)
   5088                 exception_value=self.exception_value)
   5089         else:
-> 5090             self.lhs.generate_assignment_code(self.rhs, code)
   5091 
   5092     def generate_function_definitions(self, env, code):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/ExprNodes.py in generate_assignment_code(self, rhs, code, overloaded_assignment, exception_check, exception_value)
   2178                 # variables that the acquired buffer info is stored to is allocated
   2179                 # per entry and coupled with it.
-> 2180                 self.generate_acquire_buffer(rhs, code)
   2181             assigned = False
   2182             if self.type.is_pyobject:


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/ExprNodes.py in generate_acquire_buffer(self, rhs, code)
   2260         Buffer.put_assign_to_buffer(self.result(), rhstmp, self.entry,
   2261                                     is_initialized=not self.lhs_of_first_assignment,
-> 2262                                     pos=self.pos, code=code)
   2263 
   2264         if not pretty_rhs:


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Buffer.py in put_assign_to_buffer(lhs_cname, rhs_cname, buf_entry, is_initialized, pos, code)
    373     code.putln("__Pyx_BufFmt_StackElem __pyx_stack[%d];" % buffer_type.dtype.struct_nesting_depth())
    374 
--> 375     getbuffer = get_getbuffer_call(code, "%s", buffer_aux, buffer_type) # fill in object below
    376 
    377     if is_initialized:


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Buffer.py in get_getbuffer_call(code, obj_cname, buffer_aux, buffer_type)
    343     pybuffernd_struct = buffer_aux.buflocal_nd_var.cname
    344 
--> 345     dtype_typeinfo = get_type_information_cname(code, buffer_type.dtype)
    346 
    347     return ("__Pyx_GetBufferAndValidate(&%(pybuffernd_struct)s.rcbuffer->pybuffer, "


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Buffer.py in get_type_information_cname(code, dtype, maxdepth)
    677             assert len(fields) > 0
    678             types = [get_type_information_cname(code, f.type, maxdepth - 1)
--> 679                      for f in fields]
    680             typecode.putln("static __Pyx_StructField %s[] = {" % structinfo_name, safe=True)
    681             for f, typeinfo in zip(fields, types):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Buffer.py in <listcomp>(.0)
    677             assert len(fields) > 0
    678             types = [get_type_information_cname(code, f.type, maxdepth - 1)
--> 679                      for f in fields]
    680             typecode.putln("static __Pyx_StructField %s[] = {" % structinfo_name, safe=True)
    681             for f, typeinfo in zip(fields, types):


/usr/local/lib/python3.5/dist-packages/Cython/Compiler/Buffer.py in get_type_information_cname(code, dtype, maxdepth)
    709 
    710         else:
--> 711             assert False, dtype
    712 
    713         typeinfo = ('static __Pyx_TypeInfo %s = '


AssertionError: PyObject *
print_test()
999.0
success test 1

sjdv1982 added a commit to sjdv1982/cython that referenced this issue Aug 24, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment