Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot access nested named elements #552

Open
Honza0297 opened this issue Apr 11, 2024 · 3 comments
Open

Cannot access nested named elements #552

Honza0297 opened this issue Apr 11, 2024 · 3 comments

Comments

@Honza0297
Copy link

When I define a named element inside another named element (e.g. pronoun inside sentence in the example below), I suppose I would be able to access the named elements recursively as shown in the example (parsed.sentence.verb).
Documentation does not describe this kind of situation, thus I am not sure whether this is a bug or a feature?
Thanks in advance for the answer!

Example below

from pyparsing import Word, alphas

# Define tokens
verb = Word(alphas).setResultsName("verb")
pronoun = Word(alphas).setResultsName("pronoun")
sentence = (pronoun + verb).setResultsName("sentence")

# Input string
input_str = "You are"

# Parse input
parsed = sentence.parseString(input_str)
# parsed.pprint()

# Access individual components
print(parsed.sentence.pronoun)  # Expected result: You, actual result: ' '
print(parsed.sentence.verb)     # Expected result: are, actual result: ' '
@ptmcg
Copy link
Member

ptmcg commented Apr 11, 2024

This is intended behavior. There is some help if you run with warnings enabled (python -Wall):

C:\Users\ptmcg\dev\venvs\pyparsing_311\Lib\site-packages\pyparsing\util.py:256: UserWarning: warn_ungrouped_named_tokens_in_collection: setting results name 'sentence' on And expression collides with 'pronoun' on contained expression
  return fn(self, *args, **kwargs)

The warning source line is not so great, because this actually occurs in the compatibility wrapper for setResultsName. If you change to using the newer PEP8 name set_results_name, and run with warnings, you'll get a better looking output:

C:\Users\ptmcg\dev\pyparsing\gh\pyparsing\scratch\nested_names.py:6: UserWarning: warn_ungrouped_named_tokens_in_collection: setting results name 'sentence' on And expression collides with 'pronoun' on contained expression
  sentence = (pronoun + verb)("sentence")

The solution is to Group the contents of sentence (after importing Group from pyparsing, of course):

sentence = Group(pronoun + verb).set_results_name("sentence")

Which will now give you the results you are looking for.

Some other notes:
parsed.pprint() will just print out the nested list. To see the assigned names, use print(parsed.dump()). Doing so will show how pronoun and verb are actually captured at the same level of sentence, since there is no grouping defined:

['You', 'are']
- pronoun: 'You'
- sentence: ['You', 'are']
- verb: 'are'

A handy short-cut for calling set_results_name is to just call the expression like it was a function:

verb = Word(alphas)("verb")
pronoun = Word(alphas)("pronoun")
sentence = Group(pronoun + verb)("sentence")

This way you don't have to worry about PEP8 method name or not.

There is also a new parse_string PEP8 name which you might want to start using. In the near future, I'll push out a release where the old pre-PEP8 names will start to emit DeprecationWarnings. and in the more distant future, I hope to get rid of the pre-PEP8 names altogether (while this won't be for a while yet, probably good to just get in the habit of using the newer names).

@ptmcg
Copy link
Member

ptmcg commented Apr 11, 2024

I was just looking through the docs, and I could have sworn I wrote these notes up. Maybe in the wiki... nope. The CHANGES file? Kinda, sorta. There is discussion of the new warning that flags ungrouped expressions (like sentence) being defined with internal expressions with results names. But this is buried pretty deep.

Let's leave this issue open as a reminder to me to update the docs.

@Honza0297
Copy link
Author

Although a little late, thanks for the detailed answer! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants