Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
67990d9e
Commit
67990d9e
authored
Aug 29, 2016
by
Dean Moldovan
Browse files
Add py::print() function
Replicates Python API including keyword arguments.
parent
c743e1b1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
5 deletions
+69
-5
include/pybind11/pybind11.h
include/pybind11/pybind11.h
+27
-0
tests/conftest.py
tests/conftest.py
+13
-5
tests/test_python_types.cpp
tests/test_python_types.cpp
+14
-0
tests/test_python_types.py
tests/test_python_types.py
+15
-0
No files found.
include/pybind11/pybind11.h
View file @
67990d9e
...
...
@@ -1233,6 +1233,33 @@ public:
}
};
NAMESPACE_BEGIN
(
detail
)
PYBIND11_NOINLINE
inline
void
print
(
tuple
args
,
dict
kwargs
)
{
auto
strings
=
tuple
(
args
.
size
());
for
(
size_t
i
=
0
;
i
<
args
.
size
();
++
i
)
{
strings
[
i
]
=
args
[
i
].
cast
<
object
>
().
str
();
}
auto
sep
=
kwargs
[
"sep"
]
?
kwargs
[
"sep"
]
:
cast
(
" "
);
auto
line
=
sep
.
attr
(
"join"
).
cast
<
object
>
()(
strings
);
auto
file
=
kwargs
[
"file"
]
?
kwargs
[
"file"
].
cast
<
object
>
()
:
module
::
import
(
"sys"
).
attr
(
"stdout"
);
auto
write
=
file
.
attr
(
"write"
).
cast
<
object
>
();
write
(
line
);
write
(
kwargs
[
"end"
]
?
kwargs
[
"end"
]
:
cast
(
"
\n
"
));
if
(
kwargs
[
"flush"
]
&&
kwargs
[
"flush"
].
cast
<
bool
>
())
{
file
.
attr
(
"flush"
).
cast
<
object
>
()();
}
}
NAMESPACE_END
(
detail
)
template
<
return_value_policy
policy
=
return_value_policy
::
automatic_reference
,
typename
...
Args
>
void
print
(
Args
&&
...
args
)
{
auto
c
=
detail
::
collect_arguments
<
policy
>
(
std
::
forward
<
Args
>
(
args
)...);
detail
::
print
(
c
.
args
(),
c
.
kwargs
());
}
#if defined(WITH_THREAD)
/* The functions below essentially reproduce the PyGILState_* API using a RAII
...
...
tests/conftest.py
View file @
67990d9e
...
...
@@ -68,18 +68,22 @@ class Capture(object):
def
__init__
(
self
,
capfd
):
self
.
capfd
=
capfd
self
.
out
=
""
self
.
err
=
""
def
_flush_stdout
(
self
):
def
_flush
(
self
):
"""Workaround for issues on Windows: to be removed after tests get py::print"""
sys
.
stdout
.
flush
()
os
.
fsync
(
sys
.
stdout
.
fileno
())
# make sure C++ output is also read
return
self
.
capfd
.
readouterr
()[
0
]
os
.
fsync
(
sys
.
stdout
.
fileno
())
sys
.
stderr
.
flush
()
os
.
fsync
(
sys
.
stderr
.
fileno
())
return
self
.
capfd
.
readouterr
()
def
__enter__
(
self
):
self
.
_flush
_stdout
()
self
.
_flush
()
return
self
def
__exit__
(
self
,
*
_
):
self
.
out
=
self
.
_flush
_stdout
()
self
.
out
,
self
.
err
=
self
.
_flush
()
def
__eq__
(
self
,
other
):
a
=
Output
(
self
.
out
)
...
...
@@ -100,6 +104,10 @@ class Capture(object):
def
unordered
(
self
):
return
Unordered
(
self
.
out
)
@
property
def
stderr
(
self
):
return
Output
(
self
.
err
)
@
pytest
.
fixture
def
capture
(
capfd
):
...
...
tests/test_python_types.cpp
View file @
67990d9e
...
...
@@ -197,4 +197,18 @@ test_initializer python_types([](py::module &m) {
.
def_readwrite_static
(
"value"
,
&
ExamplePythonTypes
::
value
,
"Static value member"
)
.
def_readonly_static
(
"value2"
,
&
ExamplePythonTypes
::
value2
,
"Static value member (readonly)"
)
;
m
.
def
(
"test_print_function"
,
[]()
{
py
::
print
(
"Hello, World!"
);
py
::
print
(
1
,
2.0
,
"three"
,
true
,
std
::
string
(
"-- multiple args"
));
auto
args
=
py
::
make_tuple
(
"and"
,
"a"
,
"custom"
,
"separator"
);
py
::
print
(
"*args"
,
*
args
,
"sep"
_a
=
"-"
);
py
::
print
(
"no new line here"
,
"end"
_a
=
" -- "
);
py
::
print
(
"next print"
);
auto
py_stderr
=
py
::
module
::
import
(
"sys"
).
attr
(
"stderr"
).
cast
<
py
::
object
>
();
py
::
print
(
"this goes to stderr"
,
"file"
_a
=
py_stderr
);
py
::
print
(
"flush"
,
"flush"
_a
=
true
);
});
});
tests/test_python_types.py
View file @
67990d9e
...
...
@@ -218,3 +218,18 @@ def test_module():
assert
ExamplePythonTypes
.
__module__
==
"pybind11_tests"
assert
ExamplePythonTypes
.
get_set
.
__name__
==
"get_set"
assert
ExamplePythonTypes
.
get_set
.
__module__
==
"pybind11_tests"
def
test_print
(
capture
):
from
pybind11_tests
import
test_print_function
with
capture
:
test_print_function
()
assert
capture
==
"""
Hello, World!
1 2.0 three True -- multiple args
*args-and-a-custom-separator
no new line here -- next print
flush
"""
assert
capture
.
stderr
==
"this goes to stderr"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment