After you do your selection manipulation try triggering two invert_selection actions like shown in this post. It’s not an ideal solution unfortunately.
In the API none of these will update visually (using setSelection)
dilate
erode
border
feather
grow
shrink
smooth
invert
These do though
selectAll
replace
select
subtract
intersect
resize
contract
move
Try uncommenting bits of this to see how they work, im not clear on how all of them work.
def func():
import time
from krita import Selection
start_time = time.time()
#---
inst = Krita.instance()
doc = inst.activeDocument()
if not doc: return
node = doc.activeNode()
sel = doc.selection()
new_sel = Selection()
if sel:
new_sel.replace(sel)
# if not sel:
# print("No selection...")
# return
#----------------------
# does not update visually
#----------------------
# [new_sel.dilate() for i in range(10)]
# [new_sel.erode() for i in range(10)]
# new_sel.border(5,10)
# new_sel.feather(10) # can't be visualized with ants anyway
# new_sel.grow(10,25)
# new_sel.shrink(5,10,0)
# new_sel.smooth() # can't be visualized with ants anyway
# new_sel.invert() #not the same as the action
#----------------------
# updates visually
#----------------------
all_sel = Selection()
# selects bounding box of all pixels in a node (even outside canvas area)
all_sel.selectAll(node,255)
new_sel.replace(all_sel)
# sub_sel = Selection()
# sub_sel.select(0,0,200,400,255)
# new_sel.subtract(sub_sel)
# int_sel = Selection()
# int_sel.select(0,0,200,400,255)
# new_sel.intersect(int_sel)
# new_sel.resize(100,100) # not sure how this is upposed to work
# new_sel.select(0,0,25,25,255) #select box in top left
# new_sel.contract(100) # confusing
# new_sel.move(0,100)
# dup_sel = new_sel.duplicate() # idk
# doc.setSelection(dup_sel)
#---
doc.setSelection(new_sel)
#---
# workaround: using this action to invert the selection twice forces an update
# inst.action("invert_selection").trigger()
# inst.action("invert_selection").trigger()
#---
end_time = time.time()
elapsed_time = (end_time - start_time) * 1000 # Convert to milliseconds
print(f"Function executed in {elapsed_time:.2f} milliseconds")
func()