pybind11/tests/test_issues.py
Jason Rhinelander ec62d977c4 Implement py::init_alias<>() constructors
This commit adds support for forcing alias type initialization by
defining constructors with `py::init_alias<arg1, arg2>()` instead of
`py::init<arg1, arg2>()`.  Currently py::init<> only results in Alias
initialization if the type is extended in python, or the given
arguments can't be used to construct the base type, but can be used to
construct the alias.  py::init_alias<>, in contrast, always invokes the
constructor of the alias type.

It looks like this was already the intention of
`py::detail::init_alias`, which was forward-declared in
86d825f3302701d81414ddd3d38bcd09433076bc, but was apparently never
finished: despite the existance of a .def method accepting it, the
`detail::init_alias` class isn't actually defined anywhere.

This commit completes the feature (or possibly repurposes it), allowing
declaration of classes that will always initialize the trampoline which
is (as I argued in #397) sometimes useful.
2016-09-09 03:04:09 -04:00

160 lines
4.5 KiB
Python

import pytest
import gc
def test_regressions():
from pybind11_tests.issues import print_cchar, print_char
# #137: const char* isn't handled properly
assert print_cchar("const char *") == "const char *"
# #150: char bindings broken
assert print_char("c") == "c"
def test_dispatch_issue(msg):
"""#159: virtual function dispatch has problems with similar-named functions"""
from pybind11_tests.issues import DispatchIssue, dispatch_issue_go
class PyClass1(DispatchIssue):
def dispatch(self):
return "Yay.."
class PyClass2(DispatchIssue):
def dispatch(self):
with pytest.raises(RuntimeError) as excinfo:
super(PyClass2, self).dispatch()
assert msg(excinfo.value) == 'Tried to call pure virtual function "Base::dispatch"'
p = PyClass1()
return dispatch_issue_go(p)
b = PyClass2()
assert dispatch_issue_go(b) == "Yay.."
def test_reference_wrapper():
"""#171: Can't return reference wrappers (or STL data structures containing them)"""
from pybind11_tests.issues import Placeholder, return_vec_of_reference_wrapper
assert str(return_vec_of_reference_wrapper(Placeholder(4))) == \
"[Placeholder[1], Placeholder[2], Placeholder[3], Placeholder[4]]"
def test_iterator_passthrough():
"""#181: iterator passthrough did not compile"""
from pybind11_tests.issues import iterator_passthrough
assert list(iterator_passthrough(iter([3, 5, 7, 9, 11, 13, 15]))) == [3, 5, 7, 9, 11, 13, 15]
def test_shared_ptr_gc():
"""// #187: issue involving std::shared_ptr<> return value policy & garbage collection"""
from pybind11_tests.issues import ElementList, ElementA
el = ElementList()
for i in range(10):
el.add(ElementA(i))
gc.collect()
for i, v in enumerate(el.get()):
assert i == v.value()
def test_no_id(capture, msg):
from pybind11_tests.issues import get_element, expect_float, expect_int
with pytest.raises(TypeError) as excinfo:
get_element(None)
assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported:
1. (arg0: m.issues.ElementA) -> int
Invoked with: None
"""
with pytest.raises(TypeError) as excinfo:
expect_int(5.2)
assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported:
1. (arg0: int) -> int
Invoked with: 5.2
"""
assert expect_float(12) == 12
def test_str_issue(msg):
"""Issue #283: __str__ called on uninitialized instance when constructor arguments invalid"""
from pybind11_tests.issues import StrIssue
assert str(StrIssue(3)) == "StrIssue[3]"
with pytest.raises(TypeError) as excinfo:
str(StrIssue("no", "such", "constructor"))
assert msg(excinfo.value) == """
Incompatible constructor arguments. The following argument types are supported:
1. m.issues.StrIssue(arg0: int)
2. m.issues.StrIssue()
Invoked with: no, such, constructor
"""
def test_nested():
""" #328: first member in a class can't be used in operators"""
from pybind11_tests.issues import NestA, NestB, NestC, get_NestA, get_NestB, get_NestC
a = NestA()
b = NestB()
c = NestC()
a += 10
assert get_NestA(a) == 13
b.a += 100
assert get_NestA(b.a) == 103
c.b.a += 1000
assert get_NestA(c.b.a) == 1003
b -= 1
assert get_NestB(b) == 3
c.b -= 3
assert get_NestB(c.b) == 1
c *= 7
assert get_NestC(c) == 35
abase = a.as_base()
assert abase.value == -2
a.as_base().value += 44
assert abase.value == 42
assert c.b.a.as_base().value == -2
c.b.a.as_base().value += 44
assert c.b.a.as_base().value == 42
del c
gc.collect()
del a # Should't delete while abase is still alive
gc.collect()
assert abase.value == 42
del abase, b
gc.collect()
def test_move_fallback():
from pybind11_tests.issues import get_moveissue1, get_moveissue2
m2 = get_moveissue2(2)
assert m2.value == 2
m1 = get_moveissue1(1)
assert m1.value == 1
def test_override_ref():
from pybind11_tests.issues import OverrideTest
o = OverrideTest("asdf")
# Not allowed (see associated .cpp comment)
#i = o.str_ref()
#assert o.str_ref() == "asdf"
assert o.str_value() == "asdf"
assert o.A_value().value == "hi"
a = o.A_ref()
assert a.value == "hi"
a.value = "bye"
assert a.value == "bye"