Skip to content

Commit 81b358d

Browse files
committed
Nicer signature to ExecutionResult
Replace `**options` with explicit keyword-only parameters to make the signrature more convenient to use and easier to document properly. This change makes it more cleaer that JSON results don't support omitting keywords (#5467) or flattening keywords (#5464).
1 parent ec5aaae commit 81b358d

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

src/robot/result/resultbuilder.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16+
from typing import Sequence
1617
from xml.etree import ElementTree as ET
1718

1819
from robot.errors import DataError
@@ -27,20 +28,28 @@
2728
from .xmlelementhandlers import XmlElementHandler
2829

2930

30-
def ExecutionResult(*sources, **options):
31+
def ExecutionResult(
32+
*sources,
33+
merge: bool = False,
34+
include_keywords: bool = True,
35+
flattened_keywords: Sequence[str] = (),
36+
rpa: "bool|None" = None,
37+
):
3138
"""Factory method to constructs :class:`~.executionresult.Result` objects.
3239
3340
:param sources: XML or JSON source(s) containing execution results.
3441
Can be specified as paths (``pathlib.Path`` or ``str``), opened file
3542
objects, or strings/bytes containing XML/JSON directly.
36-
:param options: Configuration options.
37-
Using ``merge=True`` causes multiple results to be combined so that
38-
tests in the latter results replace the ones in the original.
39-
Setting ``rpa`` either to ``True`` (RPA mode) or ``False`` (test
40-
automation) sets execution mode explicitly. By default, it is got
43+
:param merge: When ``True`` and multiple sources are given, results are merged
44+
instead of combined.
45+
:param include_keywords: When ``False``, keyword and control structure information
46+
is not parsed. This can save considerable amount of time and memory.
47+
:param flattened_keywords: List of patterns controlling what keywords
48+
and control structures to flatten. See the documentation of
49+
the ``--flattenkeywords`` option for more details.
50+
:param rpa: Setting ``rpa`` either to ``True`` (RPA mode) or ``False`` (test
51+
automation) sets the execution mode explicitly. By default, the mode is got
4152
from processed output files and conflicting modes cause an error.
42-
Other options are passed directly to the
43-
:class:`ExecutionResultBuilder` object used internally.
4453
:returns: :class:`~.executionresult.Result` instance.
4554
4655
A source is considered to be JSON in these cases:
@@ -53,7 +62,12 @@ def ExecutionResult(*sources, **options):
5362
"""
5463
if not sources:
5564
raise DataError("One or more data source needed.")
56-
if options.pop("merge", False):
65+
options = {
66+
"include_keywords": include_keywords,
67+
"flattened_keywords": flattened_keywords,
68+
"rpa": rpa,
69+
}
70+
if merge:
5771
return _merge_results(sources[0], sources[1:], options)
5872
if len(sources) > 1:
5973
return _combine_results(sources, options)
@@ -63,8 +77,8 @@ def ExecutionResult(*sources, **options):
6377
def _merge_results(original, merged, options):
6478
result = ExecutionResult(original, **options)
6579
merger = Merger(result, rpa=result.rpa)
66-
for path in merged:
67-
merged = ExecutionResult(path, **options)
80+
for source in merged:
81+
merged = ExecutionResult(source, **options)
6882
merger.merge(merged)
6983
return result
7084

@@ -75,40 +89,44 @@ def _combine_results(sources, options):
7589

7690
def _single_result(source, options):
7791
if is_json_source(source):
78-
return _json_result(source, options)
79-
return _xml_result(source, options)
92+
return _json_result(source, **options)
93+
return _xml_result(source, **options)
8094

8195

82-
def _json_result(source, options):
96+
def _json_result(source, include_keywords, flattened_keywords, rpa):
8397
try:
84-
return Result.from_json(source, rpa=options.get("rpa"))
98+
return Result.from_json(source, rpa=rpa)
8599
except IOError as err:
86100
error = err.strerror
87101
except Exception:
88102
error = get_error_message()
89103
raise DataError(f"Reading JSON source '{source}' failed: {error}")
90104

91105

92-
def _xml_result(source, options):
106+
def _xml_result(source, include_keywords, flattened_keywords, rpa):
93107
ets = ETSource(source)
94-
result = Result(source, rpa=options.pop("rpa", None))
108+
builder = ExecutionResultBuilder(ets, include_keywords, flattened_keywords)
109+
result = Result(source, rpa=rpa)
95110
try:
96-
return ExecutionResultBuilder(ets, **options).build(result)
111+
return builder.build(result)
97112
except IOError as err:
98113
error = err.strerror
99114
except Exception:
100115
error = get_error_message()
101116
raise DataError(f"Reading XML source '{ets}' failed: {error}")
102117

103118

119+
# TODO:
120+
# - Rename e.g. to XmlExecutionResultBuilder. Probably best done in a major release.
121+
# - Add Result.from_xml as a more convenient API. Could be done in RF 7.4.
104122
class ExecutionResultBuilder:
105123
"""Builds :class:`~.executionresult.Result` objects based on XML output files.
106124
107125
Instead of using this builder directly, it is recommended to use the
108126
:func:`ExecutionResult` factory method.
109127
"""
110128

111-
def __init__(self, source, include_keywords=True, flattened_keywords=None):
129+
def __init__(self, source, include_keywords=True, flattened_keywords=()):
112130
"""
113131
:param source: Path to the XML output file to build
114132
:class:`~.executionresult.Result` objects from.

0 commit comments

Comments
 (0)