Commit 6e8dd308 authored by Mark Florisson's avatar Mark Florisson

Allow 'not None' declaration for memoryview slice arguments

parent a7b2a8d3
...@@ -1833,7 +1833,12 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1833,7 +1833,12 @@ class FuncDefNode(StatNode, BlockNode):
def generate_arg_none_check(self, arg, code): def generate_arg_none_check(self, arg, code):
# Generate None check for one argument. # Generate None check for one argument.
code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname) if arg.type.is_memoryviewslice:
cname = "%s.memview" % arg.entry.cname
else:
cname = arg.entry.cname
code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % cname)
code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % ( code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
arg.name, arg.name,
code.error_goto(arg.pos))) code.error_goto(arg.pos)))
...@@ -2979,13 +2984,13 @@ class DefNode(FuncDefNode): ...@@ -2979,13 +2984,13 @@ class DefNode(FuncDefNode):
arg.needs_conversion = 0 arg.needs_conversion = 0
arg.needs_type_test = 0 arg.needs_type_test = 0
arg.is_generic = 1 arg.is_generic = 1
if arg.type.is_pyobject or arg.type.is_buffer: if arg.type.is_pyobject or arg.type.is_buffer or arg.type.is_memoryviewslice:
if arg.or_none: if arg.or_none:
arg.accept_none = True arg.accept_none = True
elif arg.not_none: elif arg.not_none:
arg.accept_none = False arg.accept_none = False
elif (arg.type.is_extension_type or arg.type.is_builtin_type elif (arg.type.is_extension_type or arg.type.is_builtin_type
or arg.type.is_buffer): or arg.type.is_buffer or arg.type.is_memoryviewslice):
if arg.default and arg.default.constant_result is None: if arg.default and arg.default.constant_result is None:
# special case: def func(MyType obj = None) # special case: def func(MyType obj = None)
arg.accept_none = True arg.accept_none = True
...@@ -4029,7 +4034,9 @@ class DefNodeWrapper(FuncDefNode): ...@@ -4029,7 +4034,9 @@ class DefNodeWrapper(FuncDefNode):
for arg in self.args: for arg in self.args:
if arg.needs_type_test: if arg.needs_type_test:
self.generate_arg_type_test(arg, code) self.generate_arg_type_test(arg, code)
elif not arg.accept_none and arg.type.is_pyobject: elif not arg.accept_none and (arg.type.is_pyobject or
arg.type.is_buffer or
arg.type.is_memoryviewslice):
self.generate_arg_none_check(arg, code) self.generate_arg_none_check(arg, code)
def error_value(self): def error_value(self):
......
...@@ -2195,6 +2195,14 @@ def test_noneslice_nogil_check_none(double[:] m): ...@@ -2195,6 +2195,14 @@ def test_noneslice_nogil_check_none(double[:] m):
return is_none, not_none return is_none, not_none
@testcase
def test_noneslice_not_none(double[:] m not None):
"""
>>> test_noneslice_not_none(None)
Traceback (most recent call last):
TypeError: Argument 'm' must not be None
"""
def get_int(): def get_int():
return 10 return 10
......
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