idl-parser 0.2.2__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. {idl_parser-0.2.2 → idl_parser-0.3.2}/.github/workflows/test.yml +26 -0
  2. {idl_parser-0.2.2 → idl_parser-0.3.2}/.gitignore +2 -0
  3. idl_parser-0.3.2/.vscode/extensions.json +6 -0
  4. idl_parser-0.3.2/.vscode/launch.json +21 -0
  5. idl_parser-0.3.2/.vscode/settings.json +23 -0
  6. {idl_parser-0.2.2/idl_parser.egg-info → idl_parser-0.3.2}/PKG-INFO +11 -3
  7. {idl_parser-0.2.2 → idl_parser-0.3.2}/README.md +6 -1
  8. {idl_parser-0.2.2 → idl_parser-0.3.2}/README.rst +10 -2
  9. idl_parser-0.3.2/examples/argument_direction_example.py +75 -0
  10. idl_parser-0.3.2/examples/enum_example.py +68 -0
  11. idl_parser-0.3.2/examples/example.py +37 -0
  12. idl_parser-0.3.2/examples/scoped_name_example.py +121 -0
  13. idl_parser-0.3.2/examples/struct_example.py +72 -0
  14. idl_parser-0.3.2/idl_parser/__init__.py +18 -0
  15. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/bitmask.py +26 -1
  16. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/bitset.py +27 -0
  17. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/const.py +24 -1
  18. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/enum.py +40 -1
  19. idl_parser-0.3.2/idl_parser/exception.py +80 -0
  20. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/interface.py +68 -0
  21. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/module.py +213 -31
  22. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/node.py +79 -7
  23. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/parser.py +80 -0
  24. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/pragma.py +3 -0
  25. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/struct.py +70 -10
  26. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/token_buffer.py +9 -0
  27. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/type.py +103 -2
  28. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/typedef.py +39 -1
  29. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser/union.py +61 -4
  30. {idl_parser-0.2.2 → idl_parser-0.3.2/idl_parser.egg-info}/PKG-INFO +11 -3
  31. idl_parser-0.3.2/idl_parser.egg-info/SOURCES.txt +128 -0
  32. idl_parser-0.3.2/idl_parser.egg-info/scm_file_list.json +126 -0
  33. idl_parser-0.3.2/idl_parser.egg-info/scm_version.json +8 -0
  34. idl_parser-0.3.2/tests/README.md +67 -0
  35. idl_parser-0.3.2/tests/__init__.py +0 -0
  36. idl_parser-0.3.2/tests/annotation/__init__.py +0 -0
  37. {idl_parser-0.2.2/tests → idl_parser-0.3.2/tests/annotation}/annotation_test.py +58 -0
  38. idl_parser-0.3.2/tests/annotation/bit_bound_scope_test.py +45 -0
  39. idl_parser-0.3.2/tests/annotation/string_argument_test.py +39 -0
  40. idl_parser-0.3.2/tests/bitmask_bitset/__init__.py +0 -0
  41. {idl_parser-0.2.2/tests → idl_parser-0.3.2/tests/bitmask_bitset}/bitmask_bitset_test.py +59 -17
  42. idl_parser-0.3.2/tests/examples/__init__.py +0 -0
  43. idl_parser-0.3.2/tests/examples/examples_test.py +402 -0
  44. idl_parser-0.3.2/tests/forward_declaration/__init__.py +0 -0
  45. idl_parser-0.3.2/tests/forward_declaration/element_type_forward_test.py +64 -0
  46. idl_parser-0.2.2/tests/forward_declaration_test.py → idl_parser-0.3.2/tests/forward_declaration/interface_forward_test.py +85 -3
  47. idl_parser-0.2.2/tests/issue57_test.py → idl_parser-0.3.2/tests/forward_declaration/struct_union_forward_test.py +83 -0
  48. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/invalid_idl.idl +1 -1
  49. idl_parser-0.3.2/tests/include/__init__.py +0 -0
  50. idl_parser-0.2.2/tests/include_test.py → idl_parser-0.3.2/tests/include/circular_include_test.py +20 -2
  51. idl_parser-0.3.2/tests/include/include_dirs_test.py +46 -0
  52. idl_parser-0.2.2/tests/issue12_test.py → idl_parser-0.3.2/tests/include/subpath_include_test.py +20 -4
  53. idl_parser-0.3.2/tests/interface/__init__.py +0 -0
  54. idl_parser-0.3.2/tests/interface/argument_direction_test.py +77 -0
  55. idl_parser-0.3.2/tests/interface/basic_module_test.py +63 -0
  56. idl_parser-0.2.2/tests/generalization_test.py → idl_parser-0.3.2/tests/interface/inheritance_test.py +112 -66
  57. idl_parser-0.2.2/tests/issue45_test.py → idl_parser-0.3.2/tests/interface/raises_context_test.py +70 -0
  58. idl_parser-0.3.2/tests/lexing/__init__.py +0 -0
  59. idl_parser-0.3.2/tests/lexing/basic_module_test.py +55 -0
  60. idl_parser-0.2.2/tests/issue53_test.py → idl_parser-0.3.2/tests/lexing/bracket_spacing_test.py +80 -0
  61. idl_parser-0.3.2/tests/lexing/error_line_number_test.py +33 -0
  62. idl_parser-0.3.2/tests/lexing/exception_message_test.py +113 -0
  63. idl_parser-0.2.2/tests/issue9_test.py → idl_parser-0.3.2/tests/lexing/opensplice_idl_test.py +19 -1
  64. idl_parser-0.2.2/tests/issue50_test.py → idl_parser-0.3.2/tests/lexing/string_literal_comment_test.py +39 -1
  65. idl_parser-0.3.2/tests/lexing/token_split_test.py +51 -0
  66. idl_parser-0.3.2/tests/output/__init__.py +0 -0
  67. idl_parser-0.2.2/tests/issue43_test.py → idl_parser-0.3.2/tests/output/constructor_python_test.py +17 -0
  68. idl_parser-0.3.2/tests/output/simple_dic_enum_test.py +101 -0
  69. idl_parser-0.3.2/tests/output/simple_dic_inherits_test.py +101 -0
  70. idl_parser-0.2.2/tests/simple_dic_test.py → idl_parser-0.3.2/tests/output/simple_dic_member_only_test.py +14 -4
  71. idl_parser-0.2.2/tests/issue30_test.py → idl_parser-0.3.2/tests/output/simple_dic_member_type_test.py +30 -1
  72. idl_parser-0.3.2/tests/pragma_key/__init__.py +0 -0
  73. {idl_parser-0.2.2/tests → idl_parser-0.3.2/tests/pragma_key}/key_annotation_test.py +58 -0
  74. idl_parser-0.3.2/tests/pragma_key/keylist_validation_test.py +135 -0
  75. {idl_parser-0.2.2/tests → idl_parser-0.3.2/tests/pragma_key}/pragma_test.py +72 -82
  76. idl_parser-0.3.2/tests/primitive_const/__init__.py +0 -0
  77. idl_parser-0.3.2/tests/primitive_const/basic_module_test.py +86 -0
  78. idl_parser-0.2.2/tests/issue52_test.py → idl_parser-0.3.2/tests/primitive_const/const_test.py +56 -42
  79. idl_parser-0.2.2/tests/issue18_test.py → idl_parser-0.3.2/tests/primitive_const/int_types_test.py +27 -1
  80. idl_parser-0.3.2/tests/scope/__init__.py +0 -0
  81. idl_parser-0.3.2/tests/scope/basename_test.py +38 -0
  82. idl_parser-0.3.2/tests/scope/basic_module_test.py +39 -0
  83. idl_parser-0.3.2/tests/scope/leading_scope_test.py +115 -0
  84. idl_parser-0.2.2/tests/multimodule_test.py → idl_parser-0.3.2/tests/scope/multi_module_test.py +19 -30
  85. idl_parser-0.3.2/tests/scope/same_name_resolution_test.py +204 -0
  86. idl_parser-0.3.2/tests/scope/unknown_word_test.py +165 -0
  87. idl_parser-0.2.2/tests/issue39_test.py → idl_parser-0.3.2/tests/scope/unsupported_block_scope_test.py +17 -0
  88. idl_parser-0.3.2/tests/sequence_array/__init__.py +0 -0
  89. idl_parser-0.3.2/tests/sequence_array/basic_module_test.py +111 -0
  90. idl_parser-0.3.2/tests/sequence_array/element_type_test.py +164 -0
  91. idl_parser-0.2.2/tests/issue31_test.py → idl_parser-0.3.2/tests/sequence_array/nested_bounded_sequence_test.py +49 -0
  92. idl_parser-0.3.2/tests/sequence_array/syntax_error_test.py +29 -0
  93. idl_parser-0.3.2/tests/struct_enum_union/__init__.py +0 -0
  94. idl_parser-0.3.2/tests/struct_enum_union/basic_module_test.py +126 -0
  95. {idl_parser-0.2.2/tests → idl_parser-0.3.2/tests/struct_enum_union}/syntax_error_test.py +10 -8
  96. idl_parser-0.2.2/tests/issue49_test.py → idl_parser-0.3.2/tests/struct_enum_union/union_char_label_test.py +25 -0
  97. idl_parser-0.2.2/tests/issue48_test.py → idl_parser-0.3.2/tests/struct_enum_union/union_default_label_test.py +70 -0
  98. idl_parser-0.3.2/tests/support.py +6 -0
  99. idl_parser-0.2.2/examples/example.py +0 -101
  100. idl_parser-0.2.2/idl_parser/__init__.py +0 -7
  101. idl_parser-0.2.2/idl_parser/exception.py +0 -37
  102. idl_parser-0.2.2/idl_parser.egg-info/SOURCES.txt +0 -85
  103. idl_parser-0.2.2/idl_parser.egg-info/scm_file_list.json +0 -83
  104. idl_parser-0.2.2/idl_parser.egg-info/scm_version.json +0 -8
  105. idl_parser-0.2.2/tests/__init__.py +0 -1
  106. idl_parser-0.2.2/tests/examples_test.py +0 -178
  107. idl_parser-0.2.2/tests/invalid_idl_test.py +0 -35
  108. idl_parser-0.2.2/tests/module_test.py +0 -301
  109. {idl_parser-0.2.2 → idl_parser-0.3.2}/.github/workflows/release.yml +0 -0
  110. {idl_parser-0.2.2 → idl_parser-0.3.2}/.readthedocs.yaml +0 -0
  111. {idl_parser-0.2.2 → idl_parser-0.3.2}/LICENSE +0 -0
  112. {idl_parser-0.2.2 → idl_parser-0.3.2}/docs/api/index.rst +0 -0
  113. {idl_parser-0.2.2 → idl_parser-0.3.2}/docs/conf.py +0 -0
  114. {idl_parser-0.2.2 → idl_parser-0.3.2}/docs/index.rst +0 -0
  115. {idl_parser-0.2.2 → idl_parser-0.3.2}/docs/requirements.txt +0 -0
  116. {idl_parser-0.2.2 → idl_parser-0.3.2}/examples/_path.py +0 -0
  117. {idl_parser-0.2.2 → idl_parser-0.3.2}/examples/annotation_example.py +0 -0
  118. {idl_parser-0.2.2 → idl_parser-0.3.2}/examples/union_example.py +0 -0
  119. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser.egg-info/dependency_links.txt +0 -0
  120. {idl_parser-0.2.2 → idl_parser-0.3.2}/idl_parser.egg-info/top_level.txt +0 -0
  121. {idl_parser-0.2.2 → idl_parser-0.3.2}/pyproject.toml +0 -0
  122. {idl_parser-0.2.2 → idl_parser-0.3.2}/setup.cfg +0 -0
  123. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/basic_module_test.idl +0 -0
  124. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/circular/circular_a.idl +0 -0
  125. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/circular/circular_b.idl +0 -0
  126. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/circular/diamond.idl +0 -0
  127. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/forward_declaration.idl +0 -0
  128. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/generalization.idl +0 -0
  129. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/generalization_extended.idl +0 -0
  130. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/included_idl.idl +0 -0
  131. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/including_idl.idl +0 -0
  132. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue12_subpath/relative_include.idl +0 -0
  133. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue12_subpath/sensor_msgs/msg/Imu.idl +0 -0
  134. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue12_subpath/std/msg/Header.idl +0 -0
  135. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue18_idl42_int_types.idl +0 -0
  136. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue28_pragma_keylist.idl +0 -0
  137. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue9_const_pragma.idl +0 -0
  138. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue9_tabs_bounded_string.idl +0 -0
  139. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/issue9_whitespace_variants.idl +0 -0
  140. {idl_parser-0.2.2 → idl_parser-0.3.2}/tests/idls/multi_module_test.idl +0 -0
