Commit f599da79 authored by Stefan Behnel's avatar Stefan Behnel

make 'object' predictably the last fallback option for fused typed arguments

parent 9e9b474a
...@@ -78,6 +78,10 @@ Bugs fixed ...@@ -78,6 +78,10 @@ Bugs fixed
* Language level 3 did not enable true division (a.k.a. float division) * Language level 3 did not enable true division (a.k.a. float division)
for integer operands. for integer operands.
* Functions with fused argument types that included a generic 'object'
fallback could end up using that fallback also for other explicitly
listed object types.
* Relative cimports could accidentally fall back to trying an absolute * Relative cimports could accidentally fall back to trying an absolute
cimport on failure. cimport on failure.
......
...@@ -268,8 +268,8 @@ class FusedCFuncDefNode(StatListNode): ...@@ -268,8 +268,8 @@ class FusedCFuncDefNode(StatListNode):
) )
pyx_code.put_chunk( pyx_code.put_chunk(
u""" u"""
elif isinstance(arg, {{py_type_name}}): if isinstance(arg, {{py_type_name}}):
dest_sig[{{dest_sig_idx}}] = '{{specialized_type_name}}' dest_sig[{{dest_sig_idx}}] = '{{specialized_type_name}}'; break
""") """)
def _dtype_name(self, dtype): def _dtype_name(self, dtype):
...@@ -394,7 +394,6 @@ class FusedCFuncDefNode(StatListNode): ...@@ -394,7 +394,6 @@ class FusedCFuncDefNode(StatListNode):
to match the format string. to match the format string.
""" """
# The first thing to find a match in this loop breaks out of the loop # The first thing to find a match in this loop breaks out of the loop
if pyx_code.indenter(u"while 1:"):
pyx_code.put_chunk( pyx_code.put_chunk(
u""" u"""
if ndarray is not None: if ndarray is not None:
...@@ -424,10 +423,6 @@ class FusedCFuncDefNode(StatListNode): ...@@ -424,10 +423,6 @@ class FusedCFuncDefNode(StatListNode):
self._buffer_parse_format_string_check( self._buffer_parse_format_string_check(
pyx_code, decl_code, specialized_type, env) pyx_code, decl_code, specialized_type, env)
pyx_code.putln(self.no_match)
pyx_code.putln("break")
pyx_code.dedent()
def _buffer_declarations(self, pyx_code, decl_code, all_buffer_types): def _buffer_declarations(self, pyx_code, decl_code, all_buffer_types):
""" """
If we have any buffer specializations, write out some variable If we have any buffer specializations, write out some variable
...@@ -492,17 +487,21 @@ class FusedCFuncDefNode(StatListNode): ...@@ -492,17 +487,21 @@ class FusedCFuncDefNode(StatListNode):
# specialized_types.sort() # specialized_types.sort()
seen_py_type_names = set() seen_py_type_names = set()
normal_types, buffer_types = [], [] normal_types, buffer_types = [], []
has_object_fallback = False
for specialized_type in specialized_types: for specialized_type in specialized_types:
py_type_name = specialized_type.py_type_name() py_type_name = specialized_type.py_type_name()
if py_type_name: if py_type_name:
if py_type_name in seen_py_type_names: if py_type_name in seen_py_type_names:
continue continue
seen_py_type_names.add(py_type_name) seen_py_type_names.add(py_type_name)
if py_type_name == 'object':
has_object_fallback = True
else:
normal_types.append(specialized_type) normal_types.append(specialized_type)
elif specialized_type.is_buffer or specialized_type.is_memoryviewslice: elif specialized_type.is_buffer or specialized_type.is_memoryviewslice:
buffer_types.append(specialized_type) buffer_types.append(specialized_type)
return normal_types, buffer_types return normal_types, buffer_types, has_object_fallback
def _unpack_argument(self, pyx_code): def _unpack_argument(self, pyx_code):
pyx_code.put_chunk( pyx_code.put_chunk(
...@@ -593,18 +592,21 @@ class FusedCFuncDefNode(StatListNode): ...@@ -593,18 +592,21 @@ class FusedCFuncDefNode(StatListNode):
default_idx=default_idx, default_idx=default_idx,
) )
normal_types, buffer_types = self._split_fused_types(arg) normal_types, buffer_types, has_object_fallback = self._split_fused_types(arg)
self._unpack_argument(pyx_code) self._unpack_argument(pyx_code)
# we need an 'if' to allow the following elif/else branches # 'unrolled' loop, first match breaks out of it
pyx_code.putln("if 0: pass") if pyx_code.indenter("while 1:"):
if normal_types: if normal_types:
self._fused_instance_checks(normal_types, pyx_code, env) self._fused_instance_checks(normal_types, pyx_code, env)
if pyx_code.indenter("else:"):
if buffer_types: if buffer_types:
self._buffer_checks(buffer_types, pyx_code, decl_code, env) self._buffer_checks(buffer_types, pyx_code, decl_code, env)
if has_object_fallback:
pyx_code.context.update(specialized_type_name='object')
pyx_code.putln(self.match)
else: else:
pyx_code.putln(self.no_match) pyx_code.putln(self.no_match)
pyx_code.putln("break")
pyx_code.dedent() pyx_code.dedent()
fused_index += 1 fused_index += 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment