Skip to content

Commit c50bb0a

Browse files
richiwaremergify[bot]
authored andcommitted
Remove compilation warning with InstanceHandle_t (#262)
* Refs #23753. Take into account dependencies for rebuild Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> * Refs #23753. Fix warning Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> * Refs #23753. Remove swig warnings Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> * Refs #23753. Add unit tests Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> * Refs #23753. Apply suggestions Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> --------- Signed-off-by: Ricardo González Moreno <ricardo@richiware.dev> (cherry picked from commit 6ee4ca5) # Conflicts: # fastdds_python/src/swig/fastdds/rtps/common/BinaryProperty.i # fastdds_python/src/swig/fastdds/rtps/common/Locator.i # fastdds_python/src/swig/fastdds/rtps/common/Property.i
1 parent eb71379 commit c50bb0a

File tree

8 files changed

+315
-37
lines changed

8 files changed

+315
-37
lines changed

fastdds_python/src/swig/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(${PROJECT_NAME}_MODULE
2727
set(${PROJECT_NAME}_FILE
2828
${CMAKE_CURRENT_BINARY_DIR}/${${PROJECT_NAME}_MODULE}.i
2929
)
30+
set_property(SOURCE ${${PROJECT_NAME}_FILE} PROPERTY USE_SWIG_DEPENDENCIES TRUE)
3031

3132
file(GENERATE
3233
OUTPUT ${${PROJECT_NAME}_FILE}

fastdds_python/src/swig/fastdds/dds/core/Time_t.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
%ignore eprosima::fastdds::dds::operator+(const Time_t&, const Time_t&);
3333
%ignore eprosima::fastdds::dds::operator-(const Time_t&, const Time_t&);
3434

35+
%ignore eprosima::fastdds::dds::Time_t::is_infinite(const Time_t&);
36+
3537
// Declare the comparison operators as internal to the class
3638
%extend eprosima::fastdds::dds::Time_t {
3739
bool operator==(const eprosima::fastdds::dds::Time_t& other) const

fastdds_python/src/swig/fastdds/rtps/common/BinaryProperty.i

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
%}
1818

1919
// Ignore overloaded constructor and methods that have no effect on target language
20+
<<<<<<< HEAD
2021
%ignore eprosima::fastdds::rtps::BinaryProperty::BinaryProperty(BinaryProperty &&);
22+
=======
23+
%copyctor eprosima::fastdds::rtps::BinaryProperty;
24+
%ignore eprosima::fastdds::rtps::BinaryProperty::BinaryProperty(BinaryProperty&&);
25+
>>>>>>> 6ee4ca5 (Remove compilation warning with InstanceHandle_t (#262))
2126
%ignore eprosima::fastdds::rtps::BinaryProperty::name(std::string &&);
2227
%ignore eprosima::fastdds::rtps::BinaryProperty::value(std::vector<uint8_t> &&);
2328
%ignore eprosima::fastdds::rtps::BinaryProperty::propagate() const;

fastdds_python/src/swig/fastdds/rtps/common/InstanceHandle.i

Lines changed: 146 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
// limitations under the License.
1414

1515
%{
16+
#include <stdexcept>
17+
#include <vector>
18+
1619
#include "fastdds/rtps/common/InstanceHandle.hpp"
1720

1821
// Define a hash method in global scope for InstanceHandle_t types
@@ -26,60 +29,119 @@ long hash(const eprosima::fastdds::rtps::InstanceHandle_t& handle)
2629
}
2730
return ret;
2831
}
29-
3032
%}
3133

3234
// SWIG does not support type conversion operators correctly unless converted to a normal method
3335
%rename(get_guid) eprosima::fastdds::rtps::InstanceHandle_t::operator const GUID_t&;
3436

3537
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator [] const;
38+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator [];
3639
%ignore eprosima::fastdds::rtps::operator <<(std::ostream&, const InstanceHandle_t&);
3740
%ignore eprosima::fastdds::rtps::operator >>(std::istream&, InstanceHandle_t&);
38-
%rename(read_pointer_cast) eprosima::fastdds::rtps::InstanceHandleValue_t::operator const octet* () const;
39-
%rename(write_pointer_cast) eprosima::fastdds::rtps::InstanceHandleValue_t::operator octet* ();
40-
41-
%typemap(in) eprosima::fastdds::rtps::InstanceHandleValue_t*(eprosima::fastdds::rtps::InstanceHandleValue_t temp)
42-
{
43-
if (PyTuple_Check($input))
44-
{
45-
eprosima::fastdds::rtps::octet* buf = temp;
46-
if (!PyArg_ParseTuple($input, "BBBBBBBBBBBBBBBB",
47-
buf, buf+1, buf+2, buf+3, buf+4, buf+5, buf+6, buf+7, buf+8,
48-
buf+9, buf+10, buf+11, buf+12, buf+13, buf+14, buf+15))
41+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator const octet* () const;
42+
%ignore eprosima::fastdds::rtps::InstanceHandleValue_t::operator octet* ();
43+
44+
%extend eprosima::fastdds::rtps::InstanceHandleValue_t {
45+
46+
// Constructor from a sequence of 16 bytes (tuple/list/bytes/bytearray)
47+
InstanceHandleValue_t(PyObject* seq) {
48+
eprosima::fastdds::rtps::InstanceHandleValue_t* self = new eprosima::fastdds::rtps::InstanceHandleValue_t();
49+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
50+
51+
// Fast-path: bytes
52+
if (PyBytes_Check(seq)) {
53+
if (PyBytes_GET_SIZE(seq) == 16)
54+
{
55+
const char* b = PyBytes_AS_STRING(seq);
56+
for (int i = 0; i < 16; ++i) (*self)[i] = (uint8_t)(unsigned char)b[i];
57+
}
58+
else
59+
{
60+
delete self;
61+
self = nullptr;
62+
PyErr_SetString(PyExc_ValueError, "Expected 16 bytes");
63+
}
64+
}
65+
// Fast-path: bytearray
66+
else if (PyByteArray_Check(seq))
4967
{
50-
PyErr_SetString(PyExc_TypeError, "tuple must have 16 elements");
51-
SWIG_fail;
68+
if (PyByteArray_GET_SIZE(seq) == 16)
69+
{
70+
const char* b = PyByteArray_AS_STRING(seq);
71+
for (int i = 0; i < 16; ++i) (*self)[i] = (uint8_t)(unsigned char)b[i];
72+
}
73+
else
74+
{
75+
delete self;
76+
self = nullptr;
77+
PyErr_SetString(PyExc_ValueError, "Expected 16 bytes");
78+
}
5279
}
53-
$1 = &temp;
54-
}
55-
else
56-
{
57-
PyErr_SetString(PyExc_TypeError, "expected a tuple.");
58-
SWIG_fail;
80+
else
81+
{
82+
// Generic fallback: iterable from 16 ints 0..255
83+
PyObject* it = PyObject_GetIter(seq);
84+
size_t count {0};
85+
if (it)
86+
{
87+
PyObject* item {nullptr};
88+
while ((item = PyIter_Next(it)) && count < 16)
89+
{
90+
long val = PyLong_AsLong(item);
91+
Py_DECREF(item);
92+
if (val == -1 && PyErr_Occurred())
93+
{
94+
delete self;
95+
self = nullptr;
96+
PyErr_SetString(PyExc_TypeError, "Sequence must contain integers");
97+
break;
98+
}
99+
else if (val < 0 || val > 255)
100+
{
101+
delete self;
102+
self = nullptr;
103+
PyErr_SetString(PyExc_ValueError, "Each value must be in 0..255");
104+
break;
105+
}
106+
107+
(*self)[count] = static_cast<uint8_t>(val);
108+
++count;
109+
}
110+
Py_DECREF(it);
111+
if ((nullptr != item || count != 16) && nullptr != self)
112+
{
113+
delete self;
114+
self = nullptr;
115+
PyErr_SetString(PyExc_ValueError, "Expected 16 elements");
116+
}
117+
}
118+
else
119+
{
120+
delete self;
121+
self = nullptr;
122+
PyErr_SetString(PyExc_TypeError, "Expected a sequence of 16 integers (0..255) or 16-byte object");
123+
}
124+
}
125+
126+
SWIG_PYTHON_THREAD_END_BLOCK;
127+
128+
return self;
59129
}
60-
}
61130

62-
%typemap(out) eprosima::fastdds::rtps::InstanceHandleValue_t*
63-
{
64-
constexpr size_t ih_size = std::tuple_size<eprosima::fastdds::rtps::KeyHash_t>::value;
65-
PyObject* python_tuple = PyTuple_New(ih_size);
131+
size_t __len__() const { return 16; }
66132

67-
if (python_tuple)
68-
{
69-
for(size_t count = 0; count < ih_size; ++count)
70-
{
71-
PyTuple_SetItem(python_tuple, count, PyInt_FromLong((*$1)[count]));
72-
}
133+
uint8_t __getitem__(size_t i) const {
134+
if (i >= 16) throw std::out_of_range("index out of range");
135+
return $self->operator[](i);
73136
}
74137

75-
$result = python_tuple;
138+
void __setitem__(size_t i, uint8_t v) {
139+
if (i >= 16) throw std::out_of_range("index out of range");
140+
$self->operator[](i) = v;
141+
}
76142
}
77143

78-
// Template for std::vector<InstanceHandle_t>
79-
%template(InstanceHandleVector) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>;
80-
%typemap(doctype) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>"InstanceHandleVector";
81-
82-
%include "fastdds/rtps/common/InstanceHandle.hpp"
144+
%ignore eprosima::fastdds::rtps::InstanceHandle_t::value;
83145

84146
// Declare the comparison operators as internal to the class
85147
%extend eprosima::fastdds::rtps::InstanceHandle_t {
@@ -106,4 +168,51 @@ long hash(const eprosima::fastdds::rtps::InstanceHandle_t& handle)
106168
{
107169
return hash(*$self);
108170
}
171+
172+
// Setter from sequence (tuple/list/bytes/bytearray)
173+
void from_sequence(PyObject* seq) {
174+
// Reuse the constructor to validate and copy
175+
eprosima::fastdds::rtps::InstanceHandleValue_t* tmp = new_eprosima_fastdds_rtps_InstanceHandleValue_t(seq);
176+
if (nullptr != tmp)
177+
{
178+
for (int i = 0; i < 16; ++i) $self->value[i] = (*tmp)[i];
179+
delete tmp; // avoid memory leak
180+
}
181+
}
182+
183+
// Getter: return a tuple of 16 ints (0..255)
184+
PyObject* to_sequence() const {
185+
SWIG_PYTHON_THREAD_BEGIN_BLOCK;
186+
187+
PyObject* python_tuple = PyTuple_New(16);
188+
189+
if (python_tuple)
190+
{
191+
for(size_t count = 0; count < 16; ++count)
192+
{
193+
PyTuple_SetItem(python_tuple, count, PyInt_FromLong($self->value[count]));
194+
}
195+
}
196+
197+
SWIG_PYTHON_THREAD_END_BLOCK;
198+
199+
return python_tuple;
200+
}
109201
}
202+
203+
// Template for std::vector<InstanceHandle_t>
204+
%template(InstanceHandleVector) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>;
205+
%typemap(doctype) std::vector<eprosima::fastdds::rtps::InstanceHandle_t>"InstanceHandleVector";
206+
207+
%include "fastdds/rtps/common/InstanceHandle.hpp"
208+
209+
%pythoncode %{
210+
def _ihv_get_value(self):
211+
return self.to_sequence()
212+
213+
def _ihv_set_value(self, seq):
214+
self.from_sequence(seq)
215+
216+
InstanceHandle_t.value = property(_ihv_get_value, _ihv_set_value,
217+
doc="16-byte value as list/tuple/bytes/bytearray")
218+
%}

fastdds_python/src/swig/fastdds/rtps/common/Locator.i

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
%}
1818

1919
// Ignore overloaded constructor and methods that have no effect on target language
20+
<<<<<<< HEAD
21+
=======
22+
%copyctor eprosima::fastdds::rtps::Locator_t;
23+
>>>>>>> 6ee4ca5 (Remove compilation warning with InstanceHandle_t (#262))
2024
%ignore eprosima::fastdds::rtps::Locator_t::Locator_t(Locator_t&&);
2125
%ignore eprosima::fastdds::rtps::operator <<(std::ostream&, const Locator_t&);
2226
%ignore eprosima::fastdds::rtps::operator >>(std::istream&, Locator_t&);

fastdds_python/src/swig/fastdds/rtps/common/Property.i

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
%}
1818

1919
// Ignore overloaded constructor and methods that have no effect on target language
20+
<<<<<<< HEAD
2021
%ignore eprosima::fastdds::rtps::Property::Property(Property &&);
22+
=======
23+
%copyctor eprosima::fastdds::rtps::Property;
24+
%ignore eprosima::fastdds::rtps::Property::Property(Property&&);
25+
>>>>>>> 6ee4ca5 (Remove compilation warning with InstanceHandle_t (#262))
2126
%ignore eprosima::fastdds::rtps::Property::name(std::string &&);
2227
%ignore eprosima::fastdds::rtps::Property::value(std::string &&);
2328
%ignore eprosima::fastdds::rtps::Property::propagate() const;

fastdds_python/test/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@
1515
# Compile types
1616
add_subdirectory(types)
1717

18+
# Unit tests
19+
add_test(NAME unit_tests
20+
COMMAND
21+
${Python3_EXECUTABLE}
22+
-m pytest
23+
-vrP
24+
WORKING_DIRECTORY
25+
${CMAKE_CURRENT_SOURCE_DIR}/unittest
26+
)
27+
28+
# DDS Api tests
1829
add_test(NAME api_tests
1930
COMMAND
2031
${Python3_EXECUTABLE}

0 commit comments

Comments
 (0)