fst.view

Slice-access views on FST lists of children.

class fstview:

View for a list of AST nodes in a body, or any other field which is a list of values (not necessarily AST nodes), of an FST node.

Nodes can be gotten or put via indexing. Nodes which are accessed through indexing (normal or slice) are not automatically copied, if a copy is desired then do fst.body[start:stop].copy(). Slice assignments also work but will always assign a slice to the range. If you want to assign an individual item to this range or a subrange then use fst.body[start:stop].replace(..., one=True).

>>> from fst import FST
>>> view = FST('[1, 2, 3]').elts
>>> view[1].remove()
>>> view
<<List ROOT 0,0..0,6>.elts [<Constant 0,1..0,2>, <Constant 0,4..0,5>]>
>>> view[1:].cut()
<List ROOT 0,0..0,3>
>>> view
<<List ROOT 0,0..0,3>.elts [<Constant 0,1..0,2>]>

This object is meant to be, and is normally created automatically by accessing AST list fields on an FST node.

Examples:

>>> from fst import FST
>>> f = FST('[0, 1, 2, 3]')
>>> f
<List ROOT 0,0..0,12>
>>> f.elts
<<List ROOT 0,0..0,12>.elts [<Constant 0,1..0,2>, <Constant 0,4..0,5>, <Constant 0,7..0,8>, <Constant 0,10..0,11>]>
>>> f.elts[1]
<Constant 0,4..0,5>
>>> f.elts[1].src
'1'
>>> f.elts[1:3]
<<List ROOT 0,0..0,12>.elts[1:3] [<Constant 0,4..0,5>, <Constant 0,7..0,8>]>
>>> f.elts[1:3].copy()
<List ROOT 0,0..0,6>
>>> _.src
'[1, 2]'
>>> f.elts[1:3] = '[4]'
>>> f.src
'[0, [4], 3]'
>>> f.elts[1:2] = '4'
>>> f.src
'[0, 4, 3]'
>>> del f.elts[1:]
>>> f.src
'[0]'
>>> f.elts[0] = '*star'
>>> f.src
'[*star]'
base: fst.fst.FST

The target FST node this view references.

field: str

The target field this view references. Can be virtual field like _all.

is_FST = False

Allows to quickly differentiate between actual FST nodes vs. views or locations.

start: int

Start position within the target field list this view references.

stop: int

One past the last element within the target field list this view references.

def __getitem__(self, idx: int | slice) -> fstview | fst.fst.FST | str | None:

Get a single item or a slice view from this slice view. All indices (including negative) are relative to the bounds of this view. This is just an access, not a cut or a copy, so if you want a copy you must explicitly do .copy() on the returned value.

Note that fstview can also hold references to non-AST lists of items, so keep this in mind when dealing with return values which may be None or may not be FST nodes.

Parameters:

  • idx: The index or slice where to get the element(s) from.

Returns:

  • fstview | FST | str | None: Either a single FST node if accessing a single item or a new fstview view according to the slice passed. str can also be returned from a view of Global.names or None from a Dict.keys.

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts[1].src
'1'
>>> FST('[0, 1, 2, 3]').elts[:3]
<<List ROOT 0,0..0,12>.elts[:3] [<Constant 0,1..0,2>, <Constant 0,4..0,5>, <Constant 0,7..0,8>]>
>>> FST('[0, 1, 2, 3]').elts[:3].copy().src
'[0, 1, 2]'
>>> FST('[0, 1, 2, 3]').elts[-3:]
<<List ROOT 0,0..0,12>.elts[1:4] [<Constant 0,4..0,5>, <Constant 0,7..0,8>, <Constant 0,10..0,11>]>
>>> FST('def fun(): pass\nclass cls: pass\nvar = val').body[1]
<ClassDef 1,0..1,15>
>>> FST('global a, b, c').names
<<Global ROOT 0,0..0,14>.names ['a', 'b', 'c']>
>>> FST('global a, b, c').names[1]
'b'
def __setitem__( self, idx: int | slice, code: Union[fst.fst.FST, ast.AST, list[str], str, NoneType]) -> None:

Set a single item or a slice view in this slice view. All indices (including negative) are relative to the bounds of this view.

Note that fstview can also hold references to non-AST lists of items, so keep this in mind when assigning values.

Parameters:

  • idx: The index or slice where to put the element(s).

Examples:

>>> from fst import FST
>>> (f := FST('[0, 1, 2, 3]')).elts[1] = '4'; f.src
'[0, 4, 2, 3]'
>>> (f := FST('[0, 1, 2, 3]')).elts[:3] = '[5]'; f.src
'[[5], 3]'
>>> (f := FST('[0, 1, 2, 3]')).elts[:3] = '5'; f.src
'[5, 3]'
>>> (f := FST('[0, 1, 2, 3]')).elts[:3] = '5,'; f.src
'[5, 3]'
>>> (f := FST('[0, 1, 2, 3]')).elts[-3:] = '[6]'; f.src
'[0, [6]]'
>>> (f := FST('[0, 1, 2, 3]')).elts[-3:] = '6'; f.src
'[0, 6]'
>>> (f := FST('[0, 1, 2, 3]')).elts[:] = '7, 8'; f.src
'[7, 8]'
>>> f = FST('[0, 1, 2, 3]')
>>> f.elts[2:2] = f.elts[1:3].copy()
>>> f.src
'[0, 1, 1, 2, 2, 3]'
def __delitem__(self, idx: int | slice) -> None:

Delete a single item or a slice from this slice view. All indices (including negative) are relative to the bounds of this view.

Note that fstview can also hold references to non-AST lists of items, so keep this in mind when assigning values.

Parameters:

  • idx: The index or slice to delete.

Examples:

>>> from fst import FST
>>> del (f := FST('[0, 1, 2, 3]')).elts[1]; f.src
'[0, 2, 3]'
>>> del (f := FST('[0, 1, 2, 3]')).elts[:3]; f.src
'[3]'
>>> del (f := FST('[0, 1, 2, 3]')).elts[-3:]; f.src
'[0]'
>>> del (f := FST('[0, 1, 2, 3]')).elts[:]; f.src
'[]'
def copy(self, **options) -> fst.fst.FST:

Copy this slice to a new top-level tree, dedenting and fixing as necessary.

Parameters:

Returns:

  • FST: Copied slice.

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts[1:3].copy().src
'[1, 2]'
def cut(self, **options) -> fst.fst.FST:

Cut out this slice to a new top-level tree (if possible), dedenting and fixing as necessary. Cannot cut root node.

Parameters:

Returns:

  • FST: Cut slice.

Examples:

>>> from fst import FST
>>> (f := FST('[0, 1, 2, 3]')).elts[1:3].cut().src
'[1, 2]'
>>> f.src
'[0, 3]'
def replace( self, code: Union[fst.fst.FST, ast.AST, list[str], str, NoneType], one: bool | None = True, **options) -> fstview:

Replace or delete (if code=None) this slice.

Returns:

  • self

Parameters:

  • code: FST, AST or source str or list[str] to put. None to delete this slice.
  • one: If True then will replace the range of this slice with a single item. Otherwise False will attempt a slice replacement (type must be compatible).
  • options: See fst.fst.FST.options().

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts[1:3].replace('(4, 5)').base.src
'[0, (4, 5), 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].replace('4, 5').base.src
'[0, (4, 5), 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].replace('(4, 5)', one=False).base.src
'[0, (4, 5), 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].replace('4, 5', one=False).base.src
'[0, 4, 5, 3]'
def remove(self, **options) -> fstview:

Delete this slice, equivalent to replace(None, ...)

Parameters:

Returns:

  • self

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts[1:3].remove().base.src
'[0, 3]'
def insert( self, code: Union[fst.fst.FST, ast.AST, list[str], str], idx: Union[int, Literal['end']] = 0, *, one: bool | None = True, **options) -> fstview:

Insert into this slice at a specific index.

Returns:

  • self

Parameters:

  • code: FST, AST or source str or list[str] to insert.
  • idx: Index to insert before. Can be 'end' to indicate add at end of slice.
  • one: If True then will insert code as a single item. Otherwise False will attempt a slice insertion (type must be compatible).
  • options: See fst.fst.FST.options().

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts.insert('4, 5', 1).base.src
'[0, (4, 5), 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts.insert('(4, 5)', 1).base.src
'[0, (4, 5), 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts.insert('4, 5', 'end', one=False).base.src
'[0, 1, 2, 3, 4, 5]'
>>> FST('[0, 1, 2, 3]').elts.insert('(4, 5)', 'end', one=False).base.src
'[0, 1, 2, 3, (4, 5)]'
>>> # same as 'end' but 'end' is always 'end'
>>> FST('[0, 1, 2, 3]').elts.insert('4, 5', 4, one=False).base.src
'[0, 1, 2, 3, 4, 5]'
>>> FST('[0, 1, 2, 3]').elts.insert('(4, 5)', 4, one=False).base.src
'[0, 1, 2, 3, (4, 5)]'
>>> FST('[0, 1, 2, 3]').elts[1:3].insert('*star').base.src
'[0, *star, 1, 2, 3]'
def append( self, code: Union[fst.fst.FST, ast.AST, list[str], str], **options) -> fstview:

Append code as a single element to the end of this slice.

Returns:

  • self

Parameters:

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts.append('(4, 5)').base.src
'[0, 1, 2, 3, (4, 5)]'
>>> FST('[0, 1, 2, 3]').elts[1:3].append('*star').base.src
'[0, 1, 2, *star, 3]'
def extend( self, code: Union[fst.fst.FST, ast.AST, list[str], str], one: Optional[Literal[False]] = False, **options) -> fstview:

Extend this slice with the slice in code (type must be compatible).

Returns:

  • self

Parameters:

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts.extend('4, 5').base.src
'[0, 1, 2, 3, 4, 5]'
>>> FST('[0, 1, 2, 3]').elts.extend('(4, 5)').base.src
'[0, 1, 2, 3, (4, 5)]'
>>> FST('[0, 1, 2, 3]').elts[1:3].extend('4, 5').base.src
'[0, 1, 2, 4, 5, 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].extend('(4, 5)').base.src
'[0, 1, 2, (4, 5), 3]'
def prepend( self, code: Union[fst.fst.FST, ast.AST, list[str], str], **options) -> fstview:

prepend code as a single element to the beginning of this slice.

Returns:

  • self

Parameters:

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts.prepend('(4, 5)').base.src
'[(4, 5), 0, 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].prepend('*star').base.src
'[0, *star, 1, 2, 3]'
def prextend( self, code: Union[fst.fst.FST, ast.AST, list[str], str], one: Optional[Literal[False]] = False, **options) -> fstview:

Extend the beginning of this slice with the slice in code (type must be compatible).

Returns:

  • self

Parameters:

Examples:

>>> from fst import FST
>>> FST('[0, 1, 2, 3]').elts.prextend('4, 5').base.src
'[4, 5, 0, 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts.prextend('(4, 5)').base.src
'[(4, 5), 0, 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].prextend('4, 5').base.src
'[0, 4, 5, 1, 2, 3]'
>>> FST('[0, 1, 2, 3]').elts[1:3].prextend('(4, 5)').base.src
'[0, (4, 5), 1, 2, 3]'