refex.substitution

Substitutions with optional metadata. This forms the core data structure that Refex traffics in: Refex finds Substitution objects, displays them, and actualizes the change they represent (if any).

class Substitution(matched_spans: Mapping[str, Tuple[int, int]], primary_label: str, replacements: Mapping[str, str] = NOTHING, message: Optional[str] = None, url: Optional[str] = None, significant: bool = True, category: Optional[str] = None, key_span: Optional[Tuple[int, int]] = None)

A search result containing optional replacements and metadata.

The span of text being fixed is attached as a dict mapping span identifiers to (start, end) codepoint offsets (start is inclusive, end is not). The span identifiers are also used to identify replacements in the replacement dict.

matched_spans = None

Matched spans, keyed by label.

primary_label = None

The label for the location of the Substitution.

replacements = None

A mapping from labels to replacement strings. May be empty.

message = None

A message describing the issue.

url = None

An URL describing the issue or fix in more detail.

significant = None

If False, this is more or less a trivial change, the description of which may be dropped if this substitution is combined with a significant substitution.

category = None

A name to group fixes by. This can be used for separating out suggestions for statistics, suppressing categories of suggestions, etc.

key_span = None

A span by which to group the substitution, or None if it is ungrouped.

The scope should ideally be as local as possible. For example, grouping by expression or by line is sensible.

Suggestions with the same non-None span may be merged.

property primary_span

A convenience attribute for the span for the primary label.

relative_to_span(start: int, end: int) → Optional[refex.substitution.Substitution]

Returns a new substitution that is offset relative to the provided span.

If sub is a Substitution for s, then sub.relative_to_span(a, b) is the equivalent substitution for s[a:b].

Parameters
  • start – The start of the span to be relative to (inclusive).

  • end – The end of the span to be relative to (exclusive).

Returns

A new substitution in the substring, or else None if the substitution doesn’t fit.

all_categories() → Iterable[Optional[str]]

Yields all categories the substitution is a member of.

Categories form a hierarchy separated by a dot, so e.g. a substitution with category foo.bar.baz will be in categories foo and foo.bar.

Additionally, every substitution is in the root category, represented by the special value None.

Diffs

The following functions and classes can convert a Substitution into a diff. (Actual formatting and display of the diff is left to callers, in particular refex.formatting.)

class LabeledSpan(span: Tuple[int, int], labels: FrozenSet[str])

A part of the original text, verbatim.

A single LabeledSpan has exactly one set of labels that applied to it from the Substitution. When a new label begins, or an old label ends, a new Unchanged is created for the remaining span.

span = None

The start/end in the original string.

labels = None

A frozenset of which labels matched this span.

class DiffSpan(span: Tuple[int, int], label: str, after: str)

A part of the diff that was changed by the Substitution.

note that unlike LabeledSpan, a label may begin or end in the middle of a Diff. However, labels are not allowed to have diffs that intersect, so label is the only label responsible for this diff.

span = None

The span in the original string.

label = None

The label responsible for this diff.

after = None

The text that the span is replaced with.

as_diff(sub: refex.substitution.Substitution) → Iterable[Union[refex.substitution.LabeledSpan, refex.substitution.DiffSpan]]

Yields the diff represented by the substitution.

Note that this is a diff-of-intent, and not necessarily a minimal diff. For example, replacing 'foo' with 'foo' will yield a Diff(before='foo', after='foo').

The diff begins at the first line that the Substitution matches, and ends at the last line that the Substitution matches.

Parameters

sub – The Substitution to convert to a diff.

Yields

DiffSpan – A part of the line that the Substitution replaces.

LabeledSpan:

A part of the diff that has no replacements, or which has a replacement that overlaps with a prior DiffSpan.

labeled_spans(sub: refex.substitution.Substitution)

Yields all LabeledSpan objects for a Substitution.

Parameters

sub – The substitution in question.

Returns

An iterator of every LabeledSpan in the substitution, in sorted order.

disjoint_substitutions(subs: Iterable[refex.substitution.Substitution]) → List[refex.substitution.Substitution]

Returns subs without overlapping substitutions, in sorted order.