diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2017-11-10 10:43:48 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-11-10 10:43:48 +0100 |
commit | dfd73ac65d3b55af85b4dcc1dda62a141efaad6c (patch) | |
tree | 9e561500645d79ff0d3d5bc7bd661963e664ad73 /Cython/Compiler/Nodes.py | |
parent | 8ad16fc871be075f889d5e7c2892db3e4c8ce978 (diff) | |
download | cython-dfd73ac65d3b55af85b4dcc1dda62a141efaad6c.tar.gz |
Do not infer C types for arguments with Python default value.
Closes #1972.
Diffstat (limited to 'Cython/Compiler/Nodes.py')
-rw-r--r-- | Cython/Compiler/Nodes.py | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 07588940d..44dddcf7b 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -68,8 +68,9 @@ def embed_position(pos, docstring): return doc -def analyse_type_annotation(annotation, env): +def analyse_type_annotation(annotation, env, assigned_value=None): base_type = None + is_ambiguous = False explicit_pytype = explicit_ctype = False if annotation.is_dict_literal: warning(annotation.pos, @@ -88,6 +89,13 @@ def analyse_type_annotation(annotation, env): warning(annotation.pos, "Duplicate type declarations found in signature annotation") arg_type = annotation.analyse_as_type(env) if annotation.is_name and not annotation.cython_attribute and annotation.name in ('int', 'long', 'float'): + # Map builtin numeric Python types to C types in safe cases. + if assigned_value is not None and arg_type is not None and not arg_type.is_pyobject: + assigned_type = assigned_value.infer_type(env) + if assigned_type and assigned_type.is_pyobject: + # C type seems unsafe, e.g. due to 'None' default value => ignore annotation type + is_ambiguous = True + arg_type = None # ignore 'int' and require 'cython.int' to avoid unsafe integer declarations if arg_type in (PyrexTypes.c_long_type, PyrexTypes.c_int_type, PyrexTypes.c_float_type): arg_type = PyrexTypes.c_double_type if annotation.name == 'float' else py_object_type @@ -100,6 +108,8 @@ def analyse_type_annotation(annotation, env): "Python type declaration in signature annotation does not refer to a Python type") base_type = CAnalysedBaseTypeNode( annotation.pos, type=arg_type, is_arg=True) + elif is_ambiguous: + warning(annotation.pos, "Ambiguous types in annotation, ignoring") else: warning(annotation.pos, "Unknown type declaration in annotation, ignoring") return base_type, arg_type @@ -890,7 +900,7 @@ class CArgDeclNode(Node): annotation = self.annotation if not annotation: return None - base_type, arg_type = analyse_type_annotation(annotation, env) + base_type, arg_type = analyse_type_annotation(annotation, env, assigned_value=self.default) if base_type is not None: self.base_type = base_type return arg_type |