Reflow API
This section is for rule authors who produce whitespace or layout fixes.
Many SQLFluff rules involve spacing and layout — enforcing a particular whitespace style or adding/removing code while respecting the layout configuration. The sqlfluff.utils.reflow module provides centralised utilities so that all layout rules behave consistently.
Rules should use ReflowSequence rather than constructing LintFix objects manually; it returns ready-to-use fix lists and respects the user's layout configuration automatically.
Source: sqlfluff/utils/reflow/
ReflowSequence
Class for keeping track of elements in a reflow operation.
This acts as the primary route into using the reflow routines. It acts in a way that plays nicely within a rule context in that it accepts segments and configuration, while allowing access to modified segments and a series of LintFix objects, which can be returned by the calling rule.
Sequences are made up of alternating ReflowBlock and ReflowPoint objects (even if some points have no segments). This is validated on construction.
Most operations also return ReflowSequence objects such that operations can be chained, and then the resultant fixes accessed at the last stage, for example:
python fixes = ( ReflowSequence.from_around_target( context.segment, root_segment=context.parent_stack[0], config=context.config, ) .rebreak() .get_fixes() )
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
elements | list[ReflowBlock | ReflowPoint] | ||
root_segment | BaseSegment | ||
reflow_config | ReflowConfig | ||
depth_map | DepthMap | ||
lint_results | list[LintResult] | None | None |
Methods
break_long_lines
break_long_lines() → ReflowSequenceRebreak any remaining long lines in a sequence.
This assumes that reindent() has already been applied.
Returns:
ReflowSequence — See return type.
from_around_target
from_around_target(
target_segment,
root_segment,
config,
sides="both"
) → ReflowSequenceGenerate a sequence around a target.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
target_segment | BaseSegment | The segment to center around when considering the sequence to construct. | |
root_segment | BaseSegment | The relevant root segment (usually the base FileSegment). | |
config | FluffConfig | A config object from which to load the spacing behaviours of different segments. | |
sides | str | "both" | Limit the reflow sequence to just one side of the target. Default is two sided ("both"), but set to "before" or "after" to limit to either side. NOTE: We don't just expand to the first block around the target but to the first code element, which means we may swallow several comment blocks in the process. To evaluate reflow around a specific target, we need need to generate a sequence which goes for the preceding raw to the following raw. i.e. at least: block - point - block - point - block (where the central block is the target). |
Returns:
ReflowSequence — See return type.
from_raw_segments
from_raw_segments(
segments,
root_segment,
config,
depth_map=None
) → ReflowSequenceConstruct a ReflowSequence from a sequence of raw segments.
This is intended as a base constructor, which others can use. In particular, if no depth_map argument is provided, this method will generate one in a potentially inefficient way. If the calling method has access to a better way of inferring a depth map (for example because it has access to a common root segment for all the content), it should do that instead and pass it in.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
segments | collections.abc.Sequence[RawSegment] | ||
root_segment | BaseSegment | ||
config | FluffConfig | ||
depth_map | DepthMap | None | None |
Returns:
ReflowSequence — See return type.
from_root
from_root(
root_segment,
config
) → ReflowSequenceGenerate a sequence from a root segment.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
root_segment | BaseSegment | The relevant root segment (usually the base FileSegment). | |
config | FluffConfig | A config object from which to load the spacing behaviours of different segments. |
Returns:
ReflowSequence — See return type.
get_fixes
get_fixes() → list[LintFix]Get the current fix buffer.
We're hydrating them here directly from the LintResult objects, so for more accurate results, consider using .get_results(). This method is particularly useful when consolidating multiple results into one.
Returns:
list[LintFix] — See return type.
get_raw
get_raw() → strGet the current raw representation.
Returns:
str — See return type.
get_results
get_results() → list[LintResult]Return the current result buffer.
Returns:
list[LintResult] — See return type.
insert
insert(
insertion,
target,
pos="before"
) → ReflowSequenceReturns a new ReflowSequence with the new element inserted.
Insertion is always relative to an existing element. Either before or after it as specified by pos. This generates appropriate creation LintFix objects to direct the linter to insert those elements.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
insertion | RawSegment | ||
target | RawSegment | ||
pos | str | "before" |
Returns:
ReflowSequence — See return type.
INFO
This method is currently excluded from test coverage because it is not actively used by any rule. It was previously utilized by rule AL01, but that rule now uses an alternative implementation. The method is retained for potential future reuse or reference.
rebreak
rebreak(
rebreak_type="lines"
) → ReflowSequenceReturns a new ReflowSequence corrected line breaks.
This intentionally does not handle indentation, as the existing indents are assumed to be correct.
INFO
Currently this only moves existing segments around line breaks (e.g. for operators and commas), but eventually this method will also handle line length considerations too.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
rebreak_type | Literal['lines', 'keywords'] | "lines" |
Returns:
ReflowSequence — See return type.
reindent
reindent() → ReflowSequenceReindent lines within a sequence.
Returns:
ReflowSequence — See return type.
replace
replace(
target,
edit
) → ReflowSequenceReturns a new ReflowSequence with edit elements replaced.
This generates appropriate replacement LintFix objects to direct the linter to modify those elements.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
target | BaseSegment | ||
edit | collections.abc.Sequence[BaseSegment] |
Returns:
ReflowSequence — See return type.
respace
respace(
strip_newlines=False,
filter="all"
) → ReflowSequenceReturns a new ReflowSequence with points respaced.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
strip_newlines | bool | False | Optionally strip newlines before respacing. This is primarily used on focused sequences to coerce objects onto a single line. This does not apply any prioritisation to which line breaks to remove and so is not a substitute for the full reindent or reflow methods. |
filter | str | "all" | Optionally filter which reflow points to respace. Default configuration is all. Other options are newline which only respaces points containing a newline or followed by an end_of_file marker, or inline which is the inverse of newline. This is most useful for filtering between trailing whitespace and fixes between content on a line. NOTE this method relies on the embodied results being correct so that we can build on them. |
Returns:
ReflowSequence — See return type.
without
without(
target
) → ReflowSequenceReturns a new ReflowSequence without the specified segment.
This generates appropriate deletion LintFix objects to direct the linter to remove those elements.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
target | RawSegment |
Returns:
ReflowSequence — See return type.
INFO
This method is currently excluded from test coverage because it is not actively used by any rule. It was previously utilized by rule AL01, but that rule now uses an alternative implementation. The method is retained for potential future reuse or reference.
ReflowPoint
Class for keeping track of editable elements in reflow.
This class, and its sibling ReflowBlock, should not normally be manipulated directly by rules, but instead should be manipulated using ReflowSequence.
It holds segments which can be changed during a reflow operation such as whitespace and newlines.It may also contain Indent and Dedent elements.
It holds no configuration and is influenced by the blocks on either side, so that any operations on it usually have that configuration passed in as required.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
segments | tuple[RawSegment, ...] |
Methods
get_indent
get_indent() → str | NoneGet the current indent (if there).
Returns:
str | None — See return type.
get_indent_impulse
get_indent_impulse() → IndentStatsGet the change in intended indent balance from this point.
Returns:
IndentStats — See return type.
get_indent_segment_vals
get_indent_segment_vals(
exclude_block_indents=False
) → list[int]Iterate through any indent segments and extract their values.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
exclude_block_indents | False |
Returns:
list[int] — See return type.
indent_to
indent_to(
desired_indent,
after=None,
before=None,
description=None,
source=None
) → tuple[list[LintResult], ReflowPoint]Coerce a point to have a particular indent.
If the point currently contains no newlines, one will be introduced and any trailing whitespace will be effectively removed.
More specifically, the newline is inserted before the existing whitespace, with the new indent being a replacement for that same whitespace.
For placeholder newlines or indents we generate appropriate source fixes.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
desired_indent | str | ||
after | BaseSegment | None | None | |
before | BaseSegment | None | None | |
description | str | None | None | |
source | str | None | None |
Returns:
tuple[list[LintResult], ReflowPoint] — See return type.
is_all_unrendered
is_all_unrendered() → boolReturn whether this element is all unrendered.
Returns True if contains only whitespace, indents, template loops or placeholders.
Returns:
bool — See return type.
INFO
- ReflowBlocks will contain the placeholders and loops
- ReflowPoints will contain whitespace, indents and newlines.
num_newlines
num_newlines() → intReturn the number of newlines in this element.
These newlines are either newline segments or contained within consumed sections of whitespace. This counts both.
Returns:
int — See return type.
respace_point
respace_point(
prev_block,
next_block,
root_segment,
lint_results,
strip_newlines=False,
anchor_on="before",
indent_unit="space",
tab_space_size=4
) → tuple[list[LintResult], ReflowPoint]Respace a point based on given constraints.
NB: This effectively includes trailing whitespace fixes.
Deletion and edit fixes are generated immediately, but creations are paused to the end and done in bulk so as not to generate conflicts.
Note that the strip_newlines functionality exists here as a slight exception to pure respacing, but as a very simple case of positioning line breaks. The default operation of respace does not enable it, however it exists as a convenience for rules which wish to use it.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
prev_block | ReflowBlock | None | ||
next_block | ReflowBlock | None | ||
root_segment | BaseSegment | ||
lint_results | list[LintResult] | ||
strip_newlines | bool | False | |
anchor_on | str | "before" | |
indent_unit | str | "space" | |
tab_space_size | int | 4 |
Returns:
tuple[list[LintResult], ReflowPoint] — See return type.
ReflowBlock
Class for keeping track of elements to reflow.
This class, and its sibling ReflowPoint, should not normally be manipulated directly by rules, but instead should be manipulated using ReflowSequence.
It holds segments to reflow and also exposes configuration regarding how they are expected to reflow around others. Typically it holds only a single element, which is usually code or a templated element. Because reflow operations control spacing, it would be very unusual for this object to be modified; as such it exposes relatively few methods.
The attributes exposed are designed to be "post configuration" i.e. they should reflect configuration appropriately.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
segments | tuple[RawSegment, ...] | ||
spacing_before | str | ||
spacing_after | str | ||
line_position | str | None | ||
depth_info | DepthInfo | ||
stack_spacing_configs | dict[int, str] | ||
line_position_configs | dict[int, str] | ||
keyword_line_position | str | None | ||
keyword_line_position_configs | dict[int, str] | ||
keyword_line_position_exclusions | str | list[str] | None | ||
keyword_line_position_exclusions_configs | dict[int, str | list[str]] |
Methods
from_config
from_config(
segments,
config,
depth_info
) → ReflowBlockConstruct a ReflowBlock while extracting relevant configuration.
This is the primary route to construct a ReflowBlock, as is allows all of the inference of the spacing and position configuration from the segments it contains and the appropriate config objects.
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
segments | tuple[RawSegment, ...] | ||
config | ReflowConfig | ||
depth_info | DepthInfo |
Returns:
ReflowBlock — See return type.
is_all_unrendered
is_all_unrendered() → boolReturn whether this element is all unrendered.
Returns True if contains only whitespace, indents, template loops or placeholders.
Returns:
bool — See return type.
INFO
- ReflowBlocks will contain the placeholders and loops
- ReflowPoints will contain whitespace, indents and newlines.
num_newlines
num_newlines() → intReturn the number of newlines in this element.
These newlines are either newline segments or contained within consumed sections of whitespace. This counts both.
Returns:
int — See return type.
