Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add error handling for extract of incomplete block - #735

Merged
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block
Jan 11, 2024
Merged

Add error handling for extract of incomplete block#735
lieryan merged 3 commits into
python-rope:masterfrom
raymyers:extract-incomplete-block

Conversation

@raymyers

@raymyersraymyers commented Dec 15, 2023

Copy link
Copy Markdown
Contributor

Description

Raise exception when extracting the start of a block without the end, examples in the issue and the included tests.

Fixes#734

The added logic is:

  • Raise when:
    • region end is more indented than region start, AND
    • the next line after region end is indented as much as region end or more.
  • When any of these (start, end, or next) are on a blank/comment line, consider the next "real" line instead.

This seems correct to me and passes existing tests, but it could use a look by someone familiar with this part of the code to make sure it makes sense and is following conventions.

Checklist (delete if not relevant):

  • I have added tests that prove my fix is effective or that my feature works
  • I have updated CHANGELOG.md

@lieryan

lieryan commented Dec 16, 2023

Copy link
Copy Markdown
Member

Thanks for making this PR, @raymyers. IIUC, the current implementation here might not correctly handle multiline strings that have text indented less than the code or function calls/dicts/arguments that uses certain syntactically valid, but non-standard indentations, for example:

def foo():
if foo:
s = """
blah blah
blah
"""
print(
a, b, c
)

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils, exctract is only intended to work on source code that is syntactically valid python (i.e. they must be ast-parseable). What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block. That would allow the user to be a bit lazy and just select a few lines at the top of the block when extracting a block of statement.

Do you want to take a stab at reimplementing this with ast?

@raymyers
raymyersforce-pushed the extract-incomplete-block branch from 1cc0004 to 0acd85fCompareJanuary 7, 2024 20:12
@raymyers

Copy link
Copy Markdown
ContributorAuthor

Thanks for reviewing, @lieryan.

I suspect that it might be easier to handle all the edge cases for this if you're checking with the ast instead of sourceutils. [...] What you want to do is check that except at the top level of the selected AST node, the children node are either completely covered by the selected text range or not at all.

Good idea to use AST, I've updated it using the logic "there should be no node starting within extract range that ends after the range". Please take another look when you get a chance.

Another interesting alternative behavior could be that instead of producing an error, extract could have just automatically expanded the selection to cover the whole body if the user selected a partial block.

As a new contributor of course I don't speak for the direction of Rope, but I'll explain my rationale for suggesting this check be strict and erroring out rather than expanding:

I suspect it's not always going to be clear what direction was intended to change the selection (e.g. expand bottom vs shrink top). If anyone wants to try and repair the selection, maybe that should happen in the calling UI rather than here. Probably the calling app shouldn't have let a malformed selection get this far, failing to raise an error could mask that problem as it did in the usecase that led me to submit this. Intellij also disallows these invalid ranges fwiw.

@lieryan
lieryanforce-pushed the extract-incomplete-block branch from 0acd85f to 9cb3031CompareJanuary 11, 2024 01:41
@lieryan

Copy link
Copy Markdown
Member

Thanks for the contribution @raymyers, this looks great to me.

@all-contributors add @raymyers for code

@allcontributors

Copy link
Copy Markdown
Contributor

@lieryan

I couldn't determine any contributions to add, did you specify any contributions?
Please make sure to use valid contribution names.

I've put up a pull request to add @raymyers! 🎉

@lieryan
lieryan merged commit ffc8551 into python-rope:masterJan 11, 2024
@lieryanlieryan modified the milestones: 1.11.0, 1.12.0Jan 18, 2024
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract of incomplete block is allowed to half-execute

2 participants

@raymyers@lieryan