@@ -33,6 +33,32 @@ jobs:
33
33
  - name: Run tests
34
34
  run: python -m unittest discover --start-directory tests --pattern '*_test.py' --top-level-directory . --verbose
35
35
 
36
+ coverage:
37
+ name: Coverage
38
+ runs-on: ubuntu-latest
39
+ steps:
40
+ - uses: actions/checkout@v5
41
+
42
+ - uses: actions/setup-python@v6
43
+ with:
44
+ python-version: "3.12"
45
+
46
+ - name: Run tests with coverage
47
+ run: |
48
+ python -m pip install coverage
49
+ python -m coverage run --branch --source=idl_parser -m unittest discover --start-directory tests --pattern '*_test.py' --top-level-directory .
50
+ python -m coverage report
51
+ python -m coverage xml
52
+
53
+ # Uploads coverage.xml to Codecov, which serves the README badge.
54
+ # Without the CODECOV_TOKEN secret the upload may be rejected; that
55
+ # must not fail the tests, so errors are not fatal.
56
+ - uses: codecov/codecov-action@v5
57
+ with:
58
+ files: coverage.xml
59
+ token: ${{ secrets.CODECOV_TOKEN }}
60
+ fail_ci_if_error: false
61
+
36
62
  lint:
37
63
  name: Check undefined names
