Open parenthesis in REPL completion

I'm not aware if that was already discussed, but something I find quite annoying is the REPL auto-complete that also includes the open parenthesis symbol. I think it shouldn't be included in TAB completion. At least twice a week I make mistakes like typing "help(something()" with unmatched parentheses, because the "something" was filled by a TAB completion, and the trailing open parenthesis wasn't expected (given that there's no such a completion elsewhere). -- Danilo J. S. Bellini --------------- "*It is not our business to set up prohibitions, but to arrive at conventions.*" (R. Carnap)

Hi Danilo I've exactly the same experience, and now take the behaviour for granted, and don't personally have a desire to fix the problem. I've got used to it. On Unix the behaviour follows from https://docs.python.org/3/library/rlcompleter.html and also https://docs.python.org/3/library/site.html#rlcompleter-config. I read in https://docs.python.org/3/library/site.html that site.py attempts "to import a module named usercustomize, which can perform arbitrary user-specific customizations". So I think that you, I or any other user could solve this problem for oneself, by creating a usercustomize.py. And that would be the first step to getting it into the standard library (or perhaps as an installation option for Python). I hope this helps. -- Jonathan

For most of the time, I'm already copying and pasting stuff from a text editor to use its completion instead. After more than an year having trouble with this, I think there's no way I can "get used" to it in any positive sense, but when I stick to the REPL for a long time, I'm aware that I press backspace all the time after TAB, sometimes unconsciously. Typing the last char manually hurts less than breaking the bracket matching expectation. I usually type both the open and close parentheses at once, then I move the cursor back one character to type its contents, so I never forget some unmatched parenthesis, but that strategy (which still works for other brackets and almost everywhere else) gets broken when some open parenthesis appear for some completions but not for others. On Sat, 20 Apr 2019 at 12:57, Jonathan Fine <jfine2358@gmail.com> wrote:
Thanks. From those links I found that this behavior is a quite old stuff <https://bugs.python.org/issue449227>, though the completion wasn't active by default in Python 2.7. The documentation states that only Python 3.4 activated it by default. The solution I found from reading that code is this oneliner, which I'll copy and paste after loading the REPL (yes, it's monkeypatching a seemingly private method): __import__("rlcompleter").Completer._callable_postfix = lambda self, val, word: word Is there a default PYTHONSTARTUP file name in Python 3.7.3, or at least a single global configuration file for the REPL where I can put that oneliner or a file reference with that line? I strongly prefer not to mess around with ~/.bashrc, ~/.zshrc and scattered stuff like that, if possible. -- Danilo J. S. Bellini --------------- "*It is not our business to set up prohibitions, but to arrive at conventions.*" (R. Carnap)

On Sun, Apr 21, 2019 at 3:52 AM Danilo J. S. Bellini <danilo.bellini@gmail.com> wrote:
I think it's probably cleaner to do this by subclassing Completer and overriding something (dig around to see what actually *calls* that), but either way, you can most certainly create yourself a config file. Details are here: https://docs.python.org/3/library/site.html You should be able to do everything you want with sitecustomize or usercustomize. If you need detailed help, python-list has lots of people who know how this works (way better than I do). ChrisA

On Fri, Apr 19, 2019 at 05:12:06PM -0300, Danilo J. S. Bellini wrote:
You could try reading the command line before hitting Enter *wink* I know what you mean, and it's a tiny annoyance for me too that when I type "help(function(" I have to delete the autocompleted opening bracket. So I guess that's a small annoyance a few dozen times a day. But having the opening bracket auto-added is a small satisfaction, and if you're using the REPL for actual calculations and not just help(), the benefit probably outweighs the annoyance: # save up to four opening brackets result = function(myclass(arg)) + another(x).method() So I don't think that have the extra complication of a switch to turn this feature off is a good idea. -- Steven

