v0.3.0
Pre-release
Pre-release
0.3.0 - alpha - 2026-02-28
Added
- Python 3.15a support
- unpacking in comprehensions,
[*st for st in itr],{**key for key in itr} - lazy imports not on main branch yet
- unpacking in comprehensions,
- structural pattern matching
FST.match()match -f.match(Mstmt(body=[Expr(Constant(str)), ...]))FST.search()search -for m in f.search(Assign([Name], ListComp))FST.sub()substitute -f.sub(MCall('old_name', _args=M(all_args=...)), 'new_name(__FST_all_args, new_kw=newval)')
FST.find_def()easily find (possibly nested) function and class definitions by name in a given scope by dotted name- added usage of this in indexing (single-element only, not slice):
method = module['class.method'],del someclass['method'], etc...
- added usage of this in indexing (single-element only, not slice):
FST/fstviewinteroperability for convenience- added
src,lines,loc/ln/col/end_ln/end_col,bloc/bln/bcol/bend_ln/bend_colandpars()tofstview - added
basetoFSTso that you can dof.base.get_src(*f.loc)without knowing if isFSTorfstview
- added
walk()- can take explicit list of nodes to walk instead of just "all children of self"
- can take user callback for the
allparameter for deciding if node matches
- added
topparameter tostep_fwd/back()to restrict stepping above a given parent - finally validating
options - trivia option shorthand
()for(False, False)
Changed
- allow get and put as
one=Truesingle-itemDictorMatchMappinginstead of error, makes more sense - simplified
triviaoption to always specify entire state, no more merging with current state Global/Nonlocal.namesviews now return a single-elementFSTViewwhen dereferencing a single element instead of the string value at that index- allow delete
Raise.excifcauseexists by automatically deletingcausefirst - allow delete
ExceptHandler.typeifnameexists by automatically deletingnamefirst
Fixed
- fixed
step_fwd/back()for anything that wasn'tall=True/False/'loc' - replacement of single statement no longer replaces that statement's
FST, allowingwalk()to recurse into replaced children - disallow put
_as name toMatchMapping.restandMatchClass.kwd_attrs - disallow put
*or dotted as name toalias.nameif context does not allow - disallow put
*to_aliases.namesif there are multiple names (only allowed to replace a single one) - put empty slice of statementlikes containing only trivia erasing whole
orelseorfinalbodyfield now deletes the whole field instead of leaving a hangingelse:orfinally: