Further update on the Duplicate() function:
I have come to the conclusion that newitem = item.Duplicate()
creates a copy that is in some way dangerously shallow. That is to say, the newitem is a duplicate of the original item, but it appears to have copies of pointers to subsidiary objects that it now shares with the original.
So, for example, something like:
item = fp.Reference()
newitem = item.Duplicate()
fp.Add(newitem)
newitem.SetText("ABCD")
results in both the newitem and also the Reference() field both showing “ABCD”.
From the Python API, it’s not clear how this happens, though of course a dive into the actual C++ data structure behind (Reference()) and the Duplicate() code would reveal all.
Given this issue, the Python API doesn’t give any better confidence on any of the other “properties” that have Get and Set functions, as who knows what data structure and implementation is behind them.
My tentative conclusion is that Duplicate() on FP_TEXT (and similar) is not really usable for the purposes that its name suggests.
So instead you have to create, in effect, your own Duplicate function, which requires knowing what fields you will have to set in order to have a functioning FP_TEXT (or similar object).
So far, I’ve identified the following fields as necessary (in brief note form):
newitem = pcbnew.FP_TEXT(footprint)
SetText(newstr)
...
Get/Set Position()
Get/Set TextAngle()
Get/Set Layer()
Get/Set Visible()
Get/Set TextHeight()
Get/Set TextWidth()
Get/Set TextThickness()
Get/Set HorizJustify()
Get/Set VertJustify ()
footprint.Add(newitem)
… your Duplicate function could copy any or all of the fields from the existing item, or selectively set new values as suits your application.