Skip to content

Commit 3b2aeda

Browse files
anandoleecopybara-github
authored andcommitted
Rename we_love_dashes_module to we_love_dashes_cc_only_module
Move copyable_holder_caster/copyable_holder_caster to proto_caster_impl.h PiperOrigin-RevId: 635499681
1 parent 2079e29 commit 3b2aeda

File tree

6 files changed

+119
-89
lines changed

6 files changed

+119
-89
lines changed

pybind11_protobuf/native_proto_caster.h

Lines changed: 6 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -109,43 +109,9 @@ struct move_only_holder_caster<
109109
ProtoType, HolderType,
110110
std::enable_if_t<(std::is_base_of<::google::protobuf::Message, ProtoType>::value &&
111111
pybind11_protobuf_enable_type_caster(
112-
static_cast<ProtoType *>(nullptr)))>> {
113-
private:
114-
using Base = type_caster<intrinsic_t<ProtoType>>;
115-
static constexpr bool const_element =
116-
std::is_const<typename HolderType::element_type>::value;
117-
118-
public:
119-
static constexpr auto name = Base::name;
120-
121-
// C++->Python.
122-
static handle cast(HolderType &&src, return_value_policy, handle p) {
123-
auto *ptr = holder_helper<HolderType>::get(src);
124-
if (!ptr) return none().release();
125-
return Base::cast(std::move(*ptr), return_value_policy::move, p);
126-
}
127-
128-
// Convert Python->C++.
129-
bool load(handle src, bool convert) {
130-
Base base;
131-
if (!base.load(src, convert)) {
132-
return false;
133-
}
134-
holder = base.as_unique_ptr();
135-
return true;
136-
}
137-
138-
// PYBIND11_TYPE_CASTER
139-
explicit operator HolderType *() { return &holder; }
140-
explicit operator HolderType &() { return holder; }
141-
explicit operator HolderType &&() && { return std::move(holder); }
142-
143-
template <typename T_>
144-
using cast_op_type = pybind11::detail::movable_cast_op_type<T_>;
145-
146-
protected:
147-
HolderType holder;
148-
};
112+
static_cast<ProtoType *>(nullptr)))>>
113+
: public pybind11_protobuf::move_only_holder_caster_impl<ProtoType,
114+
HolderType> {};
149115

150116
// copyable_holder_caster enables using copyable holder types such as
151117
// std::shared_ptr. It uses type_caster<Proto> to manage the conversion
@@ -161,45 +127,9 @@ struct copyable_holder_caster<
161127
ProtoType, HolderType,
162128
std::enable_if_t<(std::is_base_of<::google::protobuf::Message, ProtoType>::value &&
163129
pybind11_protobuf_enable_type_caster(
164-
static_cast<ProtoType *>(nullptr)))>> {
165-
private:
166-
using Base = type_caster<intrinsic_t<ProtoType>>;
167-
static constexpr bool const_element =
168-
std::is_const<typename HolderType::element_type>::value;
169-
170-
public:
171-
static constexpr auto name = Base::name;
172-
173-
// C++->Python.
174-
static handle cast(const HolderType &src, return_value_policy, handle p) {
175-
// The default path calls into cast_holder so that the holder/deleter
176-
// gets added to the proto. Here we just make a copy
177-
const auto *ptr = holder_helper<HolderType>::get(src);
178-
if (!ptr) return none().release();
179-
return Base::cast(*ptr, return_value_policy::copy, p);
180-
}
181-
182-
// Convert Python->C++.
183-
bool load(handle src, bool convert) {
184-
Base base;
185-
if (!base.load(src, convert)) {
186-
return false;
187-
}
188-
// This always makes a copy, but it could, in some cases, grab a reference
189-
// and construct a shared_ptr, since the intention is clearly to mutate
190-
// the existing object...
191-
holder = base.as_unique_ptr();
192-
return true;
193-
}
194-
195-
explicit operator HolderType &() { return holder; }
196-
197-
template <typename>
198-
using cast_op_type = HolderType &;
199-
200-
protected:
201-
HolderType holder;
202-
};
130+
static_cast<ProtoType *>(nullptr)))>>
131+
: public pybind11_protobuf::copyable_holder_caster_impl<ProtoType,
132+
HolderType> {};
203133

204134
// NOTE: We also need to add support and/or test classes:
205135
//

pybind11_protobuf/proto_caster_impl.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,105 @@ struct proto_caster : public proto_caster_load_impl<ProtoType>,
315315
// clang-format on
316316
};
317317

318+
// move_only_holder_caster enables using move-only holder types such as
319+
// std::unique_ptr. It uses type_caster<Proto> to manage the conversion
320+
// and construct a holder type.
321+
template <typename MessageType, typename HolderType>
322+
struct move_only_holder_caster_impl {
323+
private:
324+
using Base =
325+
pybind11::detail::type_caster<pybind11::detail::intrinsic_t<MessageType>>;
326+
static constexpr bool const_element =
327+
std::is_const<typename HolderType::element_type>::value;
328+
329+
public:
330+
static constexpr auto name = Base::name;
331+
332+
// C++->Python.
333+
static pybind11::handle cast(HolderType &&src, pybind11::return_value_policy,
334+
pybind11::handle p) {
335+
auto *ptr = pybind11::detail::holder_helper<HolderType>::get(src);
336+
if (!ptr) return pybind11::none().release();
337+
return Base::cast(std::move(*ptr), pybind11::return_value_policy::move, p);
338+
}
339+
340+
// Convert Python->C++.
341+
bool load(pybind11::handle src, bool convert) {
342+
Base base;
343+
if (!base.load(src, convert)) {
344+
return false;
345+
}
346+
holder = base.as_unique_ptr();
347+
return true;
348+
}
349+
350+
// PYBIND11_TYPE_CASTER
351+
explicit operator HolderType *() { return &holder; }
352+
explicit operator HolderType &() { return holder; }
353+
explicit operator HolderType &&() && { return std::move(holder); }
354+
355+
template <typename T_>
356+
using cast_op_type = pybind11::detail::movable_cast_op_type<T_>;
357+
358+
protected:
359+
HolderType holder;
360+
};
361+
362+
// copyable_holder_caster enables using copyable holder types such
363+
// as std::shared_ptr. It uses type_caster<Proto> to manage the
364+
// conversion and construct a copy of the proto, then returns the
365+
// shared_ptr.
366+
//
367+
// NOTE: When using pybind11 bindings, std::shared_ptr<Proto> is
368+
// almost never correct, as it always makes a copy. It's mostly
369+
// useful for handling methods that return a shared_ptr<const T>,
370+
// which the caller never intends to mutate and where copy semantics
371+
// will work just as well.
372+
//
373+
template <typename MessageType, typename HolderType>
374+
struct copyable_holder_caster_impl {
375+
private:
376+
using Base =
377+
pybind11::detail::type_caster<pybind11::detail::intrinsic_t<MessageType>>;
378+
static constexpr bool const_element =
379+
std::is_const<typename HolderType::element_type>::value;
380+
381+
public:
382+
static constexpr auto name = Base::name;
383+
384+
// C++->Python.
385+
static pybind11::handle cast(const HolderType &src,
386+
pybind11::return_value_policy,
387+
pybind11::handle p) {
388+
// The default path calls into cast_holder so that the
389+
// holder/deleter gets added to the proto. Here we just make a
390+
// copy
391+
const auto *ptr = pybind11::detail::holder_helper<HolderType>::get(src);
392+
if (!ptr) return pybind11::none().release();
393+
return Base::cast(*ptr, pybind11::return_value_policy::copy, p);
394+
}
395+
396+
// Convert Python->C++.
397+
bool load(pybind11::handle src, bool convert) {
398+
Base base;
399+
if (!base.load(src, convert)) {
400+
return false;
401+
}
402+
// This always makes a copy, but it could, in some cases, grab a
403+
// reference and construct a shared_ptr, since the intention is
404+
// clearly to mutate the existing object...
405+
holder = base.as_unique_ptr();
406+
return true;
407+
}
408+
409+
explicit operator HolderType &() { return holder; }
410+
411+
template <typename>
412+
using cast_op_type = HolderType &;
413+
414+
protected:
415+
HolderType holder;
416+
};
318417
} // namespace pybind11_protobuf
319418

320419
#endif // PYBIND11_PROTOBUF_PROTO_CASTER_IMPL_H_

pybind11_protobuf/tests/BUILD

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_proto_library")
55
# Placeholder: load py_proto_library
66
# Placeholder: load py_library
77
load("@pybind11_bazel//:build_defs.bzl", "pybind_extension")
8+
89
# [internal] load cc_proto_library.bzl
910
load("@pypi//:requirements.bzl", "requirement")
1011

