Commit b3c3a039 authored by da-woods's avatar da-woods Committed by GitHub

Fix the type of the 'self' argument in a cdef staticmethod declared in a pxd file (GH-4085)

Fixes https://github.com/cython/cython/issues/3174
Closes https://github.com/cython/cython/pull/3175

I've removed all identification of is_self_arg from the parser, since I think it's better dealt with when analysing the declarations.

Original test copied from https://github.com/cython/cython/pull/3175
parent 03e919a0
......@@ -902,7 +902,7 @@ class CArgDeclNode(Node):
def analyse(self, env, nonempty=0, is_self_arg=False):
if is_self_arg:
self.base_type.is_self_arg = self.is_self_arg = True
self.base_type.is_self_arg = self.is_self_arg = is_self_arg
if self.type is not None:
return self.name_declarator, self.type
......@@ -1024,6 +1024,7 @@ class CSimpleBaseTypeNode(CBaseTypeNode):
module_path = []
is_basic_c_type = False
complex = False
is_self_arg = False
def analyse(self, env, could_be_name=False):
# Return type descriptor.
......
......@@ -141,10 +141,10 @@ cdef tuple p_suite_with_docstring(PyrexScanner s, ctx, bint with_doc_only=*)
cdef tuple _extract_docstring(node)
cdef p_positional_and_keyword_args(PyrexScanner s, end_sy_set, templates = *)
cpdef p_c_base_type(PyrexScanner s, bint self_flag = *, bint nonempty = *, templates = *)
cpdef p_c_base_type(PyrexScanner s, bint nonempty = *, templates = *)
cdef p_calling_convention(PyrexScanner s)
cdef p_c_complex_base_type(PyrexScanner s, templates = *)
cdef p_c_simple_base_type(PyrexScanner s, bint self_flag, bint nonempty, templates = *)
cdef p_c_simple_base_type(PyrexScanner s, bint nonempty, templates = *)
cdef p_buffer_or_template(PyrexScanner s, base_type_node, templates)
cdef p_bracketed_base_type(PyrexScanner s, base_type_node, nonempty, empty)
cdef is_memoryviewslice_access(PyrexScanner s)
......
......@@ -2477,13 +2477,11 @@ def p_positional_and_keyword_args(s, end_sy_set, templates = None):
s.next()
return positional_args, keyword_args
def p_c_base_type(s, self_flag = 0, nonempty = 0, templates = None):
# If self_flag is true, this is the base type for the
# self argument of a C method of an extension type.
def p_c_base_type(s, nonempty=False, templates=None):
if s.sy == '(':
return p_c_complex_base_type(s, templates = templates)
else:
return p_c_simple_base_type(s, self_flag, nonempty = nonempty, templates = templates)
return p_c_simple_base_type(s, nonempty=nonempty, templates=templates)
def p_calling_convention(s):
if s.sy == 'IDENT' and s.systring in calling_convention_words:
......@@ -2527,8 +2525,7 @@ def p_c_complex_base_type(s, templates = None):
return type_node
def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
#print "p_c_simple_base_type: self_flag =", self_flag, nonempty
def p_c_simple_base_type(s, nonempty, templates=None):
is_basic = 0
signed = 1
longness = 0
......@@ -2549,7 +2546,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
break
s.next()
if is_const or is_volatile:
base_type = p_c_base_type(s, self_flag=self_flag, nonempty=nonempty, templates=templates)
base_type = p_c_base_type(s, nonempty=nonempty, templates=templates)
if isinstance(base_type, Nodes.MemoryViewSliceTypeNode):
# reverse order to avoid having to write "(const int)[:]"
base_type.base_type_node = Nodes.CConstOrVolatileTypeNode(pos,
......@@ -2607,7 +2604,7 @@ def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
name = name, module_path = module_path,
is_basic_c_type = is_basic, signed = signed,
complex = complex, longness = longness,
is_self_arg = self_flag, templates = templates)
templates = templates)
# declarations here.
if s.sy == '[':
......@@ -3052,7 +3049,7 @@ def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
complex = 0, longness = 0,
is_self_arg = cmethod_flag, templates = None)
else:
base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty)
base_type = p_c_base_type(s, nonempty=nonempty)
declarator = p_c_declarator(s, ctx, nonempty = nonempty)
if s.sy in ('not', 'or') and not s.in_python_file:
kind = s.sy
......
cdef class FromPxd:
@staticmethod
cdef static_cdef(int* x)
@staticmethod
cdef static_cdef_with_implicit_object(obj)
......@@ -87,6 +87,10 @@ cdef class FromPxd:
cdef static_cdef(int* x):
return 'pxd_cdef', x[0]
@staticmethod
cdef static_cdef_with_implicit_object(obj):
return obj+1
def call_static_pxd_cdef(int x):
"""
>>> call_static_pxd_cdef(2)
......@@ -94,3 +98,11 @@ def call_static_pxd_cdef(int x):
"""
cdef int *x_ptr = &x
return FromPxd.static_cdef(x_ptr)
def call_static_pxd_cdef_with_implicit_object(int x):
"""
# https://github.com/cython/cython/issues/3174
>>> call_static_pxd_cdef_with_implicit_object(2)
3
"""
return FromPxd.static_cdef_with_implicit_object(x)
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