Steven D'Aprano writes:
But having the opening bracket auto-added is a small satisfaction,
I'm not going to weigh in on this feature: I can see it either way. What I don't get is why we don't go full metal Emacs, by adding the corresponding end delimiter, and backspace. In each line below the RHS are the characters typed, the LHS the characters inserted, and the vertical bar | represents the position of the insertion cursor: ( => (|) [ => [|] { => {|} " => "|" "" => ""| # fooled ya, didn't I? Could do it for parens too. """ => """|""" '' => ''| ''' => '''|''' There may be others. And bonus points for DTRT in strings and comments (especially for "'", since it's used as apostrophe in non-program text). Once I got used to it, I found it really cut down on the annoyance of counting parens and making sure start parens weren't paired with end braces and similar errors. YMMV, of course. Steve

On 25/04/2019 12:27, Stephen J. Turnbull wrote:
My mileage definitely varies. This sort of autocompletion is the first thing I turn off in the Eclipse-variants that come bundled with a lot of the SDKs I use, and I've never enabled it in EMACs. Automatically highlighting where the matching brackets or quotes are is a lovely thing, but I like making my own decisions and stepping past or deleting decisions the editor has made for me is a pain. -- Rhodri James *-* Kynesim Ltd

This is an interesting thread. Here's my two cents worth. (Colloquial US English for a low-value opinion.) I'm in favour of sensible defaults (of course). In this situation, perhaps this means defaults that work well for those who would find it difficult to select a different default. Put enough way, values that work well for Emacs users should not be the default (unless they also work well for beginners). Sometimes, when I'm using a module for the first time (or when I'm puzzled about Python's behaviour and online documentation), I find myself doing >>> help(something) quite often. And I find myself typing >>> help({}) instead of >>> help(dict) to avoid the unwanted >>> help(dict( My preference, which might work well for a wide range of use cases, is 1. If the initial identifier is help, tab produces the opening paren (. 2. If the intial identifier is callable, tab produces the opening paren (. 3. After help(, tab does not produce opening paren (. 4. Otherwise, tab does produce opening paren (. 5. Perhaps, after something like >>> help(int have tab produce the CLOSING paren ). As I said, just my two cents worth. Your opinions may vary. -- Jonathan

My two cents as well. I also find the open parenthesis very annoying. For me, it's asymmetry with PyCharm behavior, and inconsistency with bash. PyCharm adds the parenthesis, but also adds the end parenthesis, so the whole use of parentheses is consistent: the user has not to worry about them. Bash refuses to guess when it's ambiguous, and stops until you fill the ambiguous part. Right now, the REPL implements a mixed situation where it both assumes your usage, and does not help you all the way through. Although we can all agree that functions most of the time are invoked, rather than used as is. IMHO, either the parenthesis should not be added, or two parentheses should be added and the cursor placed in the center (I am unsure about the details of the REPL implementation, but I guess it's possible) at least to have a consistent experience. On Thu, 25 Apr 2019 at 14:24, Jonathan Fine <jfine2358@gmail.com> wrote:
-- Kind regards, Stefano Borini

On Thu, Apr 25, 2019 at 02:42:09PM +0100, Stefano Borini wrote:
In Python, functions are first-class values, so parentheses or not is *always* ambiguous. If I start typing the name of a function, there is no way for the REPR to know whether I want to call the function or refer to it as an object. Although it might *guess* that calling a function is more common than treating it as a value.
How ironic if a request on Python-Ideas to *stop* adding the opening parenthesis leads to the REPR adding the closing parenthesis as well. The more I think about it, the more I suspect the least-worst solution will be to make tab-completion configurable, with three options: - no parentheses - both parentheses - only the opening parenthesis (status quo) and an API to set the behaviour at startup depending on an environment variable or a config file. Anyone want to propose a patch? -- Steven

On Fri, Apr 26, 2019 at 11:14:32AM +1200, Greg Ewing wrote:
It could, but is that special case special enough to break the rules? "Why doesn't tab completion work correctly in help? I'm trying to call help(builder()) but tab completion doesn't add the opening parenthesis to builder..." -- Steven

Hi Danilo I've exactly the same experience, and now take the behaviour for granted, and don't personally have a desire to fix the problem. I've got used to it. On Unix the behaviour follows from https://docs.python.org/3/library/rlcompleter.html and also https://docs.python.org/3/library/site.html#rlcompleter-config. I read in https://docs.python.org/3/library/site.html that site.py attempts "to import a module named usercustomize, which can perform arbitrary user-specific customizations". So I think that you, I or any other user could solve this problem for oneself, by creating a usercustomize.py. And that would be the first step to getting it into the standard library (or perhaps as an installation option for Python). I hope this helps. -- Jonathan

For most of the time, I'm already copying and pasting stuff from a text editor to use its completion instead. After more than an year having trouble with this, I think there's no way I can "get used" to it in any positive sense, but when I stick to the REPL for a long time, I'm aware that I press backspace all the time after TAB, sometimes unconsciously. Typing the last char manually hurts less than breaking the bracket matching expectation. I usually type both the open and close parentheses at once, then I move the cursor back one character to type its contents, so I never forget some unmatched parenthesis, but that strategy (which still works for other brackets and almost everywhere else) gets broken when some open parenthesis appear for some completions but not for others. On Sat, 20 Apr 2019 at 12:57, Jonathan Fine <jfine2358@gmail.com> wrote:
Thanks. From those links I found that this behavior is a quite old stuff <https://bugs.python.org/issue449227>, though the completion wasn't active by default in Python 2.7. The documentation states that only Python 3.4 activated it by default. The solution I found from reading that code is this oneliner, which I'll copy and paste after loading the REPL (yes, it's monkeypatching a seemingly private method): __import__("rlcompleter").Completer._callable_postfix = lambda self, val, word: word Is there a default PYTHONSTARTUP file name in Python 3.7.3, or at least a single global configuration file for the REPL where I can put that oneliner or a file reference with that line? I strongly prefer not to mess around with ~/.bashrc, ~/.zshrc and scattered stuff like that, if possible. -- Danilo J. S. Bellini --------------- "*It is not our business to set up prohibitions, but to arrive at conventions.*" (R. Carnap)

On Sun, Apr 21, 2019 at 3:52 AM Danilo J. S. Bellini <danilo.bellini@gmail.com> wrote:
I think it's probably cleaner to do this by subclassing Completer and overriding something (dig around to see what actually *calls* that), but either way, you can most certainly create yourself a config file. Details are here: https://docs.python.org/3/library/site.html You should be able to do everything you want with sitecustomize or usercustomize. If you need detailed help, python-list has lots of people who know how this works (way better than I do). ChrisA

On Fri, Apr 19, 2019 at 05:12:06PM -0300, Danilo J. S. Bellini wrote:
You could try reading the command line before hitting Enter *wink* I know what you mean, and it's a tiny annoyance for me too that when I type "help(function(" I have to delete the autocompleted opening bracket. So I guess that's a small annoyance a few dozen times a day. But having the opening bracket auto-added is a small satisfaction, and if you're using the REPL for actual calculations and not just help(), the benefit probably outweighs the annoyance: # save up to four opening brackets result = function(myclass(arg)) + another(x).method() So I don't think that have the extra complication of a switch to turn this feature off is a good idea. -- Steven

Steven D'Aprano writes:
But having the opening bracket auto-added is a small satisfaction,
I'm not going to weigh in on this feature: I can see it either way. What I don't get is why we don't go full metal Emacs, by adding the corresponding end delimiter, and backspace. In each line below the RHS are the characters typed, the LHS the characters inserted, and the vertical bar | represents the position of the insertion cursor: ( => (|) [ => [|] { => {|} " => "|" "" => ""| # fooled ya, didn't I? Could do it for parens too. """ => """|""" '' => ''| ''' => '''|''' There may be others. And bonus points for DTRT in strings and comments (especially for "'", since it's used as apostrophe in non-program text). Once I got used to it, I found it really cut down on the annoyance of counting parens and making sure start parens weren't paired with end braces and similar errors. YMMV, of course. Steve

On 25/04/2019 12:27, Stephen J. Turnbull wrote:
My mileage definitely varies. This sort of autocompletion is the first thing I turn off in the Eclipse-variants that come bundled with a lot of the SDKs I use, and I've never enabled it in EMACs. Automatically highlighting where the matching brackets or quotes are is a lovely thing, but I like making my own decisions and stepping past or deleting decisions the editor has made for me is a pain. -- Rhodri James *-* Kynesim Ltd

This is an interesting thread. Here's my two cents worth. (Colloquial US English for a low-value opinion.) I'm in favour of sensible defaults (of course). In this situation, perhaps this means defaults that work well for those who would find it difficult to select a different default. Put enough way, values that work well for Emacs users should not be the default (unless they also work well for beginners). Sometimes, when I'm using a module for the first time (or when I'm puzzled about Python's behaviour and online documentation), I find myself doing >>> help(something) quite often. And I find myself typing >>> help({}) instead of >>> help(dict) to avoid the unwanted >>> help(dict( My preference, which might work well for a wide range of use cases, is 1. If the initial identifier is help, tab produces the opening paren (. 2. If the intial identifier is callable, tab produces the opening paren (. 3. After help(, tab does not produce opening paren (. 4. Otherwise, tab does produce opening paren (. 5. Perhaps, after something like >>> help(int have tab produce the CLOSING paren ). As I said, just my two cents worth. Your opinions may vary. -- Jonathan

My two cents as well. I also find the open parenthesis very annoying. For me, it's asymmetry with PyCharm behavior, and inconsistency with bash. PyCharm adds the parenthesis, but also adds the end parenthesis, so the whole use of parentheses is consistent: the user has not to worry about them. Bash refuses to guess when it's ambiguous, and stops until you fill the ambiguous part. Right now, the REPL implements a mixed situation where it both assumes your usage, and does not help you all the way through. Although we can all agree that functions most of the time are invoked, rather than used as is. IMHO, either the parenthesis should not be added, or two parentheses should be added and the cursor placed in the center (I am unsure about the details of the REPL implementation, but I guess it's possible) at least to have a consistent experience. On Thu, 25 Apr 2019 at 14:24, Jonathan Fine <jfine2358@gmail.com> wrote:
-- Kind regards, Stefano Borini

On Thu, Apr 25, 2019 at 02:42:09PM +0100, Stefano Borini wrote:
In Python, functions are first-class values, so parentheses or not is *always* ambiguous. If I start typing the name of a function, there is no way for the REPR to know whether I want to call the function or refer to it as an object. Although it might *guess* that calling a function is more common than treating it as a value.
How ironic if a request on Python-Ideas to *stop* adding the opening parenthesis leads to the REPR adding the closing parenthesis as well. The more I think about it, the more I suspect the least-worst solution will be to make tab-completion configurable, with three options: - no parentheses - both parentheses - only the opening parenthesis (status quo) and an API to set the behaviour at startup depending on an environment variable or a config file. Anyone want to propose a patch? -- Steven

On Fri, Apr 26, 2019 at 11:14:32AM +1200, Greg Ewing wrote:
It could, but is that special case special enough to break the rules? "Why doesn't tab completion work correctly in help? I'm trying to call help(builder()) but tab completion doesn't add the opening parenthesis to builder..." -- Steven
participants (8)
-
Chris Angelico
-
Danilo J. S. Bellini
-
Greg Ewing
-
Jonathan Fine
-
Rhodri James
-
Stefano Borini
-
Stephen J. Turnbull
-
Steven D'Aprano