7.7.2.2. Module axivion.analysis.post_processing¶
Custom issue post-processing filters are registered via
analysis['MyRule'].post_processing.add_filter(callback)
or
analysis.options.global_post_processing.add_filter(callback)
See documentation of method add_filter for details.
Classes¶
|
Used for the return value of add_filter() callbacks. |
|
Describes the position of a post-processing step |
|
Stores the post-processing settings (filters and sinks). |
FilterAction¶
- class axivion.analysis.post_processing.FilterAction(value)¶
Bases:
EnumUsed for the return value of add_filter() callbacks.
- normal = 1¶
The violation proceeds as usual.
- exclude = 2¶
The violation is excluded: The violation is discarded as if –exclude applied to it. The following filters won’t get to see the violation, and it will not be imported into the database under any circumstances.
- suppress = 3¶
The violation is suppressed as if AXIVION DISABLE applied to it. Whether the violation gets imported into the database is controlled by the Axivion CI configuration.
Position¶
- class axivion.analysis.post_processing.Position(value)¶
Bases:
IntEnumDescribes the position of a post-processing step
- before_deduplication = 0¶
Filter in add_issue(). This means the filter is applied before the violation is deduplicated across template instances; and before commentary activators are applied.
Note: with parallel stylecheck execution, filters with this position will run in the worker processes.
- before_commentary_activators = 10¶
Filter runs after the violation is deduplicated across template instance; before commentary activators are applied.
Note: with parallel stylecheck execution, filters with this position will run in the worker processes.
- after_commentary_activators = 20¶
Filter runs immediately after commentary activators are applied.
This position is also used by justification_checker callbacks. Because justification_checkers are registered as filters only after all user configuration was processed, justification checkers effectively run after all other filters at the after_commentary_activators position.
Note: with parallel stylecheck execution, filters with this position will run in the worker processes.
- default = 50¶
Default filter priority level.
Note: with parallel stylecheck execution, filters with this position will run in the worker processes.
- main_process = 100¶
Run after the worker process has finished processing the violation, and handed it over to the main process.
Filters with this position will run in the main process. This can only be used with global filters; not with per-rule filters.
- issue_aggregation = 110¶
Run after all main_process filters. This is intended to be used for aggregating filters like the HIS-NOMV calculation or rules like ReportUnusedComments that depend on the presence of violations reported by other rules.
Filters with this position will run in the main process. This can only be used with global filters; not with per-rule filters.
- after_issue_aggregation = 120¶
Runs after aggregating filters (HIS-NOMV, ReportUnusedComments).
Filters with this position will run in the main process. This can only be used with global filters; not with per-rule filters.
PostProcessingSettings¶
- class axivion.analysis.post_processing.PostProcessingSettings(*, copy_from=None, ctx=None, is_per_rule=False)¶
Bases:
objectStores the post-processing settings (filters and sinks).
- Parameters:
copy_from (
typing.Optional[axivion.analysis.post_processing.PostProcessingSettings])ctx (
typing.Optional[axivion.analysis.config.ValidationContext])is_per_rule (
bool)
- copy()¶
Creates a copy of this object.
- extend(other)¶
Adds all entries from the other PostProcessingSettings to self.
- Parameters:
other (
axivion.analysis.post_processing.PostProcessingSettings)- Return type:
None
- extract(start_position=None, end_position=None)¶
Return a new PostProcessingSettings instance that contains only the filters between start_position (inclusive) and end_position (exclusive).
- Parameters:
start_position (
typing.Optional[axivion.analysis.post_processing.Position])end_position (
typing.Optional[axivion.analysis.post_processing.Position])
- Return type:
- add_filter(f, *, inputs=(), position=Position.default)¶
Adds a callback that will be invoked once per reported violation.
- Parameters:
f (
typing.Callable[...,typing.Optional[axivion.analysis.post_processing.FilterAction]]) – The callback function.inputs (
typing.Iterable[typing.Union[axivion.style.WorkItem[typing.Any],axivion.style.InputHandleProtocol[axivion.style.WorkItem[typing.Any]]]]) – Requests for additional inputs.position (
axivion.analysis.post_processing.Position) – describes when the filter will be called within the normal violation-processing pipeline.
- Return type:
None
The callback will be invoked as f(analysis_result, *input_values). If multiple callbacks are registered for the same position, they will be invoked in the order of the add_filter calls.
analysis_result is the violation being reported – this will be one of the message classes from bauhaus.analysis_results:
Architecture_Violation
Clone_Pair
Cycle_Finding
Dead_Entity
Metric
Style_Violation
input_values will be the values corresponding to the declared inputs. For example, inputs = [ir.Graph] will result in a call f(analysis_result, ir_graph).
The callback may mutate the violation object, and/or it may return one of the FilterAction enum values to influence further processing of the violation.
Example usage:
import axivion.config from axivion.analysis.post_processing import FilterAction from bauhaus import ir def my_filter(sv, ir_graph): node = ir_graph.get_node(ir.Physical, sv.primary_sloc.pir_node_number) # Mutate violation to add more information to the message sv.message += f" (right is {node.Right_Operand.Value})" if node.Right_Operand.Value > 100: return FilterAction.exclude else: return FilterAction.normal analysis = axivion.config.get_analysis() analysis.activate('MisraC2012-10.1') analysis['MisraC2012-10.1'].post_processing.add_filter(my_filter, inputs=[ir.Graph]) # Alternatively, enable for all rules: # analysis.options.global_post_processing.add_filter(my_filter, inputs=[ir.Graph])
- add_sink(f, *, inputs=(), position=Position.default)¶
Similar to add_filter(), but allows using a custom bauhaus.analysis_results.Sink implementation.
- Parameters:
f (
typing.Callable[...,_analysis_results.Sink]) – The sink-constructing callback function.inputs (
typing.Iterable[typing.Union[axivion.style.WorkItem[typing.Any],axivion.style.InputHandleProtocol[axivion.style.WorkItem[typing.Any]]]]) – Requests for additional inputs.position (
axivion.analysis.post_processing.Position) – describes when the filter will be called within the normal violation-processing pipeline.
- Return type:
None
The callback will be invoked as f(next_sink, *input_values). The callback’s return value must be a sink.
All violations produced by the rule will be sent to the returned sink. It may mutate the violations and then send them on to the next sink. By not sending a violation to the next sink, it can exclude violations. Unlike the add_filter method, this also allows replacing a single violation with multiple new violations.
Caution: sinks may be used from multiple threads; make sure your sink implementation is thread-safe!
Example usage:
from bauhaus import analysis_results as ar class DuplicatingSink(ar.Sink): def __init__(self, next_sink): self.next_sink = next_sink def send(self, data): if isinstance(data, ar.Style_Violation): self.next_sink.send(data) data.message += '!!!' self.next_sink.send(data) else: self.next_sink.send(data) analysis = axivion.config.get_analysis() analysis.activate('MisraC2012-10.1') analysis['MisraC2012-10.1'].post_processing.add_sink(DuplicatingSink)
- num_filters_and_sinks()¶
- Return type:
int
- num_inputs()¶
Gets the total number of inputs required by all filters+sinks added so far.
- Return type:
int
- get_inputs(_ctx)¶
Gets the inputs required for decorate_sink().
- Parameters:
_ctx (
axivion.style.AnalysisSchedulingContext)- Return type:
typing.Iterable[typing.Union[axivion.style.WorkItem[typing.Any],axivion.style.InputHandleProtocol[axivion.style.WorkItem[typing.Any]]]]
- decorate_sink(next_sink, input_values, start_position=None, end_position=None)¶
Create a new sink that applies all the filters from this collection between start_position (inclusive) and end_position (exclusive) and then sends the modified violations to next_sink.
- Parameters:
next_sink (
_analysis_results.Sink)input_values (
typing.Sequence)start_position (
typing.Optional[axivion.analysis.post_processing.Position])end_position (
typing.Optional[axivion.analysis.post_processing.Position])
- Return type:
_analysis_results.Sink