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