Commit a9d1186d authored by Robert Bradshaw's avatar Robert Bradshaw

Merge branch 'master' into static

parents 394aa9a8 de8c251d
......@@ -91,6 +91,8 @@ Bugs fixed
* Correctly handle ``from cython.submodule cimport name``.
* Fix infinite recursion when using super with cpdef methods.
Other changes
-------------
......
......@@ -27,6 +27,7 @@ from .Code import UtilityCode
from .StringEncoding import EncodedString, escape_byte_string, split_string_literal
from . import Options
from . import DebugFlags
from Cython.Utils import LazyStr
absolute_path_length = 0
......@@ -2302,6 +2303,7 @@ class CFuncDefNode(FuncDefNode):
"private types")
def call_self_node(self, omit_optional_args=0, is_module_scope=0):
# OLD - DELETE
from . import ExprNodes
args = self.type.args
if omit_optional_args:
......@@ -2328,6 +2330,27 @@ class CFuncDefNode(FuncDefNode):
c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in call_arg_names], wrapper_call=skip_dispatch)
return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
def call_self_node(self, omit_optional_args=0, is_module_scope=0):
from . import ExprNodes
args = self.type.args
if omit_optional_args:
args = args[:len(args) - self.type.optional_arg_count]
arg_names = [arg.name for arg in args]
# The @cname decorator may mutate this later.
func_cname = LazyStr(lambda: self.entry.func_cname)
cfunc = ExprNodes.PythonCapiFunctionNode(self.pos, self.entry.name, func_cname, self.type)
# The entry is inspected due to self.type.is_overridable, but it
# has the wrong self type.
cfunc.entry = copy.copy(self.entry)
cfunc.entry.type = self.type
skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
c_call = ExprNodes.SimpleCallNode(
self.pos,
function=cfunc,
args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names],
wrapper_call=skip_dispatch)
return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
def declare_arguments(self, env):
for arg in self.type.args:
if not arg.name:
......
......@@ -24,7 +24,7 @@ cdef class Scanner:
cdef public list queue
cdef public bint trace
cdef public cur_char
cdef public int input_state
cdef public long input_state
cdef public level
......
......@@ -399,3 +399,16 @@ def print_bytes(s, end=b'\n', file=sys.stdout, flush=True):
out.write(end)
if flush:
out.flush()
class LazyStr:
def __init__(self, callback):
self.callback = callback
def __str__(self):
return self.callback()
def __repr__(self):
return self.callback()
def __add__(self, right):
return self.callback() + right
def __radd__(self, left):
return left + self.callback()
......@@ -5,18 +5,20 @@ cdef int f() except -1:
cdef str sstring
cdef basestring sustring
cdef int i
cdef long lng
cdef Py_ssize_t s
x = abs(y)
delattr(x, 'spam')
x = dir(y)
x = divmod(y, z)
x = getattr(y, 'spam')
i = hasattr(y, 'spam')
i = hash(y)
lng = hash(y)
x = intern(y)
i = isinstance(y, z)
i = issubclass(y, z)
x = iter(y)
i = len(x)
s = len(x)
x = open(y, z)
x = pow(y, z, w)
x = pow(y, z)
......
# mode: run
# tag: py3k_super
class A(object):
def method(self):
return 1
@classmethod
def class_method(cls):
return 2
@staticmethod
def static_method():
return 3
def generator_test(self):
return [1, 2, 3]
class B(A):
"""
>>> obj = B()
>>> obj.method()
1
>>> B.class_method()
2
>>> B.static_method(obj)
3
>>> list(obj.generator_test())
[1, 2, 3]
"""
def method(self):
return super(B, self).method()
@classmethod
def class_method(cls):
return super(B, cls).class_method()
@staticmethod
def static_method(instance):
return super(B, instance).static_method()
def generator_test(self):
for i in super(B, self).generator_test():
yield i
cdef class CClassBase(object):
def method(self):
return 'def'
cpdef method_cp(self):
return 'cpdef'
# cdef method_c(self):
# return 'cdef'
# def call_method_c(self):
# return self.method_c()
cdef class CClassSub(CClassBase):
"""
>>> CClassSub().method()
'def'
>>> CClassSub().method_cp()
'cpdef'
"""
# >>> CClassSub().call_method_c()
# 'cdef'
def method(self):
return super(CClassSub, self).method()
cpdef method_cp(self):
return super(CClassSub, self).method_cp()
# cdef method_c(self):
# return super(CClassSub, self).method_c()
cdef class Base(object):
"""
>>> Base().method()
'Base'
>>> Base.method(Base())
'Base'
"""
cpdef method(self):
return "Base"
cdef class Sub(Base):
"""
>>> Sub().method()
'Sub'
>>> Sub.method(Sub())
'Sub'
>>> Base.method(Sub())
'Base'
"""
cpdef method(self):
return "Sub"
......@@ -63,13 +63,29 @@ def test_class_cell_empty():
cdef class CClassBase(object):
def method(self):
return 1
return 'def'
# cpdef method_cp(self):
# return 'cpdef'
# cdef method_c(self):
# return 'cdef'
# def call_method_c(self):
# return self.method_c()
cdef class CClassSuper(CClassBase):
cdef class CClassSub(CClassBase):
"""
>>> CClassSuper().method()
1
>>> CClassSub().method()
'def'
"""
# >>> CClassSub().method_cp()
# 'cpdef'
# >>> CClassSub().call_method_c()
# 'cdef'
def method(self):
return super().method()
# cpdef method_cp(self):
# return super().method_cp()
# cdef method_c(self):
# return super().method_c()
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