mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
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:
parent
c84b37b577
commit
81511be341
@ -29,5 +29,4 @@ install:
|
|||||||
build_script:
|
build_script:
|
||||||
- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON
|
- cmake -A "%CMAKE_ARCH%" -DPYBIND11_WERROR=ON
|
||||||
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
- 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%
|
- cmake --build . --config Release --target pytest -- /v:m /logger:%MSBuildLogger%
|
||||||
|
@ -70,20 +70,12 @@ class Capture(object):
|
|||||||
self.out = ""
|
self.out = ""
|
||||||
self.err = ""
|
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):
|
def __enter__(self):
|
||||||
self._flush()
|
self.capfd.readouterr()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __exit__(self, *_):
|
def __exit__(self, *_):
|
||||||
self.out, self.err = self._flush()
|
self.out, self.err = self.capfd.readouterr()
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
a = Output(self.out)
|
a = Output(self.out)
|
||||||
|
@ -200,14 +200,17 @@ template <class T, typename... Values> void track_values(T *, Values &&...values
|
|||||||
ConstructorStats::get<T>().value(std::forward<Values>(values)...);
|
ConstructorStats::get<T>().value(std::forward<Values>(values)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void print_constr_details_more() { std::cout << std::endl; }
|
/// Don't cast pointers to Python, print them as strings
|
||||||
template <typename Head, typename... Tail> void print_constr_details_more(const Head &head, Tail &&...tail) {
|
inline const char *format_ptrs(const char *p) { return p; }
|
||||||
std::cout << " " << head;
|
template <typename T>
|
||||||
print_constr_details_more(std::forward<Tail>(tail)...);
|
py::str format_ptrs(T *p) { return "{:#x}"_s.format(reinterpret_cast<std::uintptr_t>(p)); }
|
||||||
}
|
template <typename T>
|
||||||
template <class T, typename... Output> void print_constr_details(T *inst, const std::string &action, Output &&...output) {
|
auto format_ptrs(T &&x) -> decltype(std::forward<T>(x)) { return std::forward<T>(x); }
|
||||||
std::cout << "### " << py::type_id<T>() << " @ " << inst << " " << action;
|
|
||||||
print_constr_details_more(std::forward<Output>(output)...);
|
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:
|
// Verbose versions of the above:
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
#include <iostream>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
using namespace pybind11::literals;
|
using namespace pybind11::literals;
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ void init_issues(py::module &m) {
|
|||||||
// classes that were not extended on the Python side
|
// classes that were not extended on the Python side
|
||||||
struct A {
|
struct A {
|
||||||
virtual ~A() {}
|
virtual ~A() {}
|
||||||
virtual void f() { std::cout << "A.f()" << std::endl; }
|
virtual void f() { py::print("A.f()"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PyA : A {
|
struct PyA : A {
|
||||||
PyA() { std::cout << "PyA.PyA()" << std::endl; }
|
PyA() { py::print("PyA.PyA()"); }
|
||||||
|
|
||||||
void f() override {
|
void f() override {
|
||||||
std::cout << "PyA.f()" << std::endl;
|
py::print("PyA.f()");
|
||||||
PYBIND11_OVERLOAD(void, A, f);
|
PYBIND11_OVERLOAD(void, A, f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -177,7 +177,7 @@ void init_issues(py::module &m) {
|
|||||||
class MoveIssue1 {
|
class MoveIssue1 {
|
||||||
public:
|
public:
|
||||||
MoveIssue1(int v) : v{v} {}
|
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;
|
MoveIssue1(MoveIssue1 &&) = delete;
|
||||||
int v;
|
int v;
|
||||||
};
|
};
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
|
|
||||||
class Child {
|
class Child {
|
||||||
public:
|
public:
|
||||||
Child() { std::cout << "Allocating child." << std::endl; }
|
Child() { py::print("Allocating child."); }
|
||||||
~Child() { std::cout << "Releasing child." << std::endl; }
|
~Child() { py::print("Releasing child."); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Parent {
|
class Parent {
|
||||||
public:
|
public:
|
||||||
Parent() { std::cout << "Allocating parent." << std::endl; }
|
Parent() { py::print("Allocating parent."); }
|
||||||
~Parent() { std::cout << "Releasing parent." << std::endl; }
|
~Parent() { py::print("Releasing parent."); }
|
||||||
void addChild(Child *) { }
|
void addChild(Child *) { }
|
||||||
Child *returnChild() { return new Child(); }
|
Child *returnChild() { return new Child(); }
|
||||||
Child *returnNullChild() { return nullptr; }
|
Child *returnNullChild() { return nullptr; }
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include <pybind11/numpy.h>
|
#include <pybind11/numpy.h>
|
||||||
|
|
||||||
double my_func(int x, float y, double z) {
|
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;
|
return (float) x*y*z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
py::list get_list() {
|
py::list get_list() {
|
||||||
py::list list;
|
py::list list;
|
||||||
list.append(py::str("value"));
|
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");
|
list[0] = py::str("overwritten");
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -80,42 +80,39 @@ public:
|
|||||||
/* Easily iterate over a dictionary using a C++11 range-based for loop */
|
/* Easily iterate over a dictionary using a C++11 range-based for loop */
|
||||||
void print_dict(py::dict dict) {
|
void print_dict(py::dict dict) {
|
||||||
for (auto item : 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 */
|
/* Easily iterate over a set using a C++11 range-based for loop */
|
||||||
void print_set(py::set set) {
|
void print_set(py::set set) {
|
||||||
for (auto item : 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 */
|
/* Easily iterate over a list using a C++11 range-based for loop */
|
||||||
void print_list(py::list list) {
|
void print_list(py::list list) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto item : list)
|
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 */
|
/* STL data types (such as maps) are automatically casted from Python */
|
||||||
void print_dict_2(const std::map<std::string, std::string> &dict) {
|
void print_dict_2(const std::map<std::string, std::string> &dict) {
|
||||||
for (auto item : 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 */
|
/* STL data types (such as sets) are automatically casted from Python */
|
||||||
void print_set_2(const std::set<std::string> &set) {
|
void print_set_2(const std::set<std::string> &set) {
|
||||||
for (auto item : 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 */
|
/* STL data types (such as vectors) are automatically casted from Python */
|
||||||
void print_list_2(std::vector<std::wstring> &list) {
|
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;
|
int index = 0;
|
||||||
for (auto item : list)
|
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 */
|
/* pybind automatically translates between C++11 and Python tuples */
|
||||||
@ -132,7 +129,7 @@ public:
|
|||||||
void print_array(std::array<std::string, 2> &array) {
|
void print_array(std::array<std::string, 2> &array) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto item : array)
|
for (auto item : array)
|
||||||
std::cout << "array item " << index++ << ": " << item << std::endl;
|
py::print("array item {}: {}"_s.format(index++, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
void throw_exception() {
|
void throw_exception() {
|
||||||
@ -156,8 +153,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_print(const py::object& obj) {
|
void test_print(const py::object& obj) {
|
||||||
std::cout << obj.str() << std::endl;
|
py::print(obj.str());
|
||||||
std::cout << obj.repr() << std::endl;
|
py::print(obj.repr());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int value;
|
static int value;
|
||||||
|
@ -59,7 +59,7 @@ def test_instance(capture):
|
|||||||
list_result.append('value2')
|
list_result.append('value2')
|
||||||
instance.print_list(list_result)
|
instance.print_list(list_result)
|
||||||
assert capture.unordered == """
|
assert capture.unordered == """
|
||||||
Entry at positon 0: value
|
Entry at position 0: value
|
||||||
list item 0: overwritten
|
list item 0: overwritten
|
||||||
list item 1: value2
|
list item 1: value2
|
||||||
"""
|
"""
|
||||||
|
@ -97,25 +97,25 @@ std::shared_ptr<MyObject2> make_myobject2_2() { return std::make_shared<MyObject
|
|||||||
MyObject3 *make_myobject3_1() { return new MyObject3(8); }
|
MyObject3 *make_myobject3_1() { return new MyObject3(8); }
|
||||||
std::shared_ptr<MyObject3> make_myobject3_2() { return std::make_shared<MyObject3>(9); }
|
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_1(const Object *obj) { py::print(obj->toString()); }
|
||||||
void print_object_2(ref<Object> obj) { std::cout << obj->toString() << std::endl; }
|
void print_object_2(ref<Object> obj) { py::print(obj->toString()); }
|
||||||
void print_object_3(const ref<Object> &obj) { std::cout << obj->toString() << std::endl; }
|
void print_object_3(const ref<Object> &obj) { py::print(obj->toString()); }
|
||||||
void print_object_4(const ref<Object> *obj) { std::cout << (*obj)->toString() << std::endl; }
|
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_1(const MyObject1 *obj) { py::print(obj->toString()); }
|
||||||
void print_myobject1_2(ref<MyObject1> obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject1_2(ref<MyObject1> obj) { py::print(obj->toString()); }
|
||||||
void print_myobject1_3(const ref<MyObject1> &obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject1_3(const ref<MyObject1> &obj) { py::print(obj->toString()); }
|
||||||
void print_myobject1_4(const ref<MyObject1> *obj) { std::cout << (*obj)->toString() << std::endl; }
|
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_1(const MyObject2 *obj) { py::print(obj->toString()); }
|
||||||
void print_myobject2_2(std::shared_ptr<MyObject2> obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject2_2(std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); }
|
||||||
void print_myobject2_3(const std::shared_ptr<MyObject2> &obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject2_3(const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); }
|
||||||
void print_myobject2_4(const std::shared_ptr<MyObject2> *obj) { std::cout << (*obj)->toString() << std::endl; }
|
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_1(const MyObject3 *obj) { py::print(obj->toString()); }
|
||||||
void print_myobject3_2(std::shared_ptr<MyObject3> obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject3_2(std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); }
|
||||||
void print_myobject3_3(const std::shared_ptr<MyObject3> &obj) { std::cout << obj->toString() << std::endl; }
|
void print_myobject3_3(const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); }
|
||||||
void print_myobject3_4(const std::shared_ptr<MyObject3> *obj) { std::cout << (*obj)->toString() << std::endl; }
|
void print_myobject3_4(const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); }
|
||||||
|
|
||||||
test_initializer smart_ptr([](py::module &m) {
|
test_initializer smart_ptr([](py::module &m) {
|
||||||
py::class_<Object, ref<Object>> obj(m, "Object");
|
py::class_<Object, ref<Object>> obj(m, "Object");
|
||||||
|
@ -20,8 +20,8 @@ public:
|
|||||||
~ExampleVirt() { print_destroyed(this); }
|
~ExampleVirt() { print_destroyed(this); }
|
||||||
|
|
||||||
virtual int run(int value) {
|
virtual int run(int value) {
|
||||||
std::cout << "Original implementation of ExampleVirt::run(state=" << state
|
py::print("Original implementation of "
|
||||||
<< ", value=" << value << ")" << std::endl;
|
"ExampleVirt::run(state={}, value={})"_s.format(state, value));
|
||||||
return state + value;
|
return state + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user