Repository navigation
Fix KV f-string name extraction for boolean expressions - #9393
Conversation
|
Thanks for opening your first pull request here! 💖 Please check out our contributing guidelines. |
|
Here is a simple reproducer: '''
Edit the box. The plain line follows. The f-string line stays put.
When the text is empty, the plain line shows 'backup' and the f-string line still shows 'hello'.
'''
from kivy.app import App
from kivy.lang import Builder
kv = '''
BoxLayout:
orientation: 'vertical'
padding: 16
spacing: 8
Label:
text: 'plain: ' + (source.text or 'backup')
Label:
text: 'f-string: ' + f"{source.text or 'backup'}"
TextInput:
id: source
text: 'hello'
multiline: False
size_hint_y: None
height: 40
'''
class Demo(App):
def build(self):
return Builder.load_string(kv)
if __name__ == '__main__':
Demo().run()Thanks for the fix. The parser change looks right to me. I'd ask for a few changes to the tests so they fail on master and pass only with this fix.
The end of the test would look like this: I checked these against current master and against your change. Every new check fails on master and passes with the fix. |
|
Thanks, I applied your test changes in c6335e0: strict What I ran: the names test passes with the dotted case against the new parser. I could not run |
|
Thanks for the updates. I ran the new tests locally: both fail against master's parser and pass with your change, and CI is green. This looks good to me. A recommended simplification: In parser.py the shared branch can stay if the f-string unwrapping moves into its own Literal text in an f-string is a In the simpler version, the .value step belongs to FormattedValue, not to the loop. With a branch for it, both lists (ast.JoinedStr, ast.BoolOp) can be walked the same way, as shown above. It's the same behavior with one loop instead of two. I ran the PR's tests with this version and they pass. The current change is also correct. I suspect the maintainer would prefer the simplified version. I apologize for not noticing this my initial review. |
JoinedStr and BoolOp share one loop over node.values; FormattedValue yields from its value. Same behavior, one loop instead of two.
|
Thanks for running the tests and for the suggestion. I moved the f-string unwrapping into its own |
|
Thanks for the review, kuzeyron. Is there anything else you need from me before this can merge? |
Looks good to me thank you! |
|
The backport to To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add .worktrees/backport-devel-2.3.x devel-2.3.x
# Navigate to the new working tree
cd .worktrees/backport-devel-2.3.x
# Create a new branch
git switch --create backport-9393-to-devel-2.3.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 951556e09341f0d5a8609cfc20c487a7551ea038
# Push it to GitHub
git push --set-upstream origin backport-9393-to-devel-2.3.x
# Go back to the original working tree
cd ../..
# Delete the working tree
git worktree remove .worktrees/backport-devel-2.3.xThen, create a pull request where the |
An f-string such as
f"{a or b}"in a KV rule crashes the parser withAttributeError: 'Name' object has no attribute 'value'.ParserRuleProperty.get_names_from_expressionshares one branch forast.JoinedStrandast.BoolOp, reading.valuefrom every element. That works forJoinedStr.values(FormattedValue nodes), butBoolOp.valuesholds plain expression nodes, so aNamenode crashes the lookup and anyor/andinside an f-string breaks the whole KV file.Split the branches:
JoinedStrkeeps the existing.valuetraversal, andBoolOpnow recurses into each operand directly, which also handles nesting likea or (b and c).Adds parser-level extraction tests and a Builder binding test showing both operands stay reactive.
Closes #9390.
Validation:
Caveat: master needs a native SDL toolchain, so the patched tests were run against the released 2.3.1 wheel carrying the identical method; master's own suite was not run. The Builder binding test needs a display (xvfb-run).