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

bpo-21756: fix IDLE's "show surrounding parens" for multi-line statements #20753

Conversation

taleinat
Copy link
Contributor

@taleinat taleinat commented Jun 9, 2020

@@ -23,7 +23,7 @@


class HyperParser:
def __init__(self, editwin, index):
def __init__(self, editwin, index, end_at_eol=True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a nit, but I prefer

Suggested change
def __init__(self, editwin, index, end_at_eol=True):
def __init__(self, editwin, index, *, end_at_eol=True):

for something like this.

Copy link
Contributor Author

@taleinat taleinat Jun 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion!

I'm still slowly chipping away at the deeply-ingrained "IDLE supports very old Python versions" rule in my mind...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One 3.7.8 is out, we can consider using new-in-3.8 features such as '/' in signatures and ':='.

if r:
stopatindex = text.index(r[0] + "-1c")
else:
stopatindex = "end-1c"
Copy link
Contributor

@csabella csabella Jun 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else is a bit unwieldy. Since hyperparser has tests, maybe it can be restructured with a high confidence of correctness?

        else:
            r = text.tag_prevrange("console", index)
            if r:
                startatindex = r[1]
            else:
                startatindex = "1.0"
            stopatindex = "%d.end" % lno
            if end_at_eol:
                stopatindex = "%d.end" % lno
            else:
                r = text.tag_nextrange("console", index)
                if r:
                    stopatindex = text.index(r[0] + "-1c")
                else:
                    stopatindex = "end-1c"

@csabella
Copy link
Contributor

csabella commented Jun 9, 2020

Nice! This works well. test_hyperparser.py has pretty good coverage, so maybe add tests for this change?

Also #18539 changes this code a little. It doesn't fix this issue, but we'll need to rebase whichever one is merged second.

@@ -23,7 +23,7 @@


class HyperParser:
def __init__(self, editwin, index):
def __init__(self, editwin, index, end_at_eol=True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think wrap or something like it would work instead of end_at_eol? I had to stop and think about end_at_eol to comprehend its meaning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the name "end_at_eol" isn't great. I'm not sure "wrap" is clear enough though. Perhaps "stop_at_line_end" or "multiline"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer one word or at most two (which don't necessarily need '_') rather than a phrase. The docstring can explain the word. In any case, the audience is only IDLE maintainers and there may never be more than one or two calls that change the current default. 'endline=True' is a possibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So "multiline"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

endline, multiline, oneline, singleline, continuation?

@@ -39,7 +39,7 @@ def index2line(index):
for context in editwin.num_context_lines:
startat = max(lno - context, 1)
startatindex = repr(startat) + ".0"
stopatindex = "%d.end" % lno
stopatindex = "%d.end" % lno if end_at_eol else "end-1c"
Copy link
Contributor

@csabella csabella Jun 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you're changing this line, an f-string would make this more readable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely.

@taleinat
Copy link
Contributor Author

Also #18539 changes this code a little. It doesn't fix this issue, but we'll need to rebase whichever one is merged second.

I'd be happy to handle that merging/rebasing, @csabella.

Also, let me know if you'd like my review for GH-18539.

@taleinat
Copy link
Contributor Author

Thanks for taking a look at this @csabella! I've made some changes based on your suggestions. It would be great if you could take another look :)

@taleinat
Copy link
Contributor Author

I also added a test and then discovered that this breaks rather badly in some cases... The underlying PyParse parser strongly assumes that it's only given code up to the end of the current statement.

@terryjreedy
Copy link
Member

An possible alternative is to leave Hyperparser.__init__ alone, add the new parameter, possibly endfile=False, to get_surrounding_brackets(), and do a separate forward scan for the closer when endfile is True and afterindex does not mark the closer.

@csabella
Copy link
Contributor

Also, let me know if you'd like my review for GH-18539.

Always! :-)

@taleinat
Copy link
Contributor Author

taleinat commented Oct 4, 2020

So, as it stands, this PR doesn't work properly, and breaks certain use-cases :( It's not a minor problem with the PR, it a problem with the approach. So I'm closing this PR.

Properly fixing bpo-21756 will simply require a more significant refactoring. Specifically, it will likely need a version of the code parser which can handle lines incrementally, maybe both backwards (to find the beginning of a code block) and forwards (to find the end).

@taleinat taleinat closed this Oct 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting core review DO-NOT-MERGE needs backport to 3.8 only security fixes needs backport to 3.9 only security fixes type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants