Mailing List Archive

Baffled by readline module
In an interactive command-line Python program on Linux, I want to be
able to read a line at a time from stdin, providing command line
history and editing to the user. In C, I would use GNU readline to do
that.

Python has the readline module, which appears to be a wrapper for GNU
readline. However, I've read and re-read the documenation for that
module, but I'm completely baffled. There's all sorts of stuff about
history files, but I neither need nor want a history file. Likewise
tab-completion: don't want it. All the examples not only involve
history files and tab-completion but they're somehow connected to the
interactive Python REPL, which is also completely off-base for my use
case.

Is the readline module not the right tool for an interactive Linux
command-line application that needs to provide command line recall and
editing to the user who's entering stuff on stdin from a tty?

--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09, Grant Edwards <grant.b.edwards@gmail.com> wrote:

> In an interactive command-line Python program on Linux, I want to be
> able to read a line at a time from stdin, providing command line
> history and editing to the user. In C, I would use GNU readline to do
> that.
>
> Python has the readline module, which appears to be a wrapper for GNU
> readline. However, I've read and re-read the documenation for that
> module, but I'm completely baffled.

After googling for a while, I finally stumbled across an old Python 2
example that pointed me in the right direction. Here's the sort of
example I had hoped to find in the module's docs:

#!/usr/bin/python
import readline

readline.parse_and_bind('set editing-mode emacs')

while True:
try:
line = input('enter something (EOF to quit): ')
except EOFError:
print()
break
print('You entered: "%s"' % line)




--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 06:28, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>
> In an interactive command-line Python program on Linux, I want to be
> able to read a line at a time from stdin, providing command line
> history and editing to the user. In C, I would use GNU readline to do
> that.
>
> Python has the readline module, which appears to be a wrapper for GNU
> readline. However, I've read and re-read the documenation for that
> module, but I'm completely baffled. There's all sorts of stuff about
> history files, but I neither need nor want a history file. Likewise
> tab-completion: don't want it. All the examples not only involve
> history files and tab-completion but they're somehow connected to the
> interactive Python REPL, which is also completely off-base for my use
> case.
>
> Is the readline module not the right tool for an interactive Linux
> command-line application that needs to provide command line recall and
> editing to the user who's entering stuff on stdin from a tty?
>

Not sure about the history file, and I would assume that if you don't
configure one, history is simply lost when you restart. But with tab
completion, unless you need to be able to input a tab character, it
should be safe to ignore the feature and leave it at the defaults.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09, Chris Angelico <rosuav@gmail.com> wrote:

> Not sure about the history file, and I would assume that if you don't
> configure one, history is simply lost when you restart. But with tab
> completion, unless you need to be able to input a tab character, it
> should be safe to ignore the feature and leave it at the defaults.

Indeed, that seems to be how it works (though I never found that
stated anywhere in the docs).

What's really weird about the docs is that when it is described it
doesn't even _mention_ that it provides command-line recall and
editing:

The readline module defines a number of functions to facilitate
completion and reading/writing of history files from the Python
interpreter. This module can be used directly, or via the
rlcompleter module, which supports completion of Python
identifiers at the interactive prompt. Settings made using this
module affect the behaviour of both the interpreter’s interactive
prompt and the prompts offered by the built-in input() function.

It just talks about manipulating history files and about
tab-completion of Python identfiers. The last sentence mentions that
settings affect both the REPL prompt and the prompts offered by the
built-in input() function.

However, I also don't really care about the "prompts offered"
either. What I care about is the interactive handling of user
keystrokes vis-a-vis command line recall and editing.

Or is that what's meant by the phrase "behavior of the prompt"?

To me "the prompt" is the string that's printed _before_ the program
starts reading user keystrokes and doing the stuff I care about.

It finally dawned on me after seeing an example I found elsewhere that
you don't call some module method to fetch the next user-entered line.

You call the input() built-in.

Having a module modify the behavior of a built-in makes me cringe.

I suppose this way you can easily slap-on "readline" command-line
recall/editing to an existing application as long as it uses the
input() built-in instead of reading from stdin.

--
Grant


--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 08:10, Grant Edwards <grant.b.edwards@gmail.com> wrote:
> What's really weird about the docs is that when it is described it
> doesn't even _mention_ that it provides command-line recall and
> editing:
>
> It just talks about manipulating history files and about
> tab-completion of Python identfiers. The last sentence mentions that
> settings affect both the REPL prompt and the prompts offered by the
> built-in input() function.
>

Ah. Yes, that's because the **module** doesn't provide command-line
recall and editing. It does affect the input() builtin, as is
mentioned, but mainly, the module is to configure readline, not to ask
for a line of text.

It's a bit confusing, but very useful.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 09Mar2023 13:08, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>On 2023-03-09, Chris Angelico <rosuav@gmail.com> wrote:
>> Not sure about the history file, and I would assume that if you don't
>> configure one, history is simply lost when you restart. But with tab
>> completion, unless you need to be able to input a tab character, it
>> should be safe to ignore the feature and leave it at the defaults.
>
>Indeed, that seems to be how it works (though I never found that
>stated anywhere in the docs).
>
>What's really weird about the docs is that when it is described it
>doesn't even _mention_ that it provides command-line recall and
>editing:
[...]

I think this might be the common case of a module which wraps another
library: there's a tension between describing everything in pointless
detail and the trite "we're just shimming this library, go read its
docs".

The module documentation needs to:
- not insult the reader by saying nearly nothing ("this is just GNU
readline, hooked to Python!") I'm looking at you, many "man" pages on
a GNU based system which say "oh just go and read GNI info, it's all
over there"
- be detailed enough to enumerate the API calls and at least summarise
their semantics
- be general enough to not overprescribe so that small shifts in the
library as it evolves don't cause falsehoods in the module docs (and a
nightmarish maintenance burden)

Similar example: the "os" modules, which largely shims the OS POSIX
calls. It lists them and has a paragraph on their purpose and the
meaning of the flags (for example). But the platform specifics and fine
grained stuff is off in "man 2 foo" for the Python "os.foo" function.

[...]
>It finally dawned on me after seeing an example I found elsewhere that
>you don't call some module method to fetch the next user-entered line.
>
>You call the input() built-in.

Ah. That's not overtly stated? [...reads...] Ah, there it is in the last
sentence of the opening paragraph. Not quite as in-your-face as I'd have
liked it. That paragraph could do with being a bullet list of use cases.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 09:01, Cameron Simpson <cs@cskk.id.au> wrote:
> I think this might be the common case of a module which wraps another
> library: there's a tension between describing everything in pointless
> detail and the trite "we're just shimming this library, go read its
> docs".

Yeah, it's a combination of this...

> >You call the input() built-in.
>
> Ah. That's not overtly stated? [...reads...] Ah, there it is in the last
> sentence of the opening paragraph. Not quite as in-your-face as I'd have
> liked it. That paragraph could do with being a bullet list of use cases.

... and this. With a lot of "just wrap that library" functions, it can
be exactly as you say: a bit of documentation about each function, and
you can skim those to see what's available. But with readline, there
isn't a "give me a command from the user" function, because that's
input().

Maybe there should be an example added at the end?

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09, Cameron Simpson <cs@cskk.id.au> wrote:

> [...]
>>It finally dawned on me after seeing an example I found elsewhere that
>>you don't call some module method to fetch the next user-entered line.
>>
>>You call the input() built-in.
>
> Ah. That's not overtly stated? [...reads...] Ah, there it is in the last
> sentence of the opening paragraph. Not quite as in-your-face as I'd have
> liked it.

What threw me off the track for a while was that the sentence to which
you refer says it affects the "prompts offered by input()". In my head,
that means it changes the string that's printed on stdout before stuff
is read from stdin. That's different that affecting the handling of
user input read by input().

It doesn't actually change anything about the prompts provided by
input(). It changes the handling of the user input by input().

I guess I read it too literally. I must spend too much time with
computers.

> That paragraph could do with being a bullet list of use cases.



--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 09:20, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>
> On 2023-03-09, Cameron Simpson <cs@cskk.id.au> wrote:
>
> > [...]
> >>It finally dawned on me after seeing an example I found elsewhere that
> >>you don't call some module method to fetch the next user-entered line.
> >>
> >>You call the input() built-in.
> >
> > Ah. That's not overtly stated? [...reads...] Ah, there it is in the last
> > sentence of the opening paragraph. Not quite as in-your-face as I'd have
> > liked it.
>
> What threw me off the track for a while was that the sentence to which
> you refer says it affects the "prompts offered by input()". In my head,
> that means it changes the string that's printed on stdout before stuff
> is read from stdin. That's different that affecting the handling of
> user input read by input().
>
> It doesn't actually change anything about the prompts provided by
> input(). It changes the handling of the user input by input().
>
> I guess I read it too literally. I must spend too much time with
> computers.

It does actually affect the prompts, although only in subtle ways.

import readline
print("Pseudo-prompt: ", end="")
msg1 = input()
msg2 = input("Actual prompt: ")
print(repr(msg1))
print(repr(msg2))

At each of the prompts, type a bit of text, then backspace it all the
way. The actual prompt will remain, but the pseudo-prompt will get
cleared off. There'll be other small differences too.

Maybe that could be mentioned somewhere too; but this is definitely
something to be more careful with locking in, since the behaviour may
not be quite the same if it's using libedit instead of GNU readline.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09, Grant Edwards <grant.b.edwards@gmail.com> wrote:
> On 2023-03-09, Cameron Simpson <cs@cskk.id.au> wrote:
>
>> [...]
>>>It finally dawned on me after seeing an example I found elsewhere that
>>>you don't call some module method to fetch the next user-entered line.
>>>
>>>You call the input() built-in.
>>
>> Ah. That's not overtly stated? [...reads...] Ah, there it is in the last
>> sentence of the opening paragraph. Not quite as in-your-face as I'd have
>> liked it.
>
> What threw me off the track for a while was that the sentence to which
> you refer says it affects the "prompts offered by input()". In my head,
> that means it changes the string that's printed on stdout before stuff
> is read from stdin. That's different that affecting the handling of
> user input read by input().
>
> It doesn't actually change anything about the prompts provided by
> input(). It changes the handling of the user input by input().
>
> I guess I read it too literally. I must spend too much time with
> computers.

Yeesh. What's _really_ embarassing is that I just stumbled across a
small test program with which I had apparently figured this out 10-12
years ago. Must be about time to retire...

--
Grant
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 10:04, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>
> Yeesh. What's _really_ embarassing is that I just stumbled across a
> small test program with which I had apparently figured this out 10-12
> years ago. Must be about time to retire...
>

You expect yourself to remember test programs you wrote a decade ago??
I've forgotten full-on projects from that far back!

Though, congrats on being able to stumble across it. That's quite something.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 09Mar2023 13:08, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>Having a module modify the behavior of a built-in makes me cringe.

Maybe. But input(), like print(), is one of those funky conveniences for
human interaction. I'm somewhat ok with that. If for no other reason
than to make keyboard arrow keys act as normal humans expect them to (as
opposed to old nerds who predate such fancies). General improvement of
the user experience.

Another thing affected by readline is the cmd module, which will use it
during the input step for completion _if the module is present_. And
use it for the input itself if it is loaded. (These might not mean
different things and instead be an accident of phrasing.) Again, a human
interaction convenience and I'm good with it.

Good enough to have written this code recently:

try:
import readline
except ImportError:
pass

just to turn it on if available.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09, Chris Angelico <rosuav@gmail.com> wrote:
> On Fri, 10 Mar 2023 at 10:04, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>
>> Yeesh. What's _really_ embarassing is that I just stumbled across a
>> small test program with which I had apparently figured this out
>> 10-12 years ago. Must be about time to retire...
>
> You expect yourself to remember test programs you wrote a decade
> ago?? I've forgotten full-on projects from that far back!

Another thing that has happened a few times is that I'm trying to
figure out how to do something I'm pretty sure should be possible, but
I can't figure out how. After the usual resources fail, then I start
Googling with varous sets of keywords. After a while, Google eventually
finds the answer in an old mailing-list archive where there's a nice
explanation in a post...

.... by me.


> Though, congrats on being able to stumble across it. That's quite
> something.

After I figured out the answer, I realized it did seem a little
familar, so I tried a grep -r in my home directory which has stuff
lying around from as far back as 2001. When a computer dies, I
generally just cp -a (or rsync -a) $HOME to a new one.

--
Grant
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09 at 15:02:53 -0800,
Grant Edwards <grant.b.edwards@gmail.com> wrote:

> Yeesh. What's _really_ embarassing is that I just stumbled across a
> small test program with which I had apparently figured this out 10-12
> years ago. Must be about time to retire...

Retiring doesn't help. :-)

I retired almost five years ago, and I just (within the past few days)
(re)discovered a command line parsing library I'd written about a year
and a half ago (i.e., after I retired).

Dan
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 10:51, <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:
>
> On 2023-03-09 at 15:02:53 -0800,
> Grant Edwards <grant.b.edwards@gmail.com> wrote:
>
> > Yeesh. What's _really_ embarassing is that I just stumbled across a
> > small test program with which I had apparently figured this out 10-12
> > years ago. Must be about time to retire...
>
> Retiring doesn't help. :-)
>
> I retired almost five years ago, and I just (within the past few days)
> (re)discovered a command line parsing library I'd written about a year
> and a half ago (i.e., after I retired).
>

Traditional retirement: Work till you're 60 or 65 or whatever, then
society pats you on the head, calls you a "senior citizen", and lets
you go and be idle till you die (which might be prematurely soon).

Direction-change retirement: Work till you can afford to zero out your
income, then finally do what you've always wanted to do, but never had
time because you spent so much of it earning money.

Tell-the-next-generation: Work till you know so much that you're
infinitely valuable, then spend the rest of your life empowering the
next group of amazing people. See for instance: NASA.

Programmer retirement: At an early age, learn how to wield PHENOMENAL
COSMIC POWER, and spend the next X years in an itty bitty working
space, earning money. Eventually, upgrade to better living/working
space. Eventually, downgrade to a small wooden box six feet below the
ground. Never once relinquish the power. Never once abandon that
feeling of mastery.

We're not really an industry that has a concept of retirement.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 10:08 am, Grant Edwards wrote:
> It finally dawned on me after seeing an example I found elsewhere that
> you don't call some module method to fetch the next user-entered line.
>
> You call the input() built-in.
>
> Having a module modify the behavior of a built-in makes me cringe.

Importing the module is not modifying the built-in.

If your Python has been compiled with gnu readline support,
input() *already* provides recall and editing facilities.

You only need to import the readline module if you want to
change the configuration.

Yes, it would be helpful if the docs for the readline module
explained this. At present they seem to assume that you already
know what the readline module is for and just want a summary
of the API.

It *is* mentioned briefly in the docs for input(), but again
somebody wanting line editing functionality wouldn't necessarily
think of looking there.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 10:59 am, Cameron Simpson wrote:
> I think this might be the common case of a module which wraps another
> library

It's not quite the same thing, though -- the library it wraps
is already hooked into things behind the scenes in ways that
may not be obvious. (Unless you're Dutch?)

--
Greg

--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 11:43 am, Chris Angelico wrote:
> import readline
> print("Pseudo-prompt: ", end="")
> msg1 = input()
> msg2 = input("Actual prompt: ")
> print(repr(msg1))
> print(repr(msg2))
>
> At each of the prompts, type a bit of text, then backspace it all the
> way. The actual prompt will remain, but the pseudo-prompt will get
> cleared off. There'll be other small differences too.

Hmmm, so it seems that merely importing readline does change
things a little bit.

This is rather nasty. I'd go so far as to call it a bug in
gnu readline -- it shouldn't be erasing something that the
user didn't type in.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10 at 11:02:52 +1100,
Chris Angelico <rosuav@gmail.com> wrote:

> Traditional retirement: Work till you're 60 or 65 or whatever, then
> society pats you on the head, calls you a "senior citizen", and lets
> you go and be idle till you die (which might be prematurely soon).

Sounds like Free Four?:

The memories of a man in his old age
Are the deeds of a man in his prime.

You shuffle in the gloom of the sickroom
And talk to yourself as you die.

Great tune. Bad life.

> Direction-change retirement: Work till you can afford to zero out your
> income, then finally do what you've always wanted to do, but never had
> time because you spent so much of it earning money.

A little bit of that. We live in the RV, and we have crisscrossed the
country more than once, coronavirus notwithstanding.

> Tell-the-next-generation: Work till you know so much that you're
> infinitely valuable, then spend the rest of your life empowering the
> next group of amazing people. See for instance: NASA.

And a little bit of that, too. NASA would have been nice; I did my most
of my time in the commercial space, with a short break in the government
contracting business.

> Programmer retirement: At an early age, learn how to wield PHENOMENAL
> COSMIC POWER, and spend the next X years in an itty bitty working
> space, earning money. Eventually, upgrade to better living/working
> space. Eventually, downgrade to a small wooden box six feet below the
> ground. Never once relinquish the power. Never once abandon that
> feeling of mastery.

I was with you until that part of the small wooden box. :-)

> We're not really an industry that has a concept of retirement.

Which is why I'm still here (on this mailing list, and a handful of
others like it).

Thanks for asking.

? https://www.azlyrics.com/lyrics/pinkfloyd/freefour.html
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 12:43 pm, Grant Edwards wrote:
> When a computer dies, I
> generally just cp -a (or rsync -a) $HOME to a new one.

Same here, more or less. My current machine has multiple
archaeological layers going back about 5 generations of
technology...

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10, Greg Ewing via Python-list <python-list@python.org> wrote:
> On 10/03/23 10:08 am, Grant Edwards wrote:
>> It finally dawned on me after seeing an example I found elsewhere that
>> you don't call some module method to fetch the next user-entered line.
>>
>> You call the input() built-in.
>>
>> Having a module modify the behavior of a built-in makes me cringe.
>
> Importing the module is not modifying the built-in.
>
> If your Python has been compiled with gnu readline support,
> input() *already* provides recall and editing facilities.

That's not how Python 3.10.10 works for me. When I run the code below,
I do not get command recall and editing. If I hit arrow keys, I just
see the escape sequence echoed and returned by input(). Likewise for
things like ctrl-P, ctrl-N, etc. I have to uncomment the import
statement to get command line recall and editing to work. Without the
import, the escape sequences from arrow keys just end up in the input
data.

#!/usr/bin/python

# import readline
# readline.parse_and_bind('set editing-mode emacs')

while True:
try:
line = input('enter something (EOF to quit): ')
except EOFError:
print()
break
print('ENTERED: "%s"' % line)


> You only need to import the readline module if you want to
> change the configuration.

That's not how it acts for me. I have to "import readline" to get
command line recall and editing. The parse_and_bind, doesn't seem to
do anything -- emacs mode seems to be the default.

> Yes, it would be helpful if the docs for the readline module
> explained this. At present they seem to assume that you already
> know what the readline module is for and just want a summary
> of the API.
>
> It *is* mentioned briefly in the docs for input(), but again
> somebody wanting line editing functionality wouldn't necessarily
> think of looking there.



--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 1:46 pm, Grant Edwards wrote:
> That's not how it acts for me. I have to "import readline" to get
> command line recall and editing.

Maybe this has changed? Or is platform dependent?

With Python 3.8 on MacOSX I can use up arrow with input()
to recall stuff I've typed before, without having to
import anything.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, 10 Mar 2023 at 12:56, Greg Ewing via Python-list
<python-list@python.org> wrote:
>
> On 10/03/23 1:46 pm, Grant Edwards wrote:
> > That's not how it acts for me. I have to "import readline" to get
> > command line recall and editing.
>
> Maybe this has changed? Or is platform dependent?
>
> With Python 3.8 on MacOSX I can use up arrow with input()
> to recall stuff I've typed before, without having to
> import anything.
>

import sys; "readline" in sys.modules

Is it? Might be that something's pre-importing it.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10 at 12:57:48 +1100,
Chris Angelico <rosuav@gmail.com> wrote:

> On Fri, 10 Mar 2023 at 12:56, Greg Ewing via Python-list
> <python-list@python.org> wrote:
> >
> > On 10/03/23 1:46 pm, Grant Edwards wrote:
> > > That's not how it acts for me. I have to "import readline" to get
> > > command line recall and editing.
> >
> > Maybe this has changed? Or is platform dependent?
> >
> > With Python 3.8 on MacOSX I can use up arrow with input()
> > to recall stuff I've typed before, without having to
> > import anything.
> >
>
> import sys; "readline" in sys.modules
>
> Is it? Might be that something's pre-importing it.

My ~/.pythonrc contains the following:

import readline
import rlcompleter
readline.parse_and_bind( 'tab: complete' )

IIRC, that's been there "forever," certainly back into Python2, and
probably back into Python1. On my Arch Linux system Python 3.10.9, I
get readline behavior with or without those lines.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10, 2QdxY4RzWzUUiLuE@potatochowder.com <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:
> On 2023-03-10 at 12:57:48 +1100,
> Chris Angelico <rosuav@gmail.com> wrote:
>
>> On Fri, 10 Mar 2023 at 12:56, Greg Ewing via Python-list
>> <python-list@python.org> wrote:
>> >
>> > On 10/03/23 1:46 pm, Grant Edwards wrote:
>> > > That's not how it acts for me. I have to "import readline" to get
>> > > command line recall and editing.
>> >
>> > Maybe this has changed? Or is platform dependent?
>> >
>> > With Python 3.8 on MacOSX I can use up arrow with input()
>> > to recall stuff I've typed before, without having to
>> > import anything.

If you run this application from the command line, you get command
recall and editing when entering strings at the "cmd:" prompt?

#!/usr/bin/python
while True:
try:
line = input('cmd: ')
except EOFError:
print()
break
print('You entered "%s"' % line)

>> import sys; "readline" in sys.modules
>>
>> Is it? Might be that something's pre-importing it.
>
> My ~/.pythonrc contains the following:
>
> import readline
> import rlcompleter
> readline.parse_and_bind( 'tab: complete' )
>
> IIRC, that's been there "forever," certainly back into Python2, and
> probably back into Python1. On my Arch Linux system Python 3.10.9, I
> get readline behavior with or without those lines.

I "get readline behavior" in the REPL without an "import readline",
but that's irrelevent. We're talking about a command-line
application that's calling input().

--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-09 at 19:11:56 -0800,
Grant Edwards <grant.b.edwards@gmail.com> wrote:

> On 2023-03-10, 2QdxY4RzWzUUiLuE@potatochowder.com <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:

> If you run this application from the command line, you get command
> recall and editing when entering strings at the "cmd:" prompt?
>
> #!/usr/bin/python
> while True:
> try:
> line = input('cmd: ')
> except EOFError:
> print()
> break
> print('You entered "%s"' % line)

In my case, no.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 2:57 pm, Chris Angelico wrote:
> import sys; "readline" in sys.modules
>
> Is it?

Yes, it is -- but only when using the repl!
If I put that in a script, I get False.

My current theory is that it gets pre-imported when using
Python interactively because the repl itself uses it.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10/03/23 4:00 pm, 2QdxY4RzWzUUiLuE@potatochowder.com wrote:
> My ~/.pythonrc contains the following:
>
> import readline
> import rlcompleter
> readline.parse_and_bind( 'tab: complete' )

I don't have a ~/.pythonrc, so that's not what's doing it
for me.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 3/9/23 20:31, 2QdxY4RzWzUUiLuE@potatochowder.com wrote:

>
> I was with you until that part of the small wooden box. :-)
>
So was I, but we all put that off as long as we can. I retired 22 years ago.

>> We're not really an industry that has a concept of retirement.
>
> Which is why I'm still here (on this mailing list, and a handful of
> others like it).
>
More echo. And doing things, albeit at a slower pace, that I always
wanted to do.

Take care and stay well all.

Cheers, Gene Heskett.
--
"There are four boxes to be used in defense of liberty:
soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author, 1940)
If we desire respect for the law, we must first make the law respectable.
- Louis D. Brandeis
Genes Web page <http://geneslinuxbox.net:6309/>

--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
I would say, ?No, readline is not the right tool.?

cmd.Cmd is: https://docs.python.org/3/library/cmd.html. I have a couple of cmd.Cmd modules, one of which I use daily and the other weekly.

From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Grant Edwards <grant.b.edwards@gmail.com>
Date: Thursday, March 9, 2023 at 2:29 PM
To: python-list@python.org <python-list@python.org>
Subject: Baffled by readline module
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***

In an interactive command-line Python program on Linux, I want to be
able to read a line at a time from stdin, providing command line
history and editing to the user. In C, I would use GNU readline to do
that.

Python has the readline module, which appears to be a wrapper for GNU
readline. However, I've read and re-read the documenation for that
module, but I'm completely baffled. There's all sorts of stuff about
history files, but I neither need nor want a history file. Likewise
tab-completion: don't want it. All the examples not only involve
history files and tab-completion but they're somehow connected to the
interactive Python REPL, which is also completely off-base for my use
case.

Is the readline module not the right tool for an interactive Linux
command-line application that needs to provide command line recall and
editing to the user who's entering stuff on stdin from a tty?

--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iMrZQmCvzTBhFnzmb4Px34UNZrxSWMjU1Hxvg9CTc_-3tFWtjxB3-OrQUrXChOoNP8vm3em2V1XxihY0742KUNLDJnrV$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iMrZQmCvzTBhFnzmb4Px34UNZrxSWMjU1Hxvg9CTc_-3tFWtjxB3-OrQUrXChOoNP8vm3em2V1XxihY0742KUNLDJnrV$>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:

> I would say, “No, readline is not the right tool.”
>
> cmd.Cmd is: https://docs.python.org/3/library/cmd.html. I have a
> couple of cmd.Cmd modules, one of which I use daily and the other
> weekly.

I'll have to remember that one. It doesn't really fit my current use
case, but there are others where it would work nicely.

However, cmd.Cmd does not provide command recall and
editing. According to the page above, that's provided by the readline
module:

If the readline module is loaded, input will automatically
inherit bash-like history-list editing (e.g. Control-P scrolls
back to the last command, Control-N forward to the next one,
Control-F moves the cursor to the right non-destructively,
Control-B moves the cursor to the left non-destructively, etc.).

--
Grant
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On our Linux systems, I can up-arrow to go back to prior commands and use the left and right arrows to navigate a line. The functionality may be provided internally by readline. I?ve never had to dig into it because it meets my needs out of the box.

From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Grant Edwards <grant.b.edwards@gmail.com>
Date: Friday, March 10, 2023 at 9:39 AM
To: python-list@python.org <python-list@python.org>
Subject: Re: Baffled by readline module
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***

On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:

> I would say, ?No, readline is not the right tool.?
>
> cmd.Cmd is: https://urldefense.com/v3/__https://docs.python.org/3/library/cmd.html__;!!Cn_UX_p3!iH9PMR4wNfv3oBLWR_W46RY8KUzLVxsA_XRv2RJk6Td_ND59EaBvcJ58-Crx2PReX-ELMx7IEMAQ1YfpIt7xmHBGs8a1$<https://urldefense.com/v3/__https:/docs.python.org/3/library/cmd.html__;!!Cn_UX_p3!iH9PMR4wNfv3oBLWR_W46RY8KUzLVxsA_XRv2RJk6Td_ND59EaBvcJ58-Crx2PReX-ELMx7IEMAQ1YfpIt7xmHBGs8a1$> . I have a
> couple of cmd.Cmd modules, one of which I use daily and the other
> weekly.

I'll have to remember that one. It doesn't really fit my current use
case, but there are others where it would work nicely.

However, cmd.Cmd does not provide command recall and
editing. According to the page above, that's provided by the readline
module:

If the readline module is loaded, input will automatically
inherit bash-like history-list editing (e.g. Control-P scrolls
back to the last command, Control-N forward to the next one,
Control-F moves the cursor to the right non-destructively,
Control-B moves the cursor to the left non-destructively, etc.).

--
Grant
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iH9PMR4wNfv3oBLWR_W46RY8KUzLVxsA_XRv2RJk6Td_ND59EaBvcJ58-Crx2PReX-ELMx7IEMAQ1YfpIt7xmEU_EBpr$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!iH9PMR4wNfv3oBLWR_W46RY8KUzLVxsA_XRv2RJk6Td_ND59EaBvcJ58-Crx2PReX-ELMx7IEMAQ1YfpIt7xmEU_EBpr$>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:

> On our Linux systems, I can up-arrow to go back to prior commands
> and use the left and right arrows to navigate a line. The
> functionality may be provided internally by readline. I’ve never had
> to dig into it because it meets my needs out of the box.

Apparently the cmd.Cmd docs are wrong. It says:

If the readline module is loaded, input will automatically
inherit bash-like history-list editing (e.g. Control-P scrolls
back to the last command, Control-N forward to the next one,
Control-F moves the cursor to the right non-destructively,
Control-B moves the cursor to the left non-destructively, etc.).

On my Python 3.10.10 Linux system, cmd.Com itself is importing the
readline module unconditionally when I call cmdloop(). There's no 'if'
about it.

[.It's moot for my current usage, because my application allows
multiple commands per input line, and I don't see how cmd.Cmd can
support that.]

Here's my application that seem to show that cmd.Cmd.cmdloop() is
importing the readline module:

-------------------------------testit.py--------------------------------
import sys
print('readline' in sys.modules)
import cmd
print('readline' in sys.modules)

class MyShell(cmd.Cmd):
intro = 'Welcome to my shell. Type help or ? to list commands.\n'
prompt = '(what) '
file = None

