Blame tests/run/cpp_classes_def.pyx

Packit 562c7a
# mode: run
Packit 562c7a
# tag: cpp, werror
Packit 562c7a
# cython: experimental_cpp_class_def=True
Packit 562c7a
# distutils: extra_compile_args=-std=c++0x
Packit 562c7a
Packit 562c7a
cdef double pi
Packit 562c7a
from math import pi
Packit 562c7a
from libc.math cimport sin, cos
Packit 562c7a
from libcpp cimport bool
Packit 562c7a
from libcpp.memory cimport unique_ptr
Packit 562c7a
from libcpp.vector cimport vector
Packit 562c7a
from cython.operator cimport dereference as deref
Packit 562c7a
Packit 562c7a
cdef extern from "shapes.h" namespace "shapes":
Packit 562c7a
    cdef cppclass Shape:
Packit 562c7a
        float area() const
Packit 562c7a
Packit 562c7a
cdef cppclass RegularPolygon(Shape):
Packit 562c7a
    float radius # major
Packit 562c7a
    int n
Packit 562c7a
    __init__(int n, float radius):
Packit 562c7a
        this.n = n
Packit 562c7a
        this.radius = radius
Packit 562c7a
    float area() const:
Packit 562c7a
        cdef double theta = pi / this.n
Packit 562c7a
        return this.radius * this.radius * sin(theta) * cos(theta) * this.n
Packit 562c7a
Packit 562c7a
def test_Poly(int n, float radius=1):
Packit 562c7a
    """
Packit 562c7a
    >>> test_Poly(4)
Packit 562c7a
    2.0
Packit 562c7a
    >>> test_Poly(3)         #doctest: +ELLIPSIS
Packit 562c7a
    1.29903...
Packit 562c7a
    >>> test_Poly(3, 10.0)   #doctest: +ELLIPSIS
Packit 562c7a
    129.903...
Packit 562c7a
    >>> test_Poly(100)       #doctest: +ELLIPSIS
Packit 562c7a
    3.13952...
Packit 562c7a
    >>> test_Poly(1000)      #doctest: +ELLIPSIS
Packit 562c7a
    3.14157...
Packit 562c7a
    """
Packit 562c7a
    cdef RegularPolygon* poly
Packit 562c7a
    try:
Packit 562c7a
        poly = new RegularPolygon(n, radius)
Packit 562c7a
        poly.n = n
Packit 562c7a
        poly.radius = radius
Packit 562c7a
        return poly.area()
Packit 562c7a
    finally:
Packit 562c7a
        del poly
Packit 562c7a
Packit 562c7a
cdef cppclass BaseClass:
Packit 562c7a
    int n
Packit 562c7a
    int method():
Packit 562c7a
        return this.n
Packit 562c7a
Packit 562c7a
cdef cppclass SubClass(BaseClass):
Packit 562c7a
    bool override
Packit 562c7a
    __init__(bool override):
Packit 562c7a
        this.n = 1
Packit 562c7a
        this.override = override
Packit 562c7a
    int method():
Packit 562c7a
        if override:
Packit 562c7a
            return 0
Packit 562c7a
        else:
Packit 562c7a
            return BaseClass.method()
Packit 562c7a
Packit 562c7a
def test_BaseMethods(x):
Packit 562c7a
    """
Packit 562c7a
    >>> test_BaseMethods(True)
Packit 562c7a
    0
Packit 562c7a
    >>> test_BaseMethods(False)
Packit 562c7a
    1
Packit 562c7a
    """
Packit 562c7a
    cdef SubClass* subClass
Packit 562c7a
    try:
Packit 562c7a
        subClass = new SubClass(x)
Packit 562c7a
        return subClass.method()
Packit 562c7a
    finally:
Packit 562c7a
        del subClass
Packit 562c7a
Packit 562c7a
cdef cppclass WithStatic:
Packit 562c7a
    @staticmethod
Packit 562c7a
    double square(double x):
Packit 562c7a
        return x * x
Packit 562c7a
Packit 562c7a
def test_Static(x):
Packit 562c7a
    """
Packit 562c7a
    >>> test_Static(2)
Packit 562c7a
    4.0
Packit 562c7a
    >>> test_Static(0.5)
Packit 562c7a
    0.25
Packit 562c7a
    """
Packit 562c7a
    return WithStatic.square(x)
Packit 562c7a
Packit 562c7a
Packit 562c7a
cdef cppclass InitDealloc:
Packit 562c7a
    __init__():
Packit 562c7a
        try:
Packit 562c7a
            print "Init"
Packit 562c7a
        finally:
Packit 562c7a
            return  # swallow any exceptions
Packit 562c7a
    __dealloc__():
Packit 562c7a
        try:
Packit 562c7a
            print "Dealloc"
Packit 562c7a
        finally:
Packit 562c7a
            return  # swallow any exceptions
Packit 562c7a
Packit 562c7a
def test_init_dealloc():
Packit 562c7a
    """
Packit 562c7a
    >>> test_init_dealloc()
Packit 562c7a
    start
Packit 562c7a
    Init
Packit 562c7a
    live
Packit 562c7a
    Dealloc
Packit 562c7a
    end
Packit 562c7a
    """
Packit 562c7a
    print "start"
Packit 562c7a
    cdef InitDealloc *ptr = new InitDealloc()
Packit 562c7a
    print "live"
Packit 562c7a
    del ptr
Packit 562c7a
    print "end"
Packit 562c7a
Packit 562c7a
Packit 562c7a
cdef cppclass WithTemplate[T]:
Packit 562c7a
    T value
Packit 562c7a
    void set_value(T value):
Packit 562c7a
        this.value = value
Packit 562c7a
    T get_value():
Packit 562c7a
        return this.value
Packit 562c7a
Packit 562c7a
cdef cppclass ResolveTemplate(WithTemplate[long]):
Packit 562c7a
    pass
Packit 562c7a
Packit 562c7a
def test_templates(long value):
Packit 562c7a
    """
Packit 562c7a
    >>> test_templates(10)
Packit 562c7a
    >>> test_templates(-2)
Packit 562c7a
    """
Packit 562c7a
    cdef WithTemplate[long] *base = new WithTemplate[long]()
Packit 562c7a
    del base
Packit 562c7a
Packit 562c7a
    cdef ResolveTemplate *resolved = new ResolveTemplate()
Packit 562c7a
    resolved.set_value(value)
Packit 562c7a
    assert resolved.value == resolved.get_value() == value, resolved.value
Packit 562c7a
Packit 562c7a
    base = resolved
Packit 562c7a
    base.set_value(2 * value)
Packit 562c7a
    assert base.get_value() == base.value == 2 * value, base.value
Packit 562c7a
Packit 562c7a
    del base
Packit 562c7a
Packit 562c7a
cdef cppclass Simple:
Packit 562c7a
  pass
Packit 562c7a
Packit 562c7a
def test_default_init_no_gil():
Packit 562c7a
  with nogil:
Packit 562c7a
    s = new Simple()
Packit 562c7a
    del s
Packit 562c7a
Packit 562c7a
Packit 562c7a
cdef class NoisyAlloc(object):
Packit 562c7a
    cdef public name
Packit 562c7a
    def __init__(self, name):
Packit 562c7a
        print "NoisyAlloc.__init__", name
Packit 562c7a
        self.name = name
Packit 562c7a
    def __dealloc__(self):
Packit 562c7a
        try:
Packit 562c7a
            print "NoisyAlloc.__dealloc__", self.name
Packit 562c7a
        except:
Packit 562c7a
            pass  # Suppress unraisable exception warning.
Packit 562c7a
    def __repr__(self):
Packit 562c7a
        return "NoisyAlloc[%s]" % self.name
Packit 562c7a
Packit 562c7a
cdef cppclass CppClassWithObjectMember:
Packit 562c7a
    NoisyAlloc o
Packit 562c7a
    __init__(name):
Packit 562c7a
        try:
Packit 562c7a
            print "CppClassWithObjectMember.__init__", name
Packit 562c7a
            this.o = NoisyAlloc(name)
Packit 562c7a
        except:
Packit 562c7a
            pass  # Suppress unraisable exception warning.
Packit 562c7a
    __dealloc__():
Packit 562c7a
        try:
Packit 562c7a
            print "CppClassWithObjectMember.__dealloc__", this.o.name
Packit 562c7a
        except:
Packit 562c7a
            pass  # Suppress unraisable exception warning.
Packit 562c7a
Packit 562c7a
def test_CppClassWithObjectMember(name):
Packit 562c7a
    """
Packit 562c7a
    >>> test_CppClassWithObjectMember("gertrude")
Packit 562c7a
    CppClassWithObjectMember.__init__ gertrude
Packit 562c7a
    NoisyAlloc.__init__ gertrude
Packit 562c7a
    CppClassWithObjectMember.__dealloc__ gertrude
Packit 562c7a
    NoisyAlloc.__dealloc__ gertrude
Packit 562c7a
    """
Packit 562c7a
    x = new CppClassWithObjectMember(name)
Packit 562c7a
    del x
Packit 562c7a
Packit 562c7a
def test_CppClassWithObjectMemberCopyAssign(name):
Packit 562c7a
    """
Packit 562c7a
    >>> test_CppClassWithObjectMemberCopyAssign("gretel")
Packit 562c7a
    CppClassWithObjectMember.__init__ gretel
Packit 562c7a
    NoisyAlloc.__init__ gretel
Packit 562c7a
    CppClassWithObjectMember.__dealloc__ gretel
Packit 562c7a
    Alive in vector NoisyAlloc[gretel]
Packit 562c7a
    CppClassWithObjectMember.__init__ leterg
Packit 562c7a
    NoisyAlloc.__init__ leterg
Packit 562c7a
    NoisyAlloc.__dealloc__ gretel
Packit 562c7a
    CppClassWithObjectMember.__dealloc__ leterg
Packit 562c7a
    Alive in vector NoisyAlloc[leterg]
Packit 562c7a
    CppClassWithObjectMember.__dealloc__ leterg
Packit 562c7a
    NoisyAlloc.__dealloc__ leterg
Packit 562c7a
    Nothing alive.
Packit 562c7a
    """
Packit 562c7a
    x = new CppClassWithObjectMember(name)
Packit 562c7a
    cdef vector[CppClassWithObjectMember] v
Packit 562c7a
    # Invokes copy constructor.
Packit 562c7a
    v.push_back(deref(x))
Packit 562c7a
    del x
Packit 562c7a
    print "Alive in vector", v[0].o
Packit 562c7a
    y = new CppClassWithObjectMember(name[::-1])
Packit 562c7a
    # Invokes copy assignment.
Packit 562c7a
    v[0] = deref(y)
Packit 562c7a
    del y
Packit 562c7a
    print "Alive in vector", v[0].o
Packit 562c7a
    v.clear()
Packit 562c7a
    print "Nothing alive."
Packit 562c7a
Packit 562c7a
Packit 562c7a
# Github issue #1886.
Packit 562c7a
cdef public cppclass PublicCppClassWithObjectMember:
Packit 562c7a
  object o
Packit 562c7a
Packit 562c7a
def test_PublicCppClassWithObjectMember():
Packit 562c7a
  """
Packit 562c7a
  >>> test_PublicCppClassWithObjectMember()
Packit 562c7a
  """
Packit 562c7a
  cdef PublicCppClassWithObjectMember c
Packit 562c7a
  assert c.o is None
Packit 562c7a
Packit 562c7a
Packit 562c7a
cdef cppclass UncopyableConstructorArgument:
Packit 562c7a
    unique_ptr[vector[int]] member
Packit 562c7a
    __init__(unique_ptr[vector[int]] arg):
Packit 562c7a
        this.member.reset(arg.release())
Packit 562c7a
Packit 562c7a
def test_uncopyable_constructor_argument():
Packit 562c7a
    """
Packit 562c7a
    >>> test_uncopyable_constructor_argument()
Packit 562c7a
    """
Packit 562c7a
    cdef UncopyableConstructorArgument *c = new UncopyableConstructorArgument(
Packit 562c7a
        unique_ptr[vector[int]](new vector[int]()))
Packit 562c7a
    del c