Cython: Crash on type annotations with 'or'

Created on 30 Aug 2019  路  3Comments  路  Source: cython/cython

Not good practice necessarily but how would one go about writing this if possible at all?

Basic example:

def func() -> list or dict: return []

Debug from a complex example:

    def next(self, asObj: bool = False) -> numpy.ndarray or list:
                                            ^
------------------------------------------------------------

src/ipo.py:351:45: Compiler crash in AnalyseExpressionsTransform
File 'Nodes.py', line 436, in analyse_expressions: StatListNode(ipo.py:2:0)
File 'Nodes.py', line 436, in analyse_expressions: StatListNode(ipo.py:337:0)
File 'Nodes.py', line 4578, in analyse_expressions: PyClassDefNode(ipo.py:337:0,
    name = 'Calendar')
File 'Nodes.py', line 436, in analyse_expressions: StatListNode(ipo.py:338:1)
File 'Nodes.py', line 5159, in analyse_expressions: SingleAssignmentNode(ipo.py:351:1)
File 'Nodes.py', line 5279, in analyse_types: SingleAssignmentNode(ipo.py:351:1)
File 'ExprNodes.py', line 9225, in analyse_types: PyCFunctionNode(ipo.py:351:1,
    binding = True,
    is_temp = 1,
    pymethdef_cname = '__pyx_mdef_9ipo_8Calendar_7next',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 9270, in analyse_default_args: PyCFunctionNode(ipo.py:351:1,
    binding = True,
    is_temp = 1,
    pymethdef_cname = '__pyx_mdef_9ipo_8Calendar_7next',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 9358, in analyse_annotation: PyCFunctionNode(ipo.py:351:1,
    binding = True,
    is_temp = 1,
    pymethdef_cname = '__pyx_mdef_9ipo_8Calendar_7next',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 11858, in analyse_types: BoolBinopNode(ipo.py:351:54,
    is_temp = True,
    operator = 'or',
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 664, in analyse_types: BoolBinopResultNode(ipo.py:351:45,
    is_temp = True,
    result_is_used = True,
    use_managed_ref = True)
File 'ExprNodes.py', line 462, in not_implemented: BoolBinopResultNode(ipo.py:351:45,
    is_temp = True,
    result_is_used = True,
    use_managed_ref = True)


Compiler crash traceback from this point on:
  File "/home/misantroop/.local/lib/python3.7/site-packages/Cython/Compiler/ExprNodes.py", line 462, in not_implemented
    (self.__class__.__name__, method_name))
InternalError: Internal compiler error: BoolBinopResultNode.analyse_types not implemented
Traceback (most recent call last):
  File "setup.py", line 13, in <module>
    ext_modules = cythonize("src/*.py", language_level=3),
  File "/home/misantroop/.local/lib/python3.7/site-packages/Cython/Build/Dependencies.py", line 1096, in cythonize
    cythonize_one(*args)
  File "/home/misantroop/.local/lib/python3.7/site-packages/Cython/Build/Dependencies.py", line 1219, in cythonize_one
    raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: src/ipo.py

Error Reporting defect

Most helpful comment

The correct type to use here would be typing.Union[list, dict] (though Cython wouldn't be able to do anything with it). We shouldn't crash, however.

All 3 comments

Use object. There's nothing in common with those two types at a C-level, so Cython can't do any optimisations here. For parameters, you could potentially use fused types.

The correct type to use here would be typing.Union[list, dict] (though Cython wouldn't be able to do anything with it). We shouldn't crash, however.

According to PEP 604, which is being discussed for Python 3.10, the future syntax for this will be list | dict. (But I agree that a crash is not a good way to signal that ;-) )

Was this page helpful?
0 / 5 - 0 ratings