@@ -359,8 +360,8 @@ py_test(
359360
)
360361

361362
pybind_extension(
362-
name = "we_love_dashes_module",
363-
srcs = ["we_love_dashes_module.cc"],
363+
name = "we_love_dashes_cc_only_module",
364+
srcs = ["we_love_dashes_cc_only_module.cc"],
364365
deps = [
365366
":we_love_dashes_cc_proto",
366367
"//pybind11_protobuf:native_proto_caster",
@@ -371,7 +372,7 @@ py_test(
371372
name = "we_love_dashes_cc_only_test",
372373
srcs = ["we_love_dashes_cc_only_test.py"],
373374
deps = [
374-
":we_love_dashes_module",
375+
":we_love_dashes_cc_only_module",
375376
"@com_google_absl_py//absl/testing:absltest",
376377
"@com_google_protobuf//:protobuf_python",
377378
requirement("absl_py"),
@@ -382,8 +383,8 @@ py_test(
382383
name = "we_love_dashes_cc_and_py_in_deps_test",
383384
srcs = ["we_love_dashes_cc_and_py_in_deps_test.py"],
384385
deps = [
385-
":we_love_dashes_module",
386-
":we-love-dashes_py_pb2", # fixdeps: keep
386+
":we_love_dashes_cc_only_module",
387+
":we-love-dashes_py_pb2",
387388
"@com_google_absl_py//absl/testing:absltest",
388389
"@com_google_protobuf//:protobuf_python",
389390
requirement("absl_py"),

pybind11_protobuf/tests/we_love_dashes_cc_and_py_in_deps_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
# BSD-style license that can be found in the LICENSE file.
55

66
from absl.testing import absltest
7-
from pybind11_protobuf.tests import we_love_dashes_module
7+
from pybind11_protobuf.tests import we_love_dashes_cc_only_module
88

99
# NOTE: ":we-love-dashes_py_pb2" is in deps but intentionally not imported here.
1010

1111

1212
class MessageTest(absltest.TestCase):
1313

1414
def test_return_then_pass(self):
15-
msg = we_love_dashes_module.return_token_effort(234)
16-
score = we_love_dashes_module.pass_token_effort(msg)
15+
msg = we_love_dashes_cc_only_module.return_token_effort(234)
16+
score = we_love_dashes_cc_only_module.pass_token_effort(msg)
1717
self.assertEqual(score, 234)
1818

1919

pybind11_protobuf/tests/we_love_dashes_module.cc renamed to pybind11_protobuf/tests/we_love_dashes_cc_only_module.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace {
1212

13-
PYBIND11_MODULE(we_love_dashes_module, m) {
13+
PYBIND11_MODULE(we_love_dashes_cc_only_module, m) {
1414
pybind11_protobuf::ImportNativeProtoCasters();
1515

1616
m.def("return_token_effort", [](int score) {

pybind11_protobuf/tests/we_love_dashes_cc_only_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66
from absl.testing import absltest
77
from google.protobuf.internal import api_implementation
8-
from pybind11_protobuf.tests import we_love_dashes_module
8+
from pybind11_protobuf.tests import we_love_dashes_cc_only_module
99

1010

1111
class MessageTest(absltest.TestCase):
1212

1313
def test_return_then_pass(self):
1414
if api_implementation.Type() == 'cpp':
15-
msg = we_love_dashes_module.return_token_effort(234)
16-
score = we_love_dashes_module.pass_token_effort(msg)
15+
msg = we_love_dashes_cc_only_module.return_token_effort(234)
16+
score = we_love_dashes_cc_only_module.pass_token_effort(msg)
1717
self.assertEqual(score, 234)
1818
else:
1919
with self.assertRaisesRegex(
@@ -22,7 +22,7 @@ def test_return_then_pass(self):
2222
r' pybind11\.test\.TokenEffort in python\.'
2323
r' .*pybind11_protobuf\.tests\.we_love_dashes_pb2\?$',
2424
):
25-
we_love_dashes_module.return_token_effort(0)
25+
we_love_dashes_cc_only_module.return_token_effort(0)
2626

2727

2828
if __name__ == '__main__':

0 commit comments

Comments
 (0)