Skip to content

Commit 485dace

Browse files
committed
Merge branch 'master' into sh_merge_master
2 parents 50220ae + 58802de commit 485dace

22 files changed

+451
-72
lines changed

include/pybind11/detail/internals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ PYBIND11_NOINLINE internals &get_internals() {
426426
~gil_scoped_acquire_local() { PyGILState_Release(state); }
427427
const PyGILState_STATE state;
428428
} gil;
429+
error_scope err_scope;
429430

430431
PYBIND11_STR_TYPE id(PYBIND11_INTERNALS_ID);
431432
auto builtins = handle(PyEval_GetBuiltins());

include/pybind11/detail/type_caster_base.h

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -470,13 +470,20 @@ PYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp)
470470
return isinstance(obj, type);
471471
}
472472

473-
PYBIND11_NOINLINE std::string error_string() {
474-
if (!PyErr_Occurred()) {
475-
PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred");
476-
return "Unknown internal error occurred";
473+
PYBIND11_NOINLINE std::string error_string(const char *called) {
474+
error_scope scope; // Fetch error state (will be restored when this function returns).
475+
if (scope.type == nullptr) {
476+
if (called == nullptr) {
477+
called = "pybind11::detail::error_string()";
478+
}
479+
pybind11_fail("Internal error: " + std::string(called)
480+
+ " called while Python error indicator not set.");
477481
}
478482

479-
error_scope scope; // Preserve error state
483+
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
484+
if (scope.trace != nullptr) {
485+
PyException_SetTraceback(scope.value, scope.trace);
486+
}
480487

481488
std::string errorString;
482489
if (scope.type) {
@@ -487,12 +494,6 @@ PYBIND11_NOINLINE std::string error_string() {
487494
errorString += (std::string) str(scope.value);
488495
}
489496

490-
PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);
491-
492-
if (scope.trace != nullptr) {
493-
PyException_SetTraceback(scope.value, scope.trace);
494-
}
495-
496497
#if !defined(PYPY_VERSION)
497498
if (scope.trace) {
498499
auto *trace = (PyTracebackObject *) scope.trace;

include/pybind11/functional.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ struct type_caster<std::function<Return(Args...)>> {
9898
explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}
9999
Return operator()(Args... args) const {
100100
gil_scoped_acquire acq;
101-
object retval(hfunc.f(std::forward<Args>(args)...));
102-
return retval.template cast<Return>();
101+
// casts the returned object as a rvalue to the return type
102+
return object(hfunc.f(std::forward<Args>(args)...)).template cast<Return>();
103103
}
104104
};
105105

include/pybind11/iostream.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class pythonbuf : public std::streambuf {
100100

101101
if (size > remainder) {
102102
str line(pbase(), size - remainder);
103-
pywrite(line);
103+
pywrite(std::move(line));
104104
pyflush();
105105
}
106106

include/pybind11/pybind11.h

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,9 +1174,16 @@ class module_ : public object {
11741174
py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'");
11751175
\endrst */
11761176
module_ def_submodule(const char *name, const char *doc = nullptr) {
1177-
std::string full_name
1178-
= std::string(PyModule_GetName(m_ptr)) + std::string(".") + std::string(name);
1179-
auto result = reinterpret_borrow<module_>(PyImport_AddModule(full_name.c_str()));
1177+
const char *this_name = PyModule_GetName(m_ptr);
1178+
if (this_name == nullptr) {
1179+
throw error_already_set();
1180+
}
1181+
std::string full_name = std::string(this_name) + '.' + name;
1182+
handle submodule = PyImport_AddModule(full_name.c_str());
1183+
if (!submodule) {
1184+
throw error_already_set();
1185+
}
1186+
auto result = reinterpret_borrow<module_>(submodule);
11801187
if (doc && options::show_user_defined_docstrings()) {
11811188
result.attr("__doc__") = pybind11::str(doc);
11821189
}
@@ -1796,7 +1803,8 @@ class class_ : public detail::generic_type {
17961803
scope(*this),
17971804
sibling(getattr(*this, name_, none())),
17981805
extra...);
1799-
attr(cf.name()) = staticmethod(cf);
1806+
auto cf_name = cf.name();
1807+
attr(std::move(cf_name)) = staticmethod(std::move(cf));
18001808
return *this;
18011809
}
18021810

@@ -1850,7 +1858,7 @@ class class_ : public detail::generic_type {
18501858
if (!caster.load(obj, false)) {
18511859
return nullptr;
18521860
}
1853-
return new buffer_info(((capture *) ptr)->func(caster));
1861+
return new buffer_info(((capture *) ptr)->func(std::move(caster)));
18541862
},
18551863
ptr);
18561864
weakref(m_ptr, cpp_function([ptr](handle wr) {
@@ -2316,12 +2324,12 @@ struct enum_base {
23162324
str name(name_);
23172325
if (entries.contains(name)) {
23182326
std::string type_name = (std::string) str(m_base.attr("__name__"));
2319-
throw value_error(type_name + ": element \"" + std::string(name_)
2327+
throw value_error(std::move(type_name) + ": element \"" + std::string(name_)
23202328
+ "\" already exists!");
23212329
}
23222330

23232331
entries[name] = std::make_pair(value, doc);
2324-
m_base.attr(name) = value;
2332+
m_base.attr(std::move(name)) = std::move(value);
23252333
}
23262334

23272335
PYBIND11_NOINLINE void export_values() {
@@ -2580,7 +2588,7 @@ template <typename Access,
25802588
typename Sentinel,
25812589
typename ValueType,
25822590
typename... Extra>
2583-
iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
2591+
iterator make_iterator_impl(Iterator &&first, Sentinel &&last, Extra &&...extra) {
25842592
using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;
25852593
// TODO: state captures only the types of Extra, not the values
25862594

@@ -2606,7 +2614,7 @@ iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
26062614
Policy);
26072615
}
26082616

2609-
return cast(state{first, last, true});
2617+
return cast(state{std::forward<Iterator>(first), std::forward<Sentinel>(last), true});
26102618
}
26112619

26122620
PYBIND11_NAMESPACE_END(detail)
@@ -2617,13 +2625,15 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
26172625
typename Sentinel,
26182626
typename ValueType = typename detail::iterator_access<Iterator>::result_type,
26192627
typename... Extra>
2620-
iterator make_iterator(Iterator first, Sentinel last, Extra &&...extra) {
2628+
iterator make_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
26212629
return detail::make_iterator_impl<detail::iterator_access<Iterator>,
26222630
Policy,
26232631
Iterator,
26242632
Sentinel,
26252633
ValueType,
2626-
Extra...>(first, last, std::forward<Extra>(extra)...);
2634+
Extra...>(std::forward<Iterator>(first),
2635+
std::forward<Sentinel>(last),
2636+
std::forward<Extra>(extra)...);
26272637
}
26282638

26292639
/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
@@ -2633,13 +2643,15 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
26332643
typename Sentinel,
26342644
typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,
26352645
typename... Extra>
2636-
iterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {
2646+
iterator make_key_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
26372647
return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,
26382648
Policy,
26392649
Iterator,
26402650
Sentinel,
26412651
KeyType,
2642-
Extra...>(first, last, std::forward<Extra>(extra)...);
2652+
Extra...>(std::forward<Iterator>(first),
2653+
std::forward<Sentinel>(last),
2654+
std::forward<Extra>(extra)...);
26432655
}
26442656

26452657
/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
@@ -2649,13 +2661,15 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
26492661
typename Sentinel,
26502662
typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,
26512663
typename... Extra>
2652-
iterator make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {
2664+
iterator make_value_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
26532665
return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,
26542666
Policy,
26552667
Iterator,
26562668
Sentinel,
26572669
ValueType,
2658-
Extra...>(first, last, std::forward<Extra>(extra)...);
2670+
Extra...>(std::forward<Iterator>(first),
2671+
std::forward<Sentinel>(last),
2672+
std::forward<Extra>(extra)...);
26592673
}
26602674

26612675
/// Makes an iterator over values of an stl container or other container supporting
@@ -2714,7 +2728,7 @@ void implicitly_convertible() {
27142728
};
27152729

27162730
if (auto *tinfo = detail::get_type_info(typeid(OutputType))) {
2717-
tinfo->implicit_conversions.push_back(implicit_caster);
2731+
tinfo->implicit_conversions.emplace_back(std::move(implicit_caster));
27182732
} else {
27192733
pybind11_fail("implicitly_convertible: Unable to find type " + type_id<OutputType>());
27202734
}
@@ -2851,7 +2865,7 @@ PYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) {
28512865
}
28522866

28532867
auto write = file.attr("write");
2854-
write(line);
2868+
write(std::move(line));
28552869
write(kwargs.contains("end") ? kwargs["end"] : str("\n"));
28562870

28572871
if (kwargs.contains("flush") && kwargs["flush"].cast<bool>()) {

0 commit comments

Comments
 (0)