def do_what(self,arg):
print('readline' in sys.modules)
def do_bye(self, arg):
print('Good bye')
return True

print('readline' in sys.modules)

if __name__ == '__main__':
print('readline' in sys.modules)
MyShell().cmdloop()
------------------------------------------------------------------------

And here's what I see when I run it:

------------------------------------------------------------------------
$ python testit.py
False
False
False
False
Welcome to my shell. Type help or ? to list commands.

(what) what
True
(what) bye
Good bye
$
------------------------------------------------------------------------


--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On Fri, Mar 10, 2023 at 06:37:56AM -0800, Grant Edwards wrote:
>On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:
>I'll have to remember that one. It doesn't really fit my current use
>case, but there are others where it would work nicely.
>
>However, cmd.Cmd does not provide command recall and
>editing. According to the page above, that's provided by the readline
>module

There is also prompt_toolkit[1] for even more fancy command?line
handling. The documentation even states it “can be a very advanced pure
Python replacement for GNU readline, but it can also be used for
building full screen applications.” (It doesn’t depend on readline or
libedit.) It’s used by IPython for its history, editing, and completion
features. If cmd with readline is overkill for your use case then this
is even more so, but I thought it worth a mention.

Simon
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 3/9/23, Greg Ewing via Python-list <python-list@python.org> wrote:
> On 10/03/23 4:00 pm, 2QdxY4RzWzUUiLuE@potatochowder.com wrote:
>> My ~/.pythonrc contains the following:
>>
>> import readline
>> import rlcompleter
>> readline.parse_and_bind( 'tab: complete' )
>
> I don't have a ~/.pythonrc, so that's not what's doing it
> for me.

If it's available, the readline and rlcompleter modules are imported
if stdin is a tty, [I]solated mode isn't enabled, and either [i]nspect
is enabled or the REPL is being run. For example:

$ python -c "import sys;print('readline' in sys.modules)"
False

$ python -ic "import sys;print('readline' in sys.modules)"
True
>>>

$ python -ic "import sys;print('readline' in sys.modules)" 0</dev/null
False
>>>

$ python -Iic "import sys;print('readline' in sys.modules)"
False
>>>

This is determined by the following function in "Modules/main.c:"

pymain_import_readline(const PyConfig *config)
{
if (config->isolated) {
return;
}
if (!config->inspect && config_run_code(config)) {
return;
}
if (!isatty(fileno(stdin))) {
return;
}

PyObject *mod = PyImport_ImportModule("readline");
if (mod == NULL) {
PyErr_Clear();
}
else {
Py_DECREF(mod);
}
mod = PyImport_ImportModule("rlcompleter");
if (mod == NULL) {
PyErr_Clear();
}
else {
Py_DECREF(mod);
}
}

The hook for input() is handled by PyOS_Readline() in
"Parser/myreadline.c". It depends on the exported function pointer
PyOS_ReadlineFunctionPointer. When imported, the readline extension
module in "Modules/readline.c" sets PyOS_ReadlineFunctionPointer to
its call_readline() function.

---

On Windows, Python is not distributed with a readline module. Instead,
Python relies on the console host's builtin support for command-line
editing, history, and aliases.

The Windows console API function ReadConsoleW() has a parameter that
supports implementing custom command-line completion. This is how the
CMD shell implements tab completion for file paths. However, no one
has developed a version of rlcompleter for the Windows console.
Instead, there's a third-party "pyreadline3" package (note the "3";
don't install "pyreadline" by mistake) that implements readline for
the Windows console, which supports rlcompleter.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10Mar2023 09:12, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:
>> On our Linux systems, I can up-arrow to go back to prior commands
>> and use the left and right arrows to navigate a line. The
>> functionality may be provided internally by readline. I’ve never had
>> to dig into it because it meets my needs out of the box.
>
>Apparently the cmd.Cmd docs are wrong. It says:
>
> If the readline module is loaded, input will automatically
> inherit bash-like history-list editing (e.g. Control-P scrolls
> back to the last command, Control-N forward to the next one,
> Control-F moves the cursor to the right non-destructively,
> Control-B moves the cursor to the left non-destructively, etc.).
>
>On my Python 3.10.10 Linux system, cmd.Com itself is importing the
>readline module unconditionally when I call cmdloop(). There's no 'if'
>about it.

I was wondering about that myself, whether this is an accident of
phrasing. It doesn't say "is imported", so maybe the author was thinking
"if readline's part of the install" here.

Anyway, I've got a try/import-readline/except-importerror/pass in my
cmd.Cmd wrapper, because I read this the way you read it.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 2023-03-10, Cameron Simpson <cs@cskk.id.au> wrote:
> On 10Mar2023 09:12, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>>On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:
>>> On our Linux systems, I can up-arrow to go back to prior commands
>>> and use the left and right arrows to navigate a line. The
>>> functionality may be provided internally by readline. I’ve never had
>>> to dig into it because it meets my needs out of the box.
>>
>>Apparently the cmd.Cmd docs are wrong. It says:
>>
>> If the readline module is loaded, input will automatically
>> inherit bash-like history-list editing (e.g. Control-P scrolls
>> back to the last command, Control-N forward to the next one,
>> Control-F moves the cursor to the right non-destructively,
>> Control-B moves the cursor to the left non-destructively, etc.).
>>
>>On my Python 3.10.10 Linux system, cmd.Com itself is importing the
>>readline module unconditionally when I call cmdloop(). There's no 'if'
>>about it.
>
> I was wondering about that myself, whether this is an accident of
> phrasing. It doesn't say "is imported", so maybe the author was thinking
> "if readline's part of the install" here.

