From 40c4dbc809207ebf8e025e5866f9a87eb2c9256a Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 16 Apr 2010 13:52:19 +0200 Subject: [PATCH] special case '=None' default arguments in ext arg type testing: automatically allow None in this case --- Cython/Compiler/Nodes.py | 8 +++-- tests/run/ext_type_none_arg.pyx | 60 ++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 9d74c2fd..68ab97f8 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1898,8 +1898,12 @@ class DefNode(FuncDefNode): elif arg.not_none: arg.accept_none = False elif arg.type.is_extension_type or arg.type.is_builtin_type: - # default depends on compiler directive - arg.accept_none = allow_none_for_extension_args + if arg.default and arg.default.constant_result is None: + # special case: def func(MyType obj = None) + arg.accept_none = True + else: + # default depends on compiler directive + arg.accept_none = allow_none_for_extension_args else: # probably just a plain 'object' arg.accept_none = True diff --git a/tests/run/ext_type_none_arg.pyx b/tests/run/ext_type_none_arg.pyx index 93dd40d5..86d70abc 100644 --- a/tests/run/ext_type_none_arg.pyx +++ b/tests/run/ext_type_none_arg.pyx @@ -24,6 +24,18 @@ def ext_default(MyExtType x): # currently behaves like 'or None' """ return attr(x) +@cython.allow_none_for_extension_args(False) +def ext_default_none(MyExtType x=None): # special cased default arg + """ + >>> ext_default_none(MyExtType()) + 123 + >>> ext_default_none(None) + 321 + >>> ext_default_none() + 321 + """ + return attr(x) + @cython.allow_none_for_extension_args(True) def ext_default_check_off(MyExtType x): """ @@ -85,6 +97,18 @@ def builtin_default(list L): # currently behaves like 'or None' """ return litem(L, 0) +@cython.allow_none_for_extension_args(False) +def builtin_default_none(list L=None): # special cased default arg + """ + >>> builtin_default_none([123]) + 123 + >>> builtin_default_none(None) + 321 + >>> builtin_default_none() + 321 + """ + return litem(L, 0) + @cython.allow_none_for_extension_args(True) def builtin_default_check_off(list L): """ @@ -131,7 +155,8 @@ def builtin_not_none(list L not None): ## builtin type 'object' - isinstance(None, object) is True! -def object_default(object o): # behaves like 'or None' +@cython.allow_none_for_extension_args(False) +def object_default(object o): # always behaves like 'or None' """ >>> object_default(object()) 'object' @@ -142,6 +167,21 @@ def object_default(object o): # behaves like 'or None' """ return type(o).__name__ +@cython.allow_none_for_extension_args(False) +def object_default_none(object o=None): # behaves like 'or None' + """ + >>> object_default_none(object()) + 'object' + >>> object_default_none([]) + 'list' + >>> object_default_none(None) + 'NoneType' + >>> object_default_none() + 'NoneType' + """ + return type(o).__name__ + +@cython.allow_none_for_extension_args(False) def object_or_none(object o or None): """ >>> object_or_none(object()) @@ -153,6 +193,7 @@ def object_or_none(object o or None): """ return type(o).__name__ +@cython.allow_none_for_extension_args(False) def object_not_none(object o not None): """ >>> object_not_none(object()) @@ -168,6 +209,7 @@ def object_not_none(object o not None): ## untyped 'object' - isinstance(None, object) is True! +@cython.allow_none_for_extension_args(False) def notype_default(o): # behaves like 'or None' """ >>> notype_default(object()) @@ -179,6 +221,21 @@ def notype_default(o): # behaves like 'or None' """ return type(o).__name__ +@cython.allow_none_for_extension_args(False) +def notype_default_none(o=None): # behaves like 'or None' + """ + >>> notype_default_none(object()) + 'object' + >>> notype_default_none([]) + 'list' + >>> notype_default_none(None) + 'NoneType' + >>> notype_default_none() + 'NoneType' + """ + return type(o).__name__ + +@cython.allow_none_for_extension_args(False) def notype_or_none(o or None): """ >>> notype_or_none(object()) @@ -190,6 +247,7 @@ def notype_or_none(o or None): """ return type(o).__name__ +@cython.allow_none_for_extension_args(False) def notype_not_none(o not None): """ >>> notype_not_none(object()) -- 2.26.2