Skip to content

Commit b8381d9

Browse files
authored
Move rosidl_cmake Python module to a new package rosidl_pycommon (#696)
* Move common Python functions into new package Deprecate the Python module in rosidl_cmake and move the implementation to the new package rosidl_pycommon. This works towards removing a dependency on rosidl_cmake in generator packages. Signed-off-by: Jacob Perron <[email protected]> * Replace rosidl_cmake imports with rosidl_pycommon Signed-off-by: Jacob Perron <[email protected]>
1 parent da29cb0 commit b8381d9

39 files changed

+364
-222
lines changed

rosidl_cmake/package.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
<buildtool_export_depend>ament_cmake</buildtool_export_depend>
1717
<buildtool_export_depend>python3-empy</buildtool_export_depend>
1818

19-
<exec_depend>rosidl_adapter</exec_depend>
20-
<exec_depend>rosidl_parser</exec_depend>
19+
<!-- Forwarding Python module -->
20+
<exec_depend>rosidl_pycommon</exec_depend>
2121

2222
<test_depend>ament_lint_auto</test_depend>
2323
<test_depend>ament_lint_common</test_depend>

rosidl_cmake/rosidl_cmake/__init__.py

+6-187
Original file line numberDiff line numberDiff line change
@@ -12,192 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from io import StringIO
16-
import json
17-
import os
18-
import pathlib
19-
import re
20-
import sys
15+
import warnings
2116

22-
import em
23-
from rosidl_parser.definition import IdlLocator
24-
from rosidl_parser.parser import parse_idl_file
17+
from rosidl_pycommon import * # noqa: F401, F403
2518

26-
27-
def convert_camel_case_to_lower_case_underscore(value):
28-
# insert an underscore before any upper case letter
29-
# which is followed by a lower case letter
30-
value = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', value)
31-
# insert an underscore before any upper case letter
32-
# which is preseded by a lower case letter or number
33-
value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', value)
34-
return value.lower()
35-
36-
37-
def read_generator_arguments(input_file):
38-
with open(input_file, mode='r', encoding='utf-8') as h:
39-
return json.load(h)
40-
41-
42-
def get_newest_modification_time(target_dependencies):
43-
newest_timestamp = None
44-
for dep in target_dependencies:
45-
ts = os.path.getmtime(dep)
46-
if newest_timestamp is None or ts > newest_timestamp:
47-
newest_timestamp = ts
48-
return newest_timestamp
49-
50-
51-
def generate_files(
52-
generator_arguments_file, mapping, additional_context=None,
53-
keep_case=False, post_process_callback=None
54-
):
55-
args = read_generator_arguments(generator_arguments_file)
56-
57-
template_basepath = pathlib.Path(args['template_dir'])
58-
for template_filename in mapping.keys():
59-
assert (template_basepath / template_filename).exists(), \
60-
'Could not find template: ' + template_filename
61-
62-
latest_target_timestamp = get_newest_modification_time(args['target_dependencies'])
63-
generated_files = []
64-
65-
for idl_tuple in args.get('idl_tuples', []):
66-
idl_parts = idl_tuple.rsplit(':', 1)
67-
assert len(idl_parts) == 2
68-
locator = IdlLocator(*idl_parts)
69-
idl_rel_path = pathlib.Path(idl_parts[1])
70-
idl_stem = idl_rel_path.stem
71-
if not keep_case:
72-
idl_stem = convert_camel_case_to_lower_case_underscore(idl_stem)
73-
try:
74-
idl_file = parse_idl_file(locator)
75-
for template_file, generated_filename in mapping.items():
76-
generated_file = os.path.join(
77-
args['output_dir'], str(idl_rel_path.parent),
78-
generated_filename % idl_stem)
79-
generated_files.append(generated_file)
80-
data = {
81-
'package_name': args['package_name'],
82-
'interface_path': idl_rel_path,
83-
'content': idl_file.content,
84-
}
85-
if additional_context is not None:
86-
data.update(additional_context)
87-
expand_template(
88-
os.path.basename(template_file), data,
89-
generated_file, minimum_timestamp=latest_target_timestamp,
90-
template_basepath=template_basepath,
91-
post_process_callback=post_process_callback)
92-
except Exception as e:
93-
print(
94-
'Error processing idl file: ' +
95-
str(locator.get_absolute_path()), file=sys.stderr)
96-
raise(e)
97-
98-
return generated_files
99-
100-
101-
template_prefix_path = []
102-
103-
104-
def get_template_path(template_name):
105-
global template_prefix_path
106-
for basepath in template_prefix_path:
107-
template_path = basepath / template_name
108-
if template_path.exists():
109-
return template_path
110-
raise RuntimeError(f"Failed to find template '{template_name}'")
111-
112-
113-
interpreter = None
114-
115-
116-
def expand_template(
117-
template_name, data, output_file, minimum_timestamp=None,
118-
template_basepath=None, post_process_callback=None
119-
):
120-
# in the legacy API the first argument was the path to the template
121-
if template_basepath is None:
122-
template_name = pathlib.Path(template_name)
123-
template_basepath = template_name.parent
124-
template_name = template_name.name
125-
126-
global interpreter
127-
output = StringIO()
128-
interpreter = em.Interpreter(
129-
output=output,
130-
options={
131-
em.BUFFERED_OPT: True,
132-
em.RAW_OPT: True,
133-
},
134-
)
135-
136-
global template_prefix_path
137-
template_prefix_path.append(template_basepath)
138-
template_path = get_template_path(template_name)
139-
140-
# create copy before manipulating
141-
data = dict(data)
142-
_add_helper_functions(data)
143-
144-
try:
145-
with template_path.open('r') as h:
146-
template_content = h.read()
147-
interpreter.invoke(
148-
'beforeFile', name=template_name, file=h, locals=data)
149-
interpreter.string(template_content, template_path, locals=data)
150-
interpreter.invoke('afterFile')
151-
except Exception as e: # noqa: F841
152-
if os.path.exists(output_file):
153-
os.remove(output_file)
154-
print(f"{e.__class__.__name__} when expanding '{template_name}' into "
155-
f"'{output_file}': {e}", file=sys.stderr)
156-
raise
157-
finally:
158-
template_prefix_path.pop()
159-
160-
content = output.getvalue()
161-
interpreter.shutdown()
162-
163-
if post_process_callback:
164-
content = post_process_callback(content)
165-
166-
# only overwrite file if necessary
167-
# which is either when the timestamp is too old or when the content is different
168-
if os.path.exists(output_file):
169-
timestamp = os.path.getmtime(output_file)
170-
if minimum_timestamp is None or timestamp > minimum_timestamp:
171-
with open(output_file, 'r', encoding='utf-8') as h:
172-
if h.read() == content:
173-
return
174-
else:
175-
# create folder if necessary
176-
try:
177-
os.makedirs(os.path.dirname(output_file))
178-
except FileExistsError:
179-
pass
180-
181-
with open(output_file, 'w', encoding='utf-8') as h:
182-
h.write(content)
183-
184-
185-
def _add_helper_functions(data):
186-
data['TEMPLATE'] = _expand_template
187-
188-
189-
def _expand_template(template_name, **kwargs):
190-
global interpreter
191-
template_path = get_template_path(template_name)
192-
_add_helper_functions(kwargs)
193-
with template_path.open('r') as h:
194-
interpreter.invoke(
195-
'beforeInclude', name=str(template_path), file=h, locals=kwargs)
196-
content = h.read()
197-
try:
198-
interpreter.string(content, str(template_path), kwargs)
199-
except Exception as e: # noqa: F841
200-
print(f"{e.__class__.__name__} in template '{template_path}': {e}",
201-
file=sys.stderr)
202-
raise
203-
interpreter.invoke('afterInclude')
19+
warnings.warn(
20+
"The 'rosidl_cmake' Python module is deprecated. Use 'rosidl_pycommon' instead.",
21+
UserWarning
22+
)

rosidl_generator_c/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ endif()
1414
find_package(ament_cmake_python REQUIRED)
1515
find_package(ament_cmake_ros REQUIRED)
1616

17-
ament_export_dependencies(rosidl_cmake)
1817
ament_export_dependencies(rosidl_typesupport_interface)
1918
ament_index_register_resource("rosidl_generator_packages")
2019

rosidl_generator_c/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
<buildtool_export_depend>ament_cmake_core</buildtool_export_depend>
1818
<buildtool_export_depend>python3</buildtool_export_depend>
19-
<buildtool_export_depend>rosidl_cmake</buildtool_export_depend>
19+
<buildtool_export_depend>rosidl_pycommon</buildtool_export_depend>
2020

2121
<build_export_depend>rosidl_typesupport_interface</build_export_depend>
2222
<build_export_depend>rcutils</build_export_depend>

rosidl_generator_c/resource/idl.h.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
@#######################################################################
1313
@
1414
@{
15-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
15+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1616
include_parts = [package_name] + list(interface_path.parents[0].parts) + \
1717
[convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1818
include_parts_detail = [package_name] + list(interface_path.parents[0].parts) + [

rosidl_generator_c/resource/idl__functions.c.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
include_base = '/'.join(include_parts)

rosidl_generator_c/resource/idl__functions.h.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \

rosidl_generator_c/resource/idl__struct.h.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \

rosidl_generator_c/resource/idl__type_support.h.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \

rosidl_generator_c/rosidl_generator_c/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
16-
from rosidl_cmake import generate_files
1715
from rosidl_parser.definition import AbstractGenericString
1816
from rosidl_parser.definition import AbstractSequence
1917
from rosidl_parser.definition import AbstractString
@@ -24,6 +22,8 @@
2422
from rosidl_parser.definition import CHARACTER_TYPES
2523
from rosidl_parser.definition import NamespacedType
2624
from rosidl_parser.definition import OCTET_TYPE
25+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
26+
from rosidl_pycommon import generate_files
2727

2828

2929
def generate_c(generator_arguments_file):

rosidl_generator_cpp/CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ project(rosidl_generator_cpp)
55
find_package(ament_cmake REQUIRED)
66
find_package(ament_cmake_python REQUIRED)
77

8-
ament_export_dependencies(rosidl_cmake)
9-
108
ament_index_register_resource("rosidl_generator_packages")
119

1210
ament_python_install_package(${PROJECT_NAME})

rosidl_generator_cpp/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
<buildtool_export_depend>ament_cmake_core</buildtool_export_depend>
1616
<buildtool_export_depend>python3</buildtool_export_depend>
17-
<buildtool_export_depend>rosidl_cmake</buildtool_export_depend>
17+
<buildtool_export_depend>rosidl_pycommon</buildtool_export_depend>
1818

1919
<!-- This is needed for the rosidl_message_type_support_t struct and visibility macros -->
2020
<build_export_depend>rosidl_generator_c</build_export_depend>

rosidl_generator_cpp/resource/idl.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@#######################################################################
1212
@
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + \
1616
[convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
include_parts_detail = [package_name] + list(interface_path.parents[0].parts) + [

rosidl_generator_cpp/resource/idl__builder.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
include_base = '/'.join(include_parts)

rosidl_generator_cpp/resource/idl__struct.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
header_guard_variable = '__'.join([x.upper() for x in include_parts]) + \

rosidl_generator_cpp/resource/idl__traits.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
@# - content (IdlContent, list of elements, e.g. Messages or Services)
1212
@#######################################################################
1313
@{
14-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
14+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
1515
include_parts = [package_name] + list(interface_path.parents[0].parts) + [
1616
'detail', convert_camel_case_to_lower_case_underscore(interface_path.stem)]
1717
include_base = '/'.join(include_parts)

rosidl_generator_cpp/resource/msg__struct.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ msvc_common_macros = ('DELETE', 'ERROR', 'NO_ERROR')
3030
@# Collect necessary include directives for all members
3131
@{
3232
from collections import OrderedDict
33-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
33+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
3434
includes = OrderedDict()
3535
for member in message.structure.members:
3636
type_ = member.type

rosidl_generator_cpp/resource/msg__traits.hpp.em

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ message_fully_qualified_name = '/'.join(message.structure.namespaced_type.namesp
2121
@# Collect necessary include directives for all members
2222
@{
2323
from collections import OrderedDict
24-
from rosidl_cmake import convert_camel_case_to_lower_case_underscore
24+
from rosidl_pycommon import convert_camel_case_to_lower_case_underscore
2525
includes = OrderedDict()
2626
for member in message.structure.members:
2727
type_ = member.type

rosidl_generator_cpp/rosidl_generator_cpp/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
from ast import literal_eval
1616

17-
from rosidl_cmake import generate_files
1817
from rosidl_parser.definition import AbstractGenericString
1918
from rosidl_parser.definition import AbstractNestedType
2019
from rosidl_parser.definition import AbstractSequence
@@ -26,6 +25,7 @@
2625
from rosidl_parser.definition import FLOATING_POINT_TYPES
2726
from rosidl_parser.definition import NamespacedType
2827
from rosidl_parser.definition import UnboundedSequence
28+
from rosidl_pycommon import generate_files
2929

3030

3131
def generate_cpp(generator_arguments_file):

0 commit comments

Comments
 (0)