Ah, that never ocurred to me. I understood "loaded" to mean "imported"
without giving it a second thought. It probably does mean supported.



--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
This is the implementation of cmd.Cmd (Python 3.9). As you can see in cmdloop(), the import is already wrapped, and the readline feature can be turned off explicitly by passing None to the completekey in the constructor.

def __init__(self, completekey='tab', stdin=None, stdout=None):
"""Instantiate a line-oriented interpreter framework.

The optional argument 'completekey' is the readline name of a
completion key; it defaults to the Tab key. If completekey is
not None and the readline module is available, command completion
is done automatically. The optional arguments stdin and stdout
specify alternate input and output file objects; if not specified,
sys.stdin and sys.stdout are used.

"""
if stdin is not None:
self.stdin = stdin
else:
self.stdin = sys.stdin
if stdout is not None:
self.stdout = stdout
else:
self.stdout = sys.stdout
self.cmdqueue = []
self.completekey = completekey

def cmdloop(self, intro=None):
"""Repeatedly issue a prompt, accept input, parse an initial prefix
off the received input, and dispatch to action methods, passing them
the remainder of the line as argument.

"""

self.preloop()
if self.use_rawinput and self.completekey:
try:
import readline
self.old_completer = readline.get_completer()
readline.set_completer(self.complete)
readline.parse_and_bind(self.completekey+": complete")
except ImportError:
pass

From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Cameron Simpson <cs@cskk.id.au>
Date: Friday, March 10, 2023 at 5:15 PM
To: python-list@python.org <python-list@python.org>
Subject: Re: Baffled by readline module
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***

On 10Mar2023 09:12, Grant Edwards <grant.b.edwards@gmail.com> wrote:
>On 2023-03-10, Weatherby,Gerard <gweatherby@uchc.edu> wrote:
>> On our Linux systems, I can up-arrow to go back to prior commands
>> and use the left and right arrows to navigate a line. The
>> functionality may be provided internally by readline. I?ve never had
>> to dig into it because it meets my needs out of the box.
>
>Apparently the cmd.Cmd docs are wrong. It says:
>
> If the readline module is loaded, input will automatically
> inherit bash-like history-list editing (e.g. Control-P scrolls
> back to the last command, Control-N forward to the next one,
> Control-F moves the cursor to the right non-destructively,
> Control-B moves the cursor to the left non-destructively, etc.).
>
>On my Python 3.10.10 Linux system, cmd.Com itself is importing the
>readline module unconditionally when I call cmdloop(). There's no 'if'
>about it.

I was wondering about that myself, whether this is an accident of
phrasing. It doesn't say "is imported", so maybe the author was thinking
"if readline's part of the install" here.

Anyway, I've got a try/import-readline/except-importerror/pass in my
cmd.Cmd wrapper, because I read this the way you read it.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jjJFSxKkzPwZf_NLr44bZNCgMKRu0CPwvbh-jItjkqH_B2mJzTCW4ijlNHg8ysJpyMcCbaaa0Prf5SI$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jjJFSxKkzPwZf_NLr44bZNCgMKRu0CPwvbh-jItjkqH_B2mJzTCW4ijlNHg8ysJpyMcCbaaa0Prf5SI$>
--
https://mail.python.org/mailman/listinfo/python-list
Re: Baffled by readline module [ In reply to ]
On 10Mar2023 23:11, Weatherby,Gerard <gweatherby@uchc.edu> wrote:
>This is the implementation of cmd.Cmd (Python 3.9). As you can see in cmdloop(), the import is already wrapped, and the readline feature can be turned off explicitly by passing None to the completekey in the constructor.

This isn't strictly true, as I read it.

This says that if you supply a `completekey`, _then_ `cmdloop` will try
to import `readline` and set up working completion for that key.

It _doesn't_ say that readline is or is not automatically active for its
other features (command line editing, history etc).

Having a gander further down the `cmdloop` function we see:

while not stop:
if self.cmdqueue:
line = self.cmdqueue.pop(0)
else:
if self.use_rawinput:
try:
line = input(self.prompt)
except EOFError:
line = 'EOF'

and on a Python 3.10 here we see:

>>> help(input)
Help on built-in function input in module builtins:

input(prompt=None, /)
Read a string from standard input. The trailing newline is stripped.

The prompt string, if given, is printed to standard output without a
trailing newline before reading input.

If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.

which says to me that readline is used if available, regardless of
whether it is already imported.

Cheers,
Cameron Simpson <cs@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list