38
64
  runs-on: ubuntu-latest
@@ -4,3 +4,5 @@
4
4
  build/*
5
5
  dist/*docs/_build/
6
6
  docs/api/generated/
7
+ coverage.xml
8
+ .coverage
@@ -0,0 +1,6 @@
1
+ {
2
+ "recommendations": [
3
+ "ms-python.python",
4
+ "ms-python.vscode-pylance"
5
+ ]
6
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Python: unittest discover",
6
+ "type": "python",
7
+ "request": "launch",
8
+ "module": "unittest",
9
+ "args": [
10
+ "discover",
11
+ "-s",
12
+ "tests",
13
+ "-p",
14
+ "*_test.py",
15
+ "-v"
16
+ ],
17
+ "cwd": "${workspaceFolder}",
18
+ "justMyCode": true
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "python.testing.unittestEnabled": true,
3
+ "python.testing.pytestEnabled": false,
4
+ "python.testing.unittestArgs": [
5
+ "-v",
6
+ "-s",
7
+ "${workspaceFolder}/tests",
8
+ "-p",
9
+ "*_test.py"
10
+ ],
11
+ "python.testing.cwd": "${workspaceFolder}",
12
+ "python.analysis.typeCheckingMode": "basic",
13
+ "python.analysis.autoImportCompletions": true,
14
+ "python.analysis.diagnosticMode": "workspace",
15
+ "files.trimTrailingWhitespace": true,
16
+ "editor.formatOnSave": true,
17
+ "editor.rulers": [
18
+ 88
19
+ ],
20
+ "terminal.integrated.env.osx": {
21
+ "PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"
22
+ }
23
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: idl_parser
3
- Version: 0.2.2
3
+ Version: 0.3.2
4
4
  Summary: Very simple OMG IDL (Interface Definition Language) parser. This parses IDL files and outputs intermediate class objects.
5
5
  Author-email: ysuga <ysuga@ysuga.net>
6
6
  License-Expression: GPL-3.0-or-later
@@ -24,7 +24,7 @@ Dynamic: license-file
24
24
  idl_parser
25
25
  ============
26
26
 
27
- |Test Status| |Docs Status|
27
+ |Test Status| |Coverage| |Docs Status|
28
28
 
29
29
  Description
30
30
  -----------
@@ -99,9 +99,13 @@ Example
99
99
 
100
100
  More examples are in the ``examples`` folder of the repository:
101
101
 
102
- - ``example.py``: interfaces, typedefs, unions and structs
102
+ - ``example.py``: the smallest example: a module and an interface
103
+ - ``argument_direction_example.py``: directions of method arguments (``in``, ``out`` and ``inout``)
104
+ - ``struct_example.py``: structs and their member types
105
+ - ``enum_example.py``: enums and their values
103
106
  - ``union_example.py``: unions (discriminator kinds, case and ``default`` labels, member types)
104
107
  - ``annotation_example.py``: IDL 4 annotations (``@key``, ``@range``, ...) and struct keys
108
+ - ``scoped_name_example.py``: same-named types in several modules (relative ``X``, ``C::X`` and absolute ``::B::X`` names)
105
109
 
106
110
  https://github.com/sugarsweetrobotics/idl_parser/tree/main/examples
107
111
 
@@ -128,3 +132,7 @@ Copyright
128
132
  .. |Docs Status| image:: https://readthedocs.org/projects/idl-parser/badge/?version=latest
129
133
  :target: https://idl-parser.readthedocs.io/en/latest/
130
134
  :alt: Documentation Status
135
+
136
+ .. |Coverage| image:: https://codecov.io/gh/sugarsweetrobotics/idl_parser/branch/main/graph/badge.svg
137
+ :target: https://codecov.io/gh/sugarsweetrobotics/idl_parser
138
+ :alt: Coverage
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Test](https://github.com/sugarsweetrobotics/idl_parser/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/sugarsweetrobotics/idl_parser/actions/workflows/test.yml)
4
4
  [![Documentation Status](https://readthedocs.org/projects/idl-parser/badge/?version=latest)](https://idl-parser.readthedocs.io/en/latest/)
5
+ [![codecov](https://codecov.io/gh/sugarsweetrobotics/idl_parser/branch/main/graph/badge.svg)](https://codecov.io/gh/sugarsweetrobotics/idl_parser)
5
6
 
6
7
 
7
8
  ## Description
@@ -74,9 +75,13 @@ More examples are in the [examples](examples/) folder:
74
75
 
75
76
  | File | Shows |
76
77
  |---|---|
77
- | [`example.py`](examples/example.py) | interfaces, typedefs, unions and structs |
78
+ | [`example.py`](examples/example.py) | the smallest example: a module and an interface |
79
+ | [`argument_direction_example.py`](examples/argument_direction_example.py) | directions of method arguments: `in`, `out` and `inout` |
80
+ | [`struct_example.py`](examples/struct_example.py) | structs and their member types |
81
+ | [`enum_example.py`](examples/enum_example.py) | enums and their values |
78
82
  | [`union_example.py`](examples/union_example.py) | unions: discriminator kinds, case and `default` labels, member types |
79
83
  | [`annotation_example.py`](examples/annotation_example.py) | IDL 4 annotations (`@key`, `@range`, ...) and struct keys |
84
+ | [`scoped_name_example.py`](examples/scoped_name_example.py) | same-named types in several modules: relative (`X`, `C::X`) and absolute (`::B::X`) names |
80
85
 
81
86
  Run them with e.g. `python examples/union_example.py` (in a source checkout no install is needed).
82
87
 
@@ -1,7 +1,7 @@
1
1
  idl_parser
2
2
  ============
3
3
 
4
- |Test Status| |Docs Status|
4
+ |Test Status| |Coverage| |Docs Status|
5
5
 
6
6
  Description
7
7
  -----------
@@ -76,9 +76,13 @@ Example
76
76
 
77
77
  More examples are in the ``examples`` folder of the repository:
78
78
 
79
- - ``example.py``: interfaces, typedefs, unions and structs
79
+ - ``example.py``: the smallest example: a module and an interface
80
+ - ``argument_direction_example.py``: directions of method arguments (``in``, ``out`` and ``inout``)
81
+ - ``struct_example.py``: structs and their member types
82
+ - ``enum_example.py``: enums and their values
80
83
  - ``union_example.py``: unions (discriminator kinds, case and ``default`` labels, member types)
81
84
  - ``annotation_example.py``: IDL 4 annotations (``@key``, ``@range``, ...) and struct keys
85
+ - ``scoped_name_example.py``: same-named types in several modules (relative ``X``, ``C::X`` and absolute ``::B::X`` names)
82
86
 
83
87
  https://github.com/sugarsweetrobotics/idl_parser/tree/main/examples
84
88
 
@@ -105,3 +109,7 @@ Copyright
105
109
  .. |Docs Status| image:: https://readthedocs.org/projects/idl-parser/badge/?version=latest
106
110
  :target: https://idl-parser.readthedocs.io/en/latest/
107
111
  :alt: Documentation Status
112
+
113
+ .. |Coverage| image:: https://codecov.io/gh/sugarsweetrobotics/idl_parser/branch/main/graph/badge.svg
114
+ :target: https://codecov.io/gh/sugarsweetrobotics/idl_parser
115
+ :alt: Coverage
@@ -0,0 +1,75 @@
1
+ """Example: read the direction of interface method arguments (in / out / inout).
2
+
3
+ In IDL each argument of a method has a direction:
4
+
5
+ - ``in``: the caller passes a value to the method,
6
+ - ``out``: the method returns a value to the caller through the argument,
7
+ - ``inout``: the caller passes a value and the method may change it.
8
+
9
+ Shows how to
10
+ - read each argument's direction (``direction``),
11
+ - pick the arguments the caller sends and the ones it receives,
12
+ - build a simple call signature from the directions.
13
+
14
+ Run::
15
+
16
+ python examples/argument_direction_example.py
17
+ """
18
+ import _path # noqa: F401 (use the idl_parser of this checkout)
19
+
20
+ from idl_parser import parser
21
+
22
+ IDL = '''
23
+ module my_module {
24
+ interface Counter {
25
+ // in: the value is only passed to the method
26
+ void set(in long value);
27
+
28
+ // out: the value is only returned from the method
29
+ void get(out long value);
30
+
31
+ // inout: the value is passed, changed and returned
32
+ void increment(inout long value);
33
+
34
+ // directions can be mixed in one method
35
+ boolean divide(in double a, in double b, out double quotient, inout long count);
36
+ };
37
+ };
38
+ '''
39
+
40
+
41
+ def main():
42
+ global_module = parser.IDLParser().load(IDL)
43
+ counter = global_module.module_by_name('my_module').interface_by_name('Counter')
44
+
45
+ print('== Direction of each argument')
46
+ for m in counter.methods:
47
+ for a in m.arguments:
48
+ print(' %-10s %-9s %-6s %s' % (m.name, a.name, a.direction, a.type.name))
49
+ print()
50
+
51
+ # in and inout arguments are sent by the caller,
52
+ # out and inout arguments (and the return value) come back to the caller.
53
+ print('== What the caller sends and receives')
54
+ for m in counter.methods:
55
+ sends = [a.name for a in m.arguments if a.direction in ('in', 'inout')]
56
+ receives = [a.name for a in m.arguments if a.direction in ('out', 'inout')]
57
+ if m.returns.name != 'void':
58
+ receives.insert(0, '(return %s)' % m.returns.name)
59
+ print(' %-10s sends: %-14s receives: %s' % (m.name, ', '.join(sends) or '-', ', '.join(receives) or '-'))
60
+ print()
61
+
62
+ # For example, a Python-like signature: in/inout become parameters,
63
+ # out/inout and the return value become results.
64
+ print('== Python-like signatures')
65
+ for m in counter.methods:
66
+ params = [a.name for a in m.arguments if a.direction in ('in', 'inout')]
67
+ results = [a.name for a in m.arguments if a.direction in ('out', 'inout')]
68
+ if m.returns.name != 'void':
69
+ results.insert(0, 'result')
70
+ call = '%s(%s)' % (m.name, ', '.join(params))
71
+ print(' %s' % ('%s = %s' % (', '.join(results), call) if results else call))
72
+
73
+
74
+ if __name__ == '__main__':
75
+ main()
@@ -0,0 +1,68 @@
1
+ """Example: read enums and their values.
2
+
3
+ Shows how to get
4
+ - the enums in a module (``enums``, ``enum_by_name``),
5
+ - each enumerator's name and ordinal (``values``, ``value``),
6
+ - an enumerator by name (``value_by_name``),
7
+ - an enum used as a struct member and as a method return type.
8
+
9
+ Run::
10
+
11
+ python examples/enum_example.py
12
+ """
13
+ import _path # noqa: F401 (use the idl_parser of this checkout)
14
+
15
+ from idl_parser import parser
16
+
17
+ IDL = '''
18
+ module my_module {
19
+ enum Color {
20
+ RED,
21
+ GREEN,
22
+ BLUE
23
+ };
24
+
25
+ enum ReturnCode {
26
+ RETURN_OK,
27
+ RETURN_ERROR,
28
+ RETURN_TIMEOUT
29
+ };
30
+
31
+ struct Light {
32
+ Color color;
33
+ double brightness;
34
+ };
35
+
36
+ interface LightController {
37
+ ReturnCode setColor(in Color color);
38
+ };
39
+ };
40
+ '''
41
+
42
+
43
+ def main():
44
+ global_module = parser.IDLParser().load(IDL)
45
+ my_module = global_module.module_by_name('my_module')
46
+
47
+ print('enums in my_module:', [e.name for e in my_module.enums])
48
+ print()
49
+
50
+ color = my_module.enum_by_name('Color')
51
+ print('enum %s' % color.full_path)
52
+ for v in color.values:
53
+ print(' %s = %d' % (v.name, v.value))
54
+ print('BLUE is', color.value_by_name('BLUE').value)
55
+ print()
56
+
57
+ # A struct member whose type is an enum
58
+ light = my_module.struct_by_name('Light')
59
+ member = light.member_by_name('color')
60
+ print('Light.color is enum? %s (%s)' % (member.type.is_enum, member.type.full_path))
61
+
62
+ # An enum as a method return type
63
+ method = my_module.interface_by_name('LightController').method_by_name('setColor')
64
+ print('setColor returns %s' % method.returns.name)
65
+
66
+
67
+ if __name__ == '__main__':
68
+ main()
@@ -0,0 +1,37 @@
1
+ """Example: parse an IDL string and print the methods of an interface.
2
+
3
+ Run (no install needed in a checkout)::
4
+
5
+ python examples/example.py
6
+
7
+ See also ``struct_example.py``, ``enum_example.py``, ``union_example.py``,
8
+ ``annotation_example.py`` and ``scoped_name_example.py`` in this folder.
9
+ """
10
+ import _path # noqa: F401 (use the idl_parser of this checkout)
11
+
12
+ from idl_parser import parser
13
+
14
+ IDL = '''
15
+ module my_module {
16
+ interface Calculator {
17
+ long add(in long a, in long b);
18
+ void reset();
19
+ boolean divide(in double a, in double b, out double result);
20
+ };
21
+ };
22
+ '''
23
+
24
+
25
+ def main():
26
+ global_module = parser.IDLParser().load(IDL)
27
+ my_module = global_module.module_by_name('my_module')
28
+ calculator = my_module.interface_by_name('Calculator')
29
+
30
+ print('interface %s' % calculator.full_path)
31
+ for m in calculator.methods:
32
+ args = ', '.join('%s %s %s' % (a.direction, a.type.name, a.name) for a in m.arguments)
33
+ print(' %s %s(%s)' % (m.returns.name, m.name, args))
34
+
35
+
36
+ if __name__ == '__main__':
37
+ main()
@@ -0,0 +1,121 @@
1
+ """Example: resolve type names across modules (relative and absolute names).
2
+
3
+ When several modules define a type with the same name, a type name is
4
+ resolved with the IDL scoping rules (issues #69, #72):
5
+
6
+ - a relative name (``X``, ``C::X``) is looked up from the scope where it is
7
+ written, innermost first, then in the outer scopes;
8
+ - an absolute name (``::B::X``) is looked up from the global scope only.
9
+
10
+ Shows how to get
11
+ - the definition a member, argument or return type refers to (``obj`` / ``type``),
12
+ - the name as written (``ref_name``) and the name of the definition (``name``),
13
+ - a typedef resolved in the scope where it is defined,
14
+ - ``find_types()`` with and without a scope.
15
+
16
+ Run::
17
+
18
+ python examples/scoped_name_example.py
19
+ """
20
+ import _path # noqa: F401 (use the idl_parser of this checkout)
21
+
22
+ from idl_parser import parser
23
+
24
+ IDL = '''
25
+ // A global Point, and a Point in each module
26
+ struct Point { long id; };
27
+
28
+ module geometry {
29
+ struct Point { double x; double y; };
30
+ typedef Point Origin; // geometry::Point (the scope of the typedef)
31
+
32
+ module d3 {
33
+ struct Point { double x; double y; double z; };
34
+ };
35
+ };
36
+
37
+ module robot {
38
+ struct Point { long joint; };
39
+
40
+ module arm {
41
+ struct Point { double angle; };
42
+
43
+ interface Controller {
44
+ // relative names: looked up from robot::arm, then robot, then global
45
+ Point current(); // robot::arm::Point
46
+ void move_joint(in robot::Point p); // robot::Point
47
+ void move_to(in geometry::Point p); // geometry::Point
48
+ void move_to_3d(in geometry::d3::Point p);
49
+ // absolute names: from the global scope only
50
+ void mark(in ::Point p); // the global Point
51
+ void move_arm(in ::robot::arm::Point p);
52
+ geometry::Origin origin(); // typedef of geometry::Point
53
+ };
54
+ };
55
+
56
+ struct Pose {
57
+ Point joint; // robot::Point
58
+ arm::Point arm; // relative name with a scope: robot::arm::Point
59
+ sequence<geometry::Point> path; // element type is resolved too
60
+ ::Point marker; // the global Point
61
+ };
62
+ };
63
+ '''
64
+
65
+
66
+ def path(node):
67
+ """Full path of a definition ('' for the global scope is shown as '::')."""
68
+ p = node.full_path.lstrip(':')
69
+ return p if '::' in p else '::' + p
70
+
71
+
72
+ def show(label, written, definition):
73
+ print(' %-22s %-24s -> %s' % (label, written, path(definition)))
74
+
75
+
76
+ def main():
77
+ global_module = parser.IDLParser().load(IDL)
78
+ robot = global_module.module_by_name('robot')
79
+ arm = robot.module_by_name('arm')
80
+
81
+ print('robot::arm::Controller (name as written -> definition)')
82
+ controller = arm.interface_by_name('Controller')
83
+ for method in controller.methods:
84
+ if method.returns.name != 'void':
85
+ show(method.name + '() returns', method.returns.ref_name, method.returns.obj)
86
+ for a in method.arguments:
87
+ show(method.name + '(' + a.name + ')', a.type.ref_name, a.type.obj)
88
+ print()
89
+
90
+ # For a struct member, .type is the definition itself
91
+ print('robot::Pose members (member -> definition)')
92
+ pose = robot.struct_by_name('Pose')
93
+ for m in pose.members:
94
+ t = m.type
95
+ if t.is_sequence:
96
+ print(' %-22s -> sequence of %s' % (m.name, path(t.inner_type.obj)))
97
+ else:
98
+ print(' %-22s -> %s' % (m.name, path(t)))
99
+ print()
100
+
101
+ # The typedef is resolved where it is defined (module geometry),
102
+ # not where it is used (module robot::arm).
103
+ typedef = controller.method_by_name('origin').returns.obj
104
+ print('typedef %s -> %s' % (path(typedef), path(typedef.type)))
105
+ print()
106
+
107
+ # type.name is the name of the definition, without its scope
108
+ t = controller.method_by_name('move_to').arguments[0].type
109
+ print('name: %s, ref_name: %s, full path: %s' % (t.name, t.ref_name, path(t.obj)))
110
+ print()
111
+
112
+ # find_types(): with a scope the IDL scoping rules are used;
113
+ # without one, every definition with that name is returned.
114
+ print('find_types("Point", scope=robot::arm):', [path(n) for n in global_module.find_types('Point', scope=arm)])
115
+ print('find_types("Point", scope=robot): ', [path(n) for n in global_module.find_types('Point', scope=robot)])
116
+ print('find_types("::Point"): ', [path(n) for n in global_module.find_types('::Point')])
117
+ print('find_types("Point") (no scope): ', sorted(path(n) for n in global_module.find_types('Point')))
118
+
119
+
120
+ if __name__ == '__main__':
121
+ main()
@@ -0,0 +1,72 @@
1
+ """Example: read structs and their members.
2
+
3
+ Shows how to get
4
+ - the structs in a module (``structs``, ``struct_by_name``),
5
+ - each member's name and type (primitive, struct, sequence, array),
6
+ - a member by name (``member_by_name``) and a nested struct's members.
7
+
8
+ Run::
9
+
10
+ python examples/struct_example.py
11
+ """
12
+ import _path # noqa: F401 (use the idl_parser of this checkout)
13
+
14
+ from idl_parser import parser
15
+
16
+ IDL = '''
17
+ module my_module {
18
+ struct Time {
19
+ long sec;
20
+ long nsec;
21
+ };
22
+
23
+ struct Pose {
24
+ double position[3];
25
+ double orientation[4];
26
+ };
27
+
28
+ struct Odometry {
29
+ Time stamp;
30
+ string frame_id;
31
+ Pose pose;
32
+ sequence<double> covariance;
33
+ };
34
+ };
35
+ '''
36
+
37
+
38
+ def describe_type(t):
39
+ """Return a short description of a member type."""
40
+ if t.is_primitive:
41
+ return t.name
42
+ if t.is_sequence:
43
+ return 'sequence of %s' % t.inner_type.name
44
+ if t.is_array:
45
+ return 'array %s' % t.name
46
+ if t.is_struct:
47
+ return 'struct %s' % t.full_path
48
+ return t.name
49
+
50
+
51
+ def main():
52
+ global_module = parser.IDLParser().load(IDL)
53
+ my_module = global_module.module_by_name('my_module')
54
+
55
+ print('structs in my_module:', [s.name for s in my_module.structs])
56
+ print()
57
+
58
+ for struct in my_module.structs:
59
+ print('struct %s' % struct.full_path)
60
+ for m in struct.members:
61
+ print(' %-12s %s' % (m.name, describe_type(m.type)))
62
+ print()
63
+
64
+ odometry = my_module.struct_by_name('Odometry')
65
+
66
+ # A member whose type is a struct: follow it to read its members.
67
+ stamp = odometry.member_by_name('stamp')
68
+ print('Odometry.stamp members:', [(m.name, m.type.name) for m in stamp.type.members])
69
+
70
+
71
+ if __name__ == '__main__':
72
+ main()
@@ -0,0 +1,18 @@
1
+ """OMG IDL parser.
2
+
3
+ Parse IDL files (or IDL text) into a tree of definition objects::
4
+
5
+ from idl_parser import parser
6
+ global_module = parser.IDLParser().load(idl_text)
7
+ my_module = global_module.module_by_name('my_module')
8
+
9
+ Start from :class:`idl_parser.parser.IDLParser`; the result is an
10
+ :class:`idl_parser.module.IDLModule` holding the global scope.
11
+ """
12
+ #from parser import IDLParser
13
+ __all__=['parser', 'exception']
14
+
15
+
16
+
17
+
18
+
@@ -46,12 +46,15 @@ class IDLBitValue(node.IDLNode):
46
46
 
47
47
  @property
48
48
  def full_path(self):
49
+ """Scoped name (``'M::Flags::FLAG_A'``)."""
49
50
  return self.parent.full_path + sep + self.name
50
51
 
51
52
  def to_simple_dic(self):
53
+ """A compact summary: ``{name: position}``."""
52
54
  return {self.name: self.position}
53
55
 
54
56
  def to_dic(self):
57
+ """The value as a plain dict (for JSON or YAML output)."""
55
58
  return self._with_annotations({'name': self.name,
56
59
  'classname': self.classname,
57
60
  'position': self.position,
@@ -59,7 +62,15 @@ class IDLBitValue(node.IDLNode):
59
62
 
60
63
 
61
64
  class IDLBitmask(node.IDLNode):
62
-
65
+ """A ``bitmask`` and its values.
66
+
67
+ :param name: Bitmask name.
68
+ :param parent: Enclosing :class:`~idl_parser.module.IDLModule`.
69
+ :param annotations: Annotations written before the bitmask; ``@bit_bound``
70
+ sets :attr:`bit_bound`.
71
+ :raises ~idl_parser.exception.InvalidIDLSyntaxError: ``@bit_bound`` is not
72
+ in 1..64.
73
+ """
63
74
  def __init__(self, name, parent, annotations=None):
64
75
  super(IDLBitmask, self).__init__('IDLBitmask', name, parent)
65
76
  self._verbose = False
@@ -80,6 +91,7 @@ class IDLBitmask(node.IDLNode):
80
91
 
81
92
  @property
82
93
  def full_path(self):
94
+ """Scoped name (``'M::Flags'``; ``'::Flags'`` at the global scope)."""
83
95
  return self.parent.full_path + sep + self.name
84
96
 
85
97
  @property
@@ -93,12 +105,19 @@ class IDLBitmask(node.IDLNode):
93
105
  return self._values
94
106
 
95
107
  def value_by_name(self, name):
108
+ """The value named ``name`` (an :class:`IDLBitValue`), or None."""
96
109
  for v in self._values:
97
110
  if v.name == name:
98
111
  return v
99
112
  return None
100
113
 
101
114
  def to_simple_dic(self, quiet=False, full_path=False, recursive=False, member_only=False):
115
+ """A compact summary: ``{'bitmask NAME': [{name: position}, ...]}``.
116
+
117
+ :param quiet: Return only ``'bitmask NAME'``.
118
+ :param full_path: Use :attr:`full_path` as the name.
119
+ :param member_only: Return only the list of value summaries.
120
+ """
102
121
  name = self.full_path if full_path else self.name
103
122
  if quiet:
104
123
  return 'bitmask %s' % name
@@ -107,6 +126,7 @@ class IDLBitmask(node.IDLNode):
107
126
  return {'bitmask %s' % name: [v.to_simple_dic() for v in self.values]}
108
127
 
109
128
  def to_dic(self):
129
+ """The bitmask as a plain dict (for JSON or YAML output)."""
110
130
  return self._with_annotations({'name': self.name,
111
131
  'filepath': self.filepath,
112
132
  'classname': self.classname,
@@ -114,6 +134,11 @@ class IDLBitmask(node.IDLNode):
114
134
  'values': [v.to_dic() for v in self.values]})
115
135
 
116
136
  def parse_tokens(self, token_buf, filepath=None):
137
+ """Parse the bitmask from ``token_buf``, starting after its name, up to ``};``.
138
+
139
+ :raises ~idl_parser.exception.InvalidIDLSyntaxError: The declaration is
140
+ not valid IDL, or a position is out of :attr:`bit_bound` or used twice.
141
+ """
117
142
  self._filepath = filepath
118
143
  ln, fn, token = token_buf.pop()
119
144
  if token != '{':