Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread Thomas Passin

On 3/10/2023 11:15 PM, aapost wrote:

On 3/10/23 22:16, Thomas Passin wrote:

[...]
The additional note in the above is, when taking the def route above, 
the thing you would have to consider is what scope is the dictionary pids?


Do you need to submit it to the lambda and subsequently the function 
such as

lambda pids=pids: (
     update_pids("messages", pids),
     update_pids("syslog", pids),

So that update_pids can access it? Or in your design do you have a 
separate management of it that def update_pids already has access to? 
(either is valid depending on design intent).


It's easy enough to try out.  I'm not going to simulate the dictionary, 
because it's basically just another argument, and I assume that your 
example code uses it because it needs to be in that form.  For the scope 
question, see below after the basic example.


>>> def printme(x): print(x)  # Let's not quibble about inline defs!

>>> printme('xxx')
xxx
>>> cmd = lambda x: (
... printme('this'),
... printme('is'),
... printme('a test')
... )

(Yes, I know it's not recommended to assign a lambda to a variable name, 
but I'm doing it here just to demonstrate that the lambda works as desired).


>>> cmd(2)
this
is
a test
(None, None, None)

So it executes the intended steps and returns a tuple of three None 
values, as expected.  When used as the target of the "command" arg in 
the Tk control constructor, I presume the tuple would be ignored just as 
a return of None would be.  But that would need to be tested.


If returning a tuple instead of None were to cause a problem, you could 
do this:


cmd = lambda x: (
printme('this'),
printme('is'),
printme('a test')
   ) and None

>>> cmd(2)
this
is
a test

But now you are introducing a construct whose purpose is not totally 
obvious, does not cause any intended effect, and in fact is only 
required by the nature of the code receiving the callback, which you 
cannot know by reading this code.  So if this construct turns out to be 
needed, we're forced to take a step away from having the code be as 
direct and understandable as possible.  It's still better in that way 
than the earlier illustrations (which BTW would also have required the 
"and None" construct).


To test out the scope question:

>>> def printme(x): print(y)  # Print some other variable, not "x"
>>> y = 'I am y'  # Will "y" get passed through into the lambda?

>>> cmd = lambda x: (
...printme('this'),
...printme('is'),
...printme('a test')
... ) and None

>>> cmd(2)
I am y
I am y
I am y

But maybe the original value of "y" gets baked in at compile time. Let's 
see:


>>> y = 'I am a post-compile assignment'
>>> cmd(2)
I am a post-compile assignment
I am a post-compile assignment
I am a post-compile assignment

Good, the current value of "y" gets used.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread aapost

On 3/10/23 22:16, Thomas Passin wrote:

On 3/10/2023 7:07 PM, aapost wrote:
which does start to break down readability due to line length, as 
there isn't really an indention rule set for something uncommonly used.


but some renaming makes the pattern clearer

pids.update({"messages" :subprocess.Popen(["cmd1"])}) if not 
pids["messages"] else None,
pids.update({"syslog" :subprocess.Popen(["cmd2"])}) if not 
pids["syslog"] else None,
pids.update({"kern" :subprocess.Popen(["cmd3"])}) if not pids["kern"] 
else None,
pids.update({"user" :subprocess.Popen(["cmd4"])}) if not pids["user"] 
else None,


I'd make the pattern in this example even more understandable and less 
error-prone:


def update_pids(target):
     cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
     pids.update({target: subprocess.Popen(cmd)}) if not \
     pids[target] else None

lambda x: ( # The Tk callback includes an event arg, doesn't it?
     update_pids('messages'),
     update_pids('syslog'),
     # etc
   )



So yeah, that's along the same lines. cmd could be in a function, or 
just outside the lambdas. Could also do from subprocess import Popen to 
shorten that, etc.


The .trace( on the tkinter Vars use events, so you have to do something 
like

lambda _a, _b, _c: stuff

But not in the above case. My focus these last couple week hasn't used 
any of those so the specifics aren't as fresh (still heading back in 
that direction), when required python will definitely let you know, lol.


The additional note in the above is, when taking the def route above, 
the thing you would have to consider is what scope is the dictionary pids?


Do you need to submit it to the lambda and subsequently the function 
such as

lambda pids=pids: (
update_pids("messages", pids),
update_pids("syslog", pids),

So that update_pids can access it? Or in your design do you have a 
separate management of it that def update_pids already has access to? 
(either is valid depending on design intent).


In the direction I am going, in trying to build some compound widgets, 
and I need to grab stuff from one widget and send it to another within 
the same widget group, so in cases where it goes to an external 
function, it has to be sent as an arg through the lambda 
whatever=whatever: ( function(whatever), )



--
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread Thomas Passin

On 3/10/2023 10:37 PM, 2qdxy4rzwzuui...@potatochowder.com wrote:

On 2023-03-10 at 22:16:05 -0500,
Thomas Passin  wrote:


I'd make the pattern in this example even more understandable and less
error-prone:

def update_pids(target):
 cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
 pids.update({target: subprocess.Popen(cmd)}) if not \
 pids[target] else None


I might be missing something, but how is that more understandable and
less error prone than any of the following:


The main point is that there can be an easy-to-read and 
easy-to-understand expression to use in the lambda.  I don't care about 
the exact details here.  The command wasn't even mine.  But you only 
have to scan it and grasp it once, in the def:, and then only until you 
get it working.  In the lambda, my suggestions makes it much easier to 
understand what the lambda is expected to do - and it will still be 
clear in three months when the code gets revisited.




 if not pids[target]:
 cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
 pids.update({target: subprocess.Popen(cmd)})

or:

 cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
 pids[target] or pids.update({target: subprocess.Popen(cmd)})

or:

 if pids[target]:
 pass
 else:
 cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
 pids.update({target: subprocess.Popen(cmd)})

Picking a nit, that's not a good place to continue that line with the
backslash, either.  
I only continued the line for the purposes of the post because it would 
have gotten line wrapped otherwise. If it were my code in a real module 
I would probably have treated it differently.


> IMO, "not pids[target]" should be atomic.

Again, it wasn't my code.  I don't even know if the code fragments would 
actually work - they were presented as illustrative examples by the OP. 
And anyway, these nits obscure the point of my post. In a nutshell, it 
is to use good naming and encapsulation to make your code as close to 
self-documenting and as error-free as is reasonably possible, whenever 
you can. Good function names are only one step towards this goal.


Lambdas often work against this goal, so it's worthwhile spending some 
effort to see how to counteract this tendency.


And it's a goal.  You can never meet it 100%.  That's OK.  There will 
always be a matter of taste involved.  That's OK too.  It's still a 
worthwhile goal.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Python installation not full and python not working 3.11.0

2023-03-10 Thread Thomas Passin

On 3/10/2023 9:51 PM, Thomas Passin wrote:

On 3/10/2023 6:27 PM, Jan Vasko wrote:

Please note that you can't attach images in these posts, at least not so 
we can read them.  Instead, copy the messages from the console and paste 
them into your post.


I suggest that you check to make sure that your system hasn't been 
damaged or corrupted - just to make sure.  You can check it and have 
Windows restore any of the OS files if they have been damaged.  If 
everything is OK, then that would remove one potential issue, so it's 
worth doing.  It may take some time, but it's worth doing.


Here's what to do. First, open a console with administrative privileges 
- the easiest way is to press  and choose "Command Prompt 
(Admin).  In the console, run


dism /Online /Cleanup-Image /ScanHealth

(see 
https://www.dell.com/support/kbdoc/en-us/000122035/how-to-use-the-deployment-image-servicing-and-management-tool-dism-to-repair-the-windows-system-store)


If repairable problems are found, then run:

dism /Online /Cleanup-Image /RestoreHealth

Finally follow up by running

sfc /scannow

sfc can also repair some errors, and some people run it first, but I 
have read that it's more useful to run Dism first.


If any errors were found and corrected, reboot and try to uninstall 
Python3.11, then re-install it.


If no errors were found, report that back here and we'll try to go on 
from there.


If it were me, the next thing I'd try is to install Python 3.10.x.  I'd 
get a 64-bit installer from python.org. Yes, I know you want to install 
3.11, but this way will give you a clean, fresh installer to try.  If 
the installation succeeds, it would be a good data point and also give 
you a (somewhat) updated version of Python on your system.


I would like to ask you for help. I have been using Python 3.8 for 
almost 2 years and I decided to update to 3.11. Initially everything 
was correct. But at some point Windows shows me that Python is being 
reinstalled (I don't have a message print screen ..), but from that 
time I cannot run Python at all on my PC.


So I tried to reinstall it several times with no success. All the time 
I receive this "The system cannot find the file 
C:\Users...\AppData\Local\Programs\Python\Python311\python.exe."

But files are there:
[cid:image001.png@01D953B0.4E12E170]
Even when I try to run "python.exe" directly I receive this error:
[cid:image002.png@01D953B0.4E12E170]

System Variables are right (added it to both PATH):
1) User Variables:
[cid:image003.png@01D953B0.4E12E170]

2) System Variables
[cid:image004.png@01D953B0.4E12E170]

Strange thing is that after RE-Installing Python the "pip.exe" is 
missing in subfolder "Python/Scripts/" (it is simply empty - not 
installed but I mark pip to be installed):

[cid:image005.png@01D953B0.4E12E170]

I tried also Repair - no success.

Details:
System: Windows 10 (21H2)
Python: 3.11.0 (full 64bit installer from python.org)

   *   Downloaded from: Python Release Python 3.11.0 | 
Python.org


cmd:
[cid:image006.png@01D953B0.4E12E170]

This is resulting that I cannot use interpreter in VS Code and 
continue development. Any one Any Idea? Thank you


S pozdravem

Jan Vaško





--
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread 2QdxY4RzWzUUiLuE
On 2023-03-10 at 22:16:05 -0500,
Thomas Passin  wrote:

> I'd make the pattern in this example even more understandable and less
> error-prone:
> 
> def update_pids(target):
> cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
> pids.update({target: subprocess.Popen(cmd)}) if not \
> pids[target] else None

I might be missing something, but how is that more understandable and
less error prone than any of the following:

if not pids[target]:
cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
pids.update({target: subprocess.Popen(cmd)})

or:

cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
pids[target] or pids.update({target: subprocess.Popen(cmd)})

or:

if pids[target]:
pass
else:
cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
pids.update({target: subprocess.Popen(cmd)})

Picking a nit, that's not a good place to continue that line with the
backslash, either.  IMO, "not pids[target]" should be atomic.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread Thomas Passin

On 3/10/2023 7:07 PM, aapost wrote:
which does start to break down readability due to line length, as there 
isn't really an indention rule set for something uncommonly used.


but some renaming makes the pattern clearer

pids.update({"messages" :subprocess.Popen(["cmd1"])}) if not 
pids["messages"] else None,
pids.update({"syslog" :subprocess.Popen(["cmd2"])}) if not 
pids["syslog"] else None,
pids.update({"kern" :subprocess.Popen(["cmd3"])}) if not pids["kern"] 
else None,
pids.update({"user" :subprocess.Popen(["cmd4"])}) if not pids["user"] 
else None,


I'd make the pattern in this example even more understandable and less 
error-prone:


def update_pids(target):
cmd = ["tail", "-n", "1", "-f", f"/var/log/{target}"]
pids.update({target: subprocess.Popen(cmd)}) if not \
pids[target] else None

lambda x: ( # The Tk callback includes an event arg, doesn't it?
update_pids('messages'),
update_pids('syslog'),
# etc
  )

--
https://mail.python.org/mailman/listinfo/python-list


Re: Python installation not full and python not working 3.11.0

2023-03-10 Thread MRAB

On 2023-03-10 23:27, Jan Vasko wrote:

Hello all,


I would like to ask you for help. I have been using Python 3.8 for almost 2 
years and I decided to update to 3.11. Initially everything was correct. But at 
some point Windows shows me that Python is being reinstalled (I don't have a 
message print screen ..), but from that time I cannot run Python at all on my 
PC.

So I tried to reinstall it several times with no success. All the time I receive this 
"The system cannot find the file 
C:\Users...\AppData\Local\Programs\Python\Python311\python.exe."
But files are there:
[cid:image001.png@01D953B0.4E12E170]
Even when I try to run "python.exe" directly I receive this error:
[cid:image002.png@01D953B0.4E12E170]

System Variables are right (added it to both PATH):
1) User Variables:
[cid:image003.png@01D953B0.4E12E170]

2) System Variables
[cid:image004.png@01D953B0.4E12E170]

Strange thing is that after RE-Installing Python the "pip.exe" is missing in subfolder 
"Python/Scripts/" (it is simply empty - not installed but I mark pip to be installed):
[cid:image005.png@01D953B0.4E12E170]

I tried also Repair - no success.

Details:
System: Windows 10 (21H2)
Python: 3.11.0 (full 64bit installer from python.org)

   *   Downloaded from: Python Release Python 3.11.0 | 
Python.org

cmd:
[cid:image006.png@01D953B0.4E12E170]

This is resulting that I cannot use interpreter in VS Code and continue 
development. Any one Any Idea? Thank you

This list is text-only; images are automatically stripped. Please copy 
and paste any relevant text that they might contain.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Python installation not full and python not working 3.11.0

2023-03-10 Thread Thomas Passin

On 3/10/2023 6:27 PM, Jan Vasko wrote:

Please note that you can't attach images in these posts, at least not so 
we can read them.  Instead, copy the messages from the console and paste 
them into your post.


I suggest that you check to make sure that your system hasn't been 
damaged or corrupted - just to make sure.  You can check it and have 
Windows restore any of the OS files if they have been damaged.  If 
everything is OK, then that would remove one potential issue, so it's 
worth doing.  It may take some time, but it's worth doing.


Here's what to do. First, open a console with administrative privileges 
- the easiest way is to press  and choose "Command Prompt 
(Admin).  In the console, run


dism /Online /Cleanup-Image /ScanHealth

(see 
https://www.dell.com/support/kbdoc/en-us/000122035/how-to-use-the-deployment-image-servicing-and-management-tool-dism-to-repair-the-windows-system-store)


If repairable problems are found, then run:

dism /Online /Cleanup-Image /RestoreHealth

Finally follow up by running

sfc /scannow

sfc can also repair some errors, and some people run it first, but I 
have read that it's more useful to run Dism first.


If any errors were found and corrected, reboot and try to uninstall 
Python3.11, then re-install it.


If no errors were found, report that back here and we'll try to go on 
from there.



I would like to ask you for help. I have been using Python 3.8 for almost 2 
years and I decided to update to 3.11. Initially everything was correct. But at 
some point Windows shows me that Python is being reinstalled (I don't have a 
message print screen ..), but from that time I cannot run Python at all on my 
PC.

So I tried to reinstall it several times with no success. All the time I receive this 
"The system cannot find the file 
C:\Users...\AppData\Local\Programs\Python\Python311\python.exe."
But files are there:
[cid:image001.png@01D953B0.4E12E170]
Even when I try to run "python.exe" directly I receive this error:
[cid:image002.png@01D953B0.4E12E170]

System Variables are right (added it to both PATH):
1) User Variables:
[cid:image003.png@01D953B0.4E12E170]

2) System Variables
[cid:image004.png@01D953B0.4E12E170]

Strange thing is that after RE-Installing Python the "pip.exe" is missing in subfolder 
"Python/Scripts/" (it is simply empty - not installed but I mark pip to be installed):
[cid:image005.png@01D953B0.4E12E170]

I tried also Repair - no success.

Details:
System: Windows 10 (21H2)
Python: 3.11.0 (full 64bit installer from python.org)

   *   Downloaded from: Python Release Python 3.11.0 | 
Python.org

cmd:
[cid:image006.png@01D953B0.4E12E170]

This is resulting that I cannot use interpreter in VS Code and continue 
development. Any one Any Idea? Thank you

S pozdravem

Jan Vaško



--
https://mail.python.org/mailman/listinfo/python-list


RE: Python installation not full and python not working 3.11.0

2023-03-10 Thread Jan Vasko
Hello all,


I would like to ask you for help. I have been using Python 3.8 for almost 2 
years and I decided to update to 3.11. Initially everything was correct. But at 
some point Windows shows me that Python is being reinstalled (I don't have a 
message print screen ..), but from that time I cannot run Python at all on my 
PC.

So I tried to reinstall it several times with no success. All the time I 
receive this "The system cannot find the file 
C:\Users...\AppData\Local\Programs\Python\Python311\python.exe."
But files are there:
[cid:image001.png@01D953B0.4E12E170]
Even when I try to run "python.exe" directly I receive this error:
[cid:image002.png@01D953B0.4E12E170]

System Variables are right (added it to both PATH):
1) User Variables:
[cid:image003.png@01D953B0.4E12E170]

2) System Variables
[cid:image004.png@01D953B0.4E12E170]

Strange thing is that after RE-Installing Python the "pip.exe" is missing in 
subfolder "Python/Scripts/" (it is simply empty - not installed but I mark pip 
to be installed):
[cid:image005.png@01D953B0.4E12E170]

I tried also Repair - no success.

Details:
System: Windows 10 (21H2)
Python: 3.11.0 (full 64bit installer from python.org)

  *   Downloaded from: Python Release Python 3.11.0 | 
Python.org

cmd:
[cid:image006.png@01D953B0.4E12E170]

This is resulting that I cannot use interpreter in VS Code and continue 
development. Any one Any Idea? Thank you

S pozdravem

Jan Vaško

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread aapost

On 3/9/23 15:25, Thomas Passin wrote:

 >>> # this is a code snippet from a Tkinter gui app
 >>> # in this case lambda is quite convenient
 >>> self.btn_cancel = Button(self.progress_container, text='Cancel',
 >>> command=lambda: subprocess.call('taskkill /f /im uberzip.exe',
 >>> shell=True))



def kill_uberzip():
     """Kill an external running program named uberzip.exe."""
     subprocess.call('taskkill /f /im uberzip.exe', shell=True))

