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
c64e6b16
Commit
c64e6b16
authored
Sep 12, 2017
by
Gunnar Läthén
Committed by
Dean Moldovan
Sep 12, 2017
Browse files
Added function for reloading module (#1040)
parent
2cf87a54
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
1 deletion
+65
-1
docs/advanced/embedding.rst
docs/advanced/embedding.rst
+6
-1
include/pybind11/pybind11.h
include/pybind11/pybind11.h
+8
-0
tests/test_embed/test_interpreter.cpp
tests/test_embed/test_interpreter.cpp
+51
-0
No files found.
docs/advanced/embedding.rst
View file @
c64e6b16
...
...
@@ -133,6 +133,11 @@ embedding the interpreter. This makes it easy to import local Python files:
int n = result.cast<int>();
assert(n == 3);
Modules can be reloaded using `module::reload()` if the source is modified e.g.
by an external process. This can be useful in scenarios where the application
imports a user defined data processing script which needs to be updated after
changes by the user. Note that this function does not reload modules recursively.
.. _embedding_modules:
Adding embedded modules
...
...
@@ -185,7 +190,7 @@ naturally:
namespace py = pybind11;
PYBIND11_EMBEDDED_MODULE(cpp_module, m) {
m.attr("a") = 1
m.attr("a") = 1
;
}
int main() {
...
...
include/pybind11/pybind11.h
View file @
c64e6b16
...
...
@@ -836,6 +836,14 @@ public:
return
reinterpret_steal
<
module
>
(
obj
);
}
/// Reload the module or throws `error_already_set`.
void
reload
()
{
PyObject
*
obj
=
PyImport_ReloadModule
(
ptr
());
if
(
!
obj
)
throw
error_already_set
();
*
this
=
reinterpret_steal
<
module
>
(
obj
);
}
// Adds an object to the module using the given name. Throws if an object with the given name
// already exists.
//
...
...
tests/test_embed/test_interpreter.cpp
View file @
c64e6b16
...
...
@@ -2,6 +2,8 @@
#include <catch.hpp>
#include <thread>
#include <fstream>
#include <functional>
namespace
py
=
pybind11
;
using
namespace
py
::
literals
;
...
...
@@ -216,3 +218,52 @@ TEST_CASE("Threads") {
REQUIRE
(
locals
[
"count"
].
cast
<
int
>
()
==
num_threads
);
}
// Scope exit utility https://stackoverflow.com/a/36644501/7255855
struct
scope_exit
{
std
::
function
<
void
()
>
f_
;
explicit
scope_exit
(
std
::
function
<
void
()
>
f
)
noexcept
:
f_
(
std
::
move
(
f
))
{}
~
scope_exit
()
{
if
(
f_
)
f_
();
}
};
TEST_CASE
(
"Reload module from file"
)
{
// Disable generation of cached bytecode (.pyc files) for this test, otherwise
// Python might pick up an old version from the cache instead of the new versions
// of the .py files generated below
auto
sys
=
py
::
module
::
import
(
"sys"
);
bool
dont_write_bytecode
=
sys
.
attr
(
"dont_write_bytecode"
).
cast
<
bool
>
();
sys
.
attr
(
"dont_write_bytecode"
)
=
true
;
// Reset the value at scope exit
scope_exit
reset_dont_write_bytecode
([
&
]()
{
sys
.
attr
(
"dont_write_bytecode"
)
=
dont_write_bytecode
;
});
std
::
string
module_name
=
"test_module_reload"
;
std
::
string
module_file
=
module_name
+
".py"
;
// Create the module .py file
std
::
ofstream
test_module
(
module_file
);
test_module
<<
"def test():
\n
"
;
test_module
<<
" return 1
\n
"
;
test_module
.
close
();
// Delete the file at scope exit
scope_exit
delete_module_file
([
&
]()
{
std
::
remove
(
module_file
.
c_str
());
});
// Import the module from file
auto
module
=
py
::
module
::
import
(
module_name
.
c_str
());
int
result
=
module
.
attr
(
"test"
)().
cast
<
int
>
();
REQUIRE
(
result
==
1
);
// Update the module .py file with a small change
test_module
.
open
(
module_file
);
test_module
<<
"def test():
\n
"
;
test_module
<<
" return 2
\n
"
;
test_module
.
close
();
// Reload the module
module
.
reload
();
result
=
module
.
attr
(
"test"
)().
cast
<
int
>
();
REQUIRE
(
result
==
2
);
}
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