Replace std::cout with py::print in tests

With this change both C++ and Python write to sys.stdout which resolves
the capture issues noted in #351. Therefore, the related workarounds are
removed.
This commit is contained in:
Dean Moldovan 2016-09-07 00:50:10 +02:00
parent c84b37b577
commit 81511be341
11 changed files with 51 additions and 64 deletions

View File

@ -29,5 +29,4 @@ install:
build_script:
- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
- set PYTEST_ADDOPTS="-s" # workaround for pytest capture issue, see #351
- cmake --build . --config Release --target pytest -- /v:m /logger:%MSBuildLogger%

View File

@ -70,20 +70,12 @@ class Capture(object):
self.out = ""
self.err = ""
def _flush(self):
"""Workaround for issues on Windows: to be removed after tests get py::print"""
sys.stdout.flush()
os.fsync(sys.stdout.fileno())
sys.stderr.flush()
os.fsync(sys.stderr.fileno())
return self.capfd.readouterr()
def __enter__(self):
self._flush()
self.capfd.readouterr()
return self
def __exit__(self, *_):
self.out, self.err = self._flush()
self.out, self.err = self.capfd.readouterr()
def __eq__(self, other):
a = Output(self.out)

View File

@ -200,14 +200,17 @@ template <class T, typename... Values> void track_values(T *, Values &&...values
ConstructorStats::get<T>().value(std::forward<Values>(values)...);
}
inline void print_constr_details_more() { std::cout << std::endl; }
template <typename Head, typename... Tail> void print_constr_details_more(const Head &head, Tail &&...tail) {
std::cout << " " << head;
print_constr_details_more(std::forward<Tail>(tail)...);
}
template <class T, typename... Output> void print_constr_details(T *inst, const std::string &action, Output &&...output) {
std::cout << "### " << py::type_id<T>() << " @ " << inst << " " << action;
print_constr_details_more(std::forward<Output>(output)...);
/// Don't cast pointers to Python, print them as strings
inline const char *format_ptrs(const char *p) { return p; }
template <typename T>
py::str format_ptrs(T *p) { return "{:#x}"_s.format(reinterpret_cast<std::uintptr_t>(p)); }
template <typename T>
auto format_ptrs(T &&x) -> decltype(std::forward<T>(x)) { return std::forward<T>(x); }
template <class T, typename... Output>
void print_constr_details(T *inst, const std::string &action, Output &&...output) {
py::print("###", py::type_id<T>(), "@", format_ptrs(inst), action,
format_ptrs(std::forward<Output>(output))...);
}
// Verbose versions of the above:

View File

@ -1,12 +1,8 @@
#pragma once
#include <pybind11/pybind11.h>
#include <iostream>
#include <functional>
#include <list>
using std::cout;
using std::endl;
namespace py = pybind11;
using namespace pybind11::literals;

View File

@ -121,14 +121,14 @@ void init_issues(py::module &m) {
// classes that were not extended on the Python side
struct A {
virtual ~A() {}
virtual void f() { std::cout << "A.f()" << std::endl; }
virtual void f() { py::print("A.f()"); }
};
struct PyA : A {
PyA() { std::cout << "PyA.PyA()" << std::endl; }
PyA() { py::print("PyA.PyA()"); }
void f() override {
std::cout << "PyA.f()" << std::endl;
py::print("PyA.f()");
PYBIND11_OVERLOAD(void, A, f);
}
};
@ -177,7 +177,7 @@ void init_issues(py::module &m) {
class MoveIssue1 {
public:
MoveIssue1(int v) : v{v} {}
MoveIssue1(const MoveIssue1 &c) { std::cerr << "copy ctor\n"; v=c.v; }
MoveIssue1(const MoveIssue1 &c) { v = c.v; }
MoveIssue1(MoveIssue1 &&) = delete;
int v;
};

View File

@ -12,14 +12,14 @@
class Child {
public:
Child() { std::cout << "Allocating child." << std::endl; }
~Child() { std::cout << "Releasing child." << std::endl; }
Child() { py::print("Allocating child."); }
~Child() { py::print("Releasing child."); }
};
class Parent {
public:
Parent() { std::cout << "Allocating parent." << std::endl; }
~Parent() { std::cout << "Releasing parent." << std::endl; }
Parent() { py::print("Allocating parent."); }
~Parent() { py::print("Releasing parent."); }
void addChild(Child *) { }
Child *returnChild() { return new Child(); }
Child *returnNullChild() { return nullptr; }

View File

@ -12,7 +12,7 @@
#include <pybind11/numpy.h>
double my_func(int x, float y, double z) {
std::cout << "my_func(x:int=" << x << ", y:float=" << y << ", z:float=" << z << ")" << std::endl;
py::print("my_func(x:int={}, y:float={:.0f}, z:float={:.0f})"_s.format(x, y, z));
return (float) x*y*z;
}

View File

@ -60,7 +60,7 @@ public:
py::list get_list() {
py::list list;
list.append(py::str("value"));
cout << "Entry at positon 0: " << py::object(list[0]) << endl;
py::print("Entry at position 0:", py::object(list[0]));
list[0] = py::str("overwritten");
return list;
}
@ -80,42 +80,39 @@ public:
/* Easily iterate over a dictionary using a C++11 range-based for loop */
void print_dict(py::dict dict) {
for (auto item : dict)
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
py::print("key: {}, value={}"_s.format(item.first, item.second));
}
/* Easily iterate over a set using a C++11 range-based for loop */
void print_set(py::set set) {
for (auto item : set)
std::cout << "key: " << item << std::endl;
py::print("key:", item);
}
/* Easily iterate over a list using a C++11 range-based for loop */
void print_list(py::list list) {
int index = 0;
for (auto item : list)
std::cout << "list item " << index++ << ": " << item << std::endl;
py::print("list item {}: {}"_s.format(index++, item));
}
/* STL data types (such as maps) are automatically casted from Python */
void print_dict_2(const std::map<std::string, std::string> &dict) {
for (auto item : dict)
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
py::print("key: {}, value={}"_s.format(item.first, item.second));
}
/* STL data types (such as sets) are automatically casted from Python */
void print_set_2(const std::set<std::string> &set) {
for (auto item : set)
std::cout << "key: " << item << std::endl;
py::print("key:", item);
}
/* STL data types (such as vectors) are automatically casted from Python */
void print_list_2(std::vector<std::wstring> &list) {
#ifdef _WIN32 /* Can't easily mix cout and wcout on Windows */
_setmode(_fileno(stdout), _O_TEXT);
#endif
int index = 0;
for (auto item : list)
std::wcout << L"list item " << index++ << L": " << item << std::endl;
py::print("list item {}: {}"_s.format(index++, item));
}
/* pybind automatically translates between C++11 and Python tuples */
@ -132,7 +129,7 @@ public:
void print_array(std::array<std::string, 2> &array) {
int index = 0;
for (auto item : array)
std::cout << "array item " << index++ << ": " << item << std::endl;
py::print("array item {}: {}"_s.format(index++, item));
}
void throw_exception() {
@ -156,8 +153,8 @@ public:
}
void test_print(const py::object& obj) {
std::cout << obj.str() << std::endl;
std::cout << obj.repr() << std::endl;
py::print(obj.str());
py::print(obj.repr());
}
static int value;

View File

@ -59,7 +59,7 @@ def test_instance(capture):
list_result.append('value2')
instance.print_list(list_result)
assert capture.unordered == """
Entry at positon 0: value
Entry at position 0: value
list item 0: overwritten
list item 1: value2
"""

View File

@ -97,25 +97,25 @@ std::shared_ptr<MyObject2> make_myobject2_2() { return std::make_shared<MyObject
MyObject3 *make_myobject3_1() { return new MyObject3(8); }
std::shared_ptr<MyObject3> make_myobject3_2() { return std::make_shared<MyObject3>(9); }
void print_object_1(const Object *obj) { std::cout << obj->toString() << std::endl; }
void print_object_2(ref<Object> obj) { std::cout << obj->toString() << std::endl; }
void print_object_3(const ref<Object> &obj) { std::cout << obj->toString() << std::endl; }
void print_object_4(const ref<Object> *obj) { std::cout << (*obj)->toString() << std::endl; }
void print_object_1(const Object *obj) { py::print(obj->toString()); }
void print_object_2(ref<Object> obj) { py::print(obj->toString()); }
void print_object_3(const ref<Object> &obj) { py::print(obj->toString()); }
void print_object_4(const ref<Object> *obj) { py::print((*obj)->toString()); }
void print_myobject1_1(const MyObject1 *obj) { std::cout << obj->toString() << std::endl; }
void print_myobject1_2(ref<MyObject1> obj) { std::cout << obj->toString() << std::endl; }
void print_myobject1_3(const ref<MyObject1> &obj) { std::cout << obj->toString() << std::endl; }
void print_myobject1_4(const ref<MyObject1> *obj) { std::cout << (*obj)->toString() << std::endl; }
void print_myobject1_1(const MyObject1 *obj) { py::print(obj->toString()); }
void print_myobject1_2(ref<MyObject1> obj) { py::print(obj->toString()); }
void print_myobject1_3(const ref<MyObject1> &obj) { py::print(obj->toString()); }
void print_myobject1_4(const ref<MyObject1> *obj) { py::print((*obj)->toString()); }
void print_myobject2_1(const MyObject2 *obj) { std::cout << obj->toString() << std::endl; }
void print_myobject2_2(std::shared_ptr<MyObject2> obj) { std::cout << obj->toString() << std::endl; }
void print_myobject2_3(const std::shared_ptr<MyObject2> &obj) { std::cout << obj->toString() << std::endl; }
void print_myobject2_4(const std::shared_ptr<MyObject2> *obj) { std::cout << (*obj)->toString() << std::endl; }
void print_myobject2_1(const MyObject2 *obj) { py::print(obj->toString()); }
void print_myobject2_2(std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); }
void print_myobject2_3(const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); }
void print_myobject2_4(const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); }
void print_myobject3_1(const MyObject3 *obj) { std::cout << obj->toString() << std::endl; }
void print_myobject3_2(std::shared_ptr<MyObject3> obj) { std::cout << obj->toString() << std::endl; }
void print_myobject3_3(const std::shared_ptr<MyObject3> &obj) { std::cout << obj->toString() << std::endl; }
void print_myobject3_4(const std::shared_ptr<MyObject3> *obj) { std::cout << (*obj)->toString() << std::endl; }
void print_myobject3_1(const MyObject3 *obj) { py::print(obj->toString()); }
void print_myobject3_2(std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); }
void print_myobject3_3(const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); }
void print_myobject3_4(const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); }
test_initializer smart_ptr([](py::module &m) {
py::class_<Object, ref<Object>> obj(m, "Object");

View File

@ -20,8 +20,8 @@ public:
~ExampleVirt() { print_destroyed(this); }
virtual int run(int value) {
std::cout << "Original implementation of ExampleVirt::run(state=" << state
<< ", value=" << value << ")" << std::endl;
py::print("Original implementation of "
"ExampleVirt::run(state={}, value={})"_s.format(state, value));
return state + value;
}