self.btn_cancel = Button(self.progress_container, text='Cancel',
  command = kill_uberzip())

This way, it's easy to understand what btn_cancel() will do each time 
you scan that line of code.  Using the lambda makes you reparse the line 
and spend mental effort each time you scan it.  And this way, you know 
directly that the button is going to cause a side effect outside your 
program, which you have to infer (an indirect mental operation) when you 
scan the lambda.


For this particular example, it might turn out that there could be more 
than one instance of uberzip.exe running at the same time.  Which one 
should be killed, and how do you kill the right one?  With the function, 
you can get those details under control, but I hate to think what might 
happen to the lambda expression.


Yes, of course, there can be times when the lambda expression is 
somewhat easy to understand and the side effects are harmless.  In that 
case, it may be easy enough to grasp quickly that the anonymous function 
would not benefit from having a name.  So OK, it's not a hard-and-fast 
rule.


The not knowing which uberzip to kill is a design choice, the bad design 
of the the example is not really the fault of the lambda.


And in general with naming anything, much has to do with context. 
Buttons perform actions, it should be implicitly understood at the 
button level and in context of where it is placed what it is a button is 
for. A button without a command has no use, so it is understood it needs 
to do something, with good design it would be better to know what the 
buttons purpose is, rather than having to then parse an additional 
function to figure it out.



Case in point, to solve the subprocess problem, (ignoring the "whys" and 
the lack of usefulness of this example, just grok the pattern, maybe you 
are designing a game of whack-a-mole and are watching 4 things and need 
to do something when you see a change from 1 of them)



import tkinter as tk
import subprocess

main = tk.Tk()
main.pids = {
"messages": None,
"syslog": None,
"kern": None,
"user": None,
}

tk.Button(
master=main,
text="Start tailing logs",
command=lambda: (
		main.pids.update({"messages" :subprocess.Popen(["tail", "-n", "1", 
"-f", "/var/log/messages"])}),
		main.pids.update({"syslog" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/syslog"])}),
		main.pids.update({"kern" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/kern.log"])}),
		main.pids.update({"user" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/user.log"])}),

),
).pack()

tk.Button(
master=main,
text="Kill messages tail",
command=lambda: (
main.pids["messages"].kill() if main.pids["messages"] else None,
),
).pack()

tk.Button(
master=main,
text="Kill syslog tail",
command=lambda: (
main.pids["syslog"].kill() if main.pids["syslog"] else None,
),
).pack()

tk.Button(
master=main,
text="Kill kern tail",
command=lambda: (
main.pids["kern"].kill() if main.pids["kern"] else None,
),
).pack()

tk.Button(
master=main,
text="Kill user tail",
command=lambda: (
main.pids["user"].kill() if main.pids["user"] else None,
),
).pack()

tk.Button(
master=main,
text="Kill all tails",
command=lambda: (
main.pids["messages"].kill() if main.pids["messages"] else None,
main.pids["syslog"].kill() if main.pids["syslog"] else None,
main.pids["kern"].kill() if main.pids["kern"] else None,
main.pids["user"].kill() if main.pids["user"] else None,
),
).pack()

main.mainloop()


--
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread aapost

On 3/10/23 18:46, aapost wrote:

     main.pids.update({"messages" :subprocess.Popen(["tail", "-n", 
"1", "-f", "/var/log/messages"])}),
     main.pids.update({"syslog" :subprocess.Popen(["tail", "-n", 
"1", "-f", "/var/log/syslog"])}),
     main.pids.update({"kern" :subprocess.Popen(["tail", "-n", "1", 
"-f", "/var/log/kern.log"])}),
     main.pids.update({"user" :subprocess.Popen(["tail", "-n", "1", 
"-f", "/var/log/user.log"])}),

 ),


To pre-emptively address the bug there it would need to be:

main.pids.update({"messages" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/messages"])}) if not main.pids["messages"] else None,
main.pids.update({"syslog" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/syslog"])}) if not main.pids["syslog"] else None,
main.pids.update({"kern" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/kern.log"])}) if not main.pids["kern"] else None,
main.pids.update({"user" :subprocess.Popen(["tail", "-n", "1", "-f", 
"/var/log/user.log"])}) if not main.pids["user"] else None,


which does start to break down readability due to line length, as there 
isn't really an indention rule set for something uncommonly used.


but some renaming makes the pattern clearer

pids.update({"messages" :subprocess.Popen(["cmd1"])}) if not 
pids["messages"] else None,
pids.update({"syslog" :subprocess.Popen(["cmd2"])}) if not 
pids["syslog"] else None,
pids.update({"kern" :subprocess.Popen(["cmd3"])}) if not pids["kern"] 
else None,
pids.update({"user" :subprocess.Popen(["cmd4"])}) if not pids["user"] 
else None,


and adding a comment to say something like
# starting a series of processes via lambda tuple sequence if process 
not running

#pattern: p.update({"name":sp.Popen(cmd)}) if not p["name"] else None,

--
https://mail.python.org/mailman/listinfo/python-list


Re: Baffled by readline module

2023-03-10 Thread Cameron Simpson

On 10Mar2023 23:11, Weatherby,Gerard  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 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Baffled by readline module

2023-03-10 Thread Weatherby,Gerard
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  on 
behalf of Cameron Simpson 
Date: Friday, March 10, 2023 at 5:15 PM
To: 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  wrote:
>On 2023-03-10, Weatherby,Gerard  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 
--
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


Problem with wxPython form

2023-03-10 Thread Chris
Hi everyone. I'm new to Python and wxPython. I've got a form I use to 
calculate the Sq In of a leather project.


I'm using python 3.9.13 and wxPython 4.20

I'm having the following issues:
1) When I come into the form, no grid cell has the focus set - I start 
typing and nothing happens. I have to click the cell.
If I hit Tab or Enter, the OnKeyDown fires, but does not move to the 
appropriate cell - it does nothing but run the update and move off of 
the current cell.

The action I'm trying to make is this
ENTER KEY: Always go down 1 row and to col 0
TAB, if Col 0 Move to Col 1 on same row, if Col 1 go to Row +1, Col 0
I also need to have what3ever cell it is supposed to land on to get the 
focus so I can just type.

Currently I have to click in each cell I want/need to add.
There could be up to 20 pieces of leather with differing sizes, so in 
order to accurately calculate the Sq In, I need to get all the 
measurements in.
The form, one of several tabs, comes up and does everything else I've 
coded for great. Just no navigation.

Can anyone assist? Here is the module with the form

/***/

'''

Module Name : alwsqin.py

Author      : Chris Anderson

Create Date : 03/10/2023

Description : This module contains the Sq In/MM/CM of leather used

This file is Copyright Anderson Leather Works (c) 2023

'''

//

/#/

/# File Last Update and Person/

/#/

/#***/

/# Imports/

/import/wx

/#from Imports/

/from/alwlogic /import/leather_sqin

/class/LeatherSqInPanel(wx.Panel):

'''

Name        : LeatherSqInPanel

Author      : Chris Anderson

Create Date : 02/23/2023

Description : Panel for the 'Leather Sq In Calculator

              in Leatherworking Cost Estimator app

'''

dbTableName /=/'None'

/def/__init__(self, parent):

    wx.Panel.__init__(/self/, parent)

/self/.ls /=/leather_sqin

/self/.grid /=/wx.grid.Grid(/self/, size/=/(600, 515))

/self/.grid.CreateGrid(30, 6)

/# Set column labels/

/self/.grid.SetColLabelValue(0, "Length")

/self/.grid.SetColLabelValue(1, "Width")

/self/.grid.SetColLabelValue(2, "Total")

/self/.grid.SetColLabelValue(3, "Grand Total")

/self/.grid.SetColLabelValue(4, "Type")

/self/.grid.SetColLabelValue(5, "Select Calc Method")

/for/col /in/range(/self/.grid.GetNumberCols()):

/self/.grid.AutoSizeColumn(col)

/self/.grid.EnableEditing(True)

/# Set dropdown choices for column 5, row 0/

    types /=/["Sq In", "Sq Cm", "Sq Mm"]

/self/.type_dropdown /=/wx.ComboBox(/self/.grid, choices/=/types, 
style/=/wx.CB_DROPDOWN/|/wx.CB_READONLY)


/self/.type_editor /=/wx.grid.GridCellChoiceEditor(choices/=/types)

/self/.grid.SetCellEditor(0, 5, /self/.type_editor)

/self/.grid.SetCellRenderer(0, 5, wx.grid.GridCellAutoWrapStringRenderer())

/# Set initial value for Type column/

/self/.grid.SetCellValue(0, 5, types[0])

/# Make Total and Grand Total cells read-only/

/for/i /in/range(/self/.grid.GetNumberRows()):

/self/.grid.SetReadOnly(i, 2)

/self/.grid.SetReadOnly(i, 3)

/# Set Type column values/

/self/.grid.SetCellValue(0, 4, "Sq In")

/self/.grid.SetCellValue(1, 4, "Sq Cm")

/self/.grid.SetCellValue(2, 4, "Sq Mm")

/# Populate grid with data from LeatherSqIn object/

/for/i, row /in/enumerate(/self/.ls.get_data()):

/for/j, val /in/enumerate(row):

/self/.grid.SetCellValue(i, j, str(val))

/if/j /==/0: /# Check if first column/

/self/.grid.SetCellValue(i, j/+/1, "Sq In") /# Set default value for 
column 2/


/if/i /==/0/and/j /==/5:

/self/.grid.SetCellEditor(i, j, 
wx.grid.GridCellChoiceEditor(choices/=/["Sq In", "Sq Cm", "Sq Mm"]))


/else/:

/self/.grid.SetCellValue(i, j, str(val))

/# Calculate totals and grand total/

/for/i, row /in/enumerate(/self/.ls.get_data()):

/self/.ls.calculate_total(row)

    grandTotal /=/0.0

    total /=/0.0

/self/.ls.calculate_grand_total(grandTotal, total)

/# Bind events/

/self/.grid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, /self/.OnCellChange)

/self/.grid.Bind(wx.EVT_KEY_DOWN, /self/.OnKeyDown) /# Bind the key down 
event/


/# Add grid and button sizers to top sizer/

    sizer /=/wx.BoxSizer(wx.VERTICAL)

    sizer.Add(/self/.grid, 1, wx.ALL)

/self/.SetSizer(sizer)

/# Set grid line width for last column to 0/

/self/.grid.SetCellHighlightPenWidth(0)

/# Set grid cursor and focus/

/# Select cell R0C0 and set focus/

    wx.CallAfter(/self/.grid.SetGridCursor, 0, 0)

    wx.CallAfter(/self/.grid.MakeCellVisible, 0, 0)

    wx.CallAfter(/self/.grid.SetFocus)

/def//OnCellChange/(self, event):

print("OnCellChange called")

    row, col /=/event.GetRow(), event.GetCol()

    value /=//self/.grid.GetCellValue(row, col)

/# update total for the row/

/if/col /==/0/or/col /==/1:

/try/:

/self/.grid.SetCellValue(row, 2, 
/f/'{/self/.ls.calc_sqin(float(/self/.grid.GetCellValue(row, 0)), 
float(/self/.grid.GetCellValue(row, 1)))}')



Re: Baffled by readline module

2023-03-10 Thread Grant Edwards
On 2023-03-10, Cameron Simpson  wrote:
> On 10Mar2023 09:12, Grant Edwards  wrote:
>>On 2023-03-10, Weatherby,Gerard  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

2023-03-10 Thread Cameron Simpson

On 10Mar2023 09:12, Grant Edwards  wrote:

On 2023-03-10, Weatherby,Gerard  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 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Lambda returning tuple question, multi-expression

2023-03-10 Thread Cameron Simpson

On 09Mar2023 17:55, aapost  wrote:

On 3/9/23 16:37, Cameron Simpson wrote:
Just a note that some code formatters use a trailing comma on the last 
element to make the commas fold points. Both yapf (my preference) and 
black let you write a line like (and, indeed, flatten if short 
enough):


    ( a, b, c )

but if you write:

    ( a, b, c, )

they'll fold the lines like:

    ( a,
  b,
  c,
    )
Cameron Simpson 



Thanks for the info, good to know, I actually do like the idea of 
trailing commas for tuples (helps prevent things like the difference 
between ("abc") and ("abc",) and makes swapping things around nicer.


Just keep in mind that if you restructure code with copy/paste it can be 
a small issue (not really tied to the trailing comma but commas in 
general. More than once I've been bitten by doing roughly this:


f( a,
   b=x+y,
)

shuffled to:

b=x+y,
f( a,
   b=b,
)

Whoops! It shows up almost immediately, but the first time it took me a 
while to see that stray comma.


I've just been using a lot of json lately and it has been 
subconsciously training me different, lol.


Yes, it hates the trailing comma. So annoying.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Baffled by readline module

2023-03-10 Thread Eryk Sun
On 3/9/23, Greg Ewing via Python-list  wrote:
> On 10/03/23 4:00 pm, 2qdxy4rzwzuui...@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>>

$ 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

2023-03-10 Thread Simon Ward

On Fri, Mar 10, 2023 at 06:37:56AM -0800, Grant Edwards wrote:

On 2023-03-10, Weatherby,Gerard  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

2023-03-10 Thread Grant Edwards
On 2023-03-10, Weatherby,Gerard  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

2023-03-10 Thread Weatherby,Gerard
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  on 
behalf of Grant Edwards 
Date: Friday, March 10, 2023 at 9:39 AM
To: 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  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$
>  . 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://mail.python.org/mailman/listinfo/python-list


Re: Baffled by readline module

2023-03-10 Thread Grant Edwards
On 2023-03-10, Weatherby,Gerard  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

2023-03-10 Thread Weatherby,Gerard
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  on 
behalf of Grant Edwards 
Date: Thursday, March 9, 2023 at 2:29 PM
To: 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://mail.python.org/mailman/listinfo/python-list


Re: Baffled by readline module

2023-03-10 Thread gene heskett

On 3/9/23 20:31, 2qdxy4rzwzuui...@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 

--
https://mail.python.org/mailman/listinfo/python-list