STC SetValue() not marking the control as not-modified

The wxPython v4.1.0 docs say that the StyledTextCtrl.SetValue() method marks the control as not-modified. However it doesn’t do that in the following test app.

# Module: stc_set_value_test.py

import wx
import wx.stc as stc

text = """\
SetValue(self, value)

    Sets the new text control value.

    It also marks the control as not-modified which means that IsModified() 
    would return False immediately after the call to SetValue .

    The insertion point is set to the start of the control (i.e. position 0) 
    by this function unless the control value doesn’t change at all, in which 
    case the insertion point is left at its original position.

    Note that, unlike most other functions changing the controls values, this 
    function generates a wxEVT_TEXT event. To avoid this you can use ChangeValue instead.

    Parameters

        value (string) – The new value to set. It may contain newline characters 
        if the text control is multi-line.
"""


class STCFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((600, 350))
        self.styled_text_ctrl = stc.StyledTextCtrl(self, wx.ID_ANY)
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(self.styled_text_ctrl, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()

        self.styled_text_ctrl.SetScrollWidth(1)
        self.styled_text_ctrl.SetScrollWidthTracking(True)

        print("Before SetValue() IsModified =", self.styled_text_ctrl.IsModified())
        self.styled_text_ctrl.SetValue(text)
        print("After SetValue() IsModified =", self.styled_text_ctrl.IsModified())



class MyApp(wx.App):
    def OnInit(self):
        self.frame = STCFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True


if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

The test app outputs:

Before SetValue() IsModified = False
After SetValue() IsModified = True

This is running on Python 3.8.5 + wxpython 4.1.0 gtk3 (phoenix) wxWidgets 3.1.4 + Linux Mint 20.

In order to help the STC class to have an API more like the various text entry widgets the C++ STC class inherits from classes that defines the common text entry interface. It’s not a perfect match however, and little details are simply not supported by the STC implementation of those common methods for various reasons. For example the STC has its own set of events and event class so it explicitly does not send EVT_TEXT.

To further complexify things, that C++ interface class and its base classes are not documented (which is were wxPython gets the info it needs to generate the wrappers) so I have to work around that by copying that method info from another class which also derives from that interface class, wxTextEntry, into the STC. So that is where the doc you are seeing for STC.SetValue is coming from.

There isn’t a good way to resolve this that does not also increase fragility or negatively impact maintainability, but I’m open to suggestions. (Or PRs.)

Thanks for your reply, Robin, I suspected that might be the case and have been using calls to SetText() and DiscardEdits() as an alternative.

I can understand your point about not wanting to create a large maintenance overhead in trying to track the cases where the functionality doesn’t match the documentation in its current form. Perhaps it would be sufficient to add a caveat at the top of the StyledTextCtrl page, explaining the situation in much the way that you did above. Hopefully, that way people would realise that the documentation may not be 100% accurate in all areas.