Or they got __slots__ added, which would have the same effect.
One option, assuming that a ParseResults is hashable, would be to maintain your own dictionary that maps the results object to your own attributes. Or subclass the ParseResults and do nothing:
class ParseResults(ParseResults): pass
This will re-add a dict to it. But then you might have to monkey-patch that back into the place that creates them, which may not be a good idea.
The source code suggests that it was converted to slots for performance reasons. You could possibly ask the devs to add a userdata slot, which would be the same as just adding attributes, but safe against future changes, and wouldn’t have as big a performance cost as keeping a __dict__ on everything (since it would only be added when YOU choose to add it). In your code, the only change would be:
Pyparsing’s ParseResults class is somewhat split-personalitied. It is one of the classes that can be dict-like and namespace-like. (I was still somewhat new to Python when I wrote pyparsing, and I wasn’t sure which paradigm would be preferred. So I figured I would just support both.)
Here is a little parser that just gets a word and an integer, to get us a ParseResults object to work with:
import pyparsing as pp
a_word = pp.Word(pp.alphas)
a_number = pp.Word(pp.nums)
parser = a_word("some_word") + a_number("some_number")
result = parser.parse_string("Hi 1729")
(You can see this parser in railroad diagram form by setting names on the a_word, a_number, and parser expressions, and then calling parser.create_diagram with an output HTML file name.)
As you have already found, this won’t work:
result.some_data = "this won't work"
(I’m pleased to see that PyCharm will actually highlight this line, and indicate that result is read-only in this manner.)
However, you can make this assignment using the ParseResults dict-like access:
result["some_data"] = "this will work!"
And because ParseResults supports namespace-style access, you can then follow this with:
print(result.some_data)
A nice method on ParseResults is dump(), which will output a nested listing of the contents of a ParseResults including its named elements: