os.exec on Windows - python

I have a script that calls os.execvp into another Python instance. After doing this, I appear to be attached to a cmd.exe instance, not the Python instance I just created. The Python instance responds to Ctrl+C however.
H:\bin>Python 3.2.1 (default, Jul 10 2011, 21:51:15) [MSC v.1500
32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print('hi')
Can't find file ('hi')
H:\bin>
H:\bin>
KeyboardInterrupt
>>> echo hi
hi
The call to exec:
from sys import argv
os.execvp('python', argv)
How do I replace the original Python instance with the new one, as per the behaviour one might see on Linux?

On Unix executing binaries is split into two stages - fork(3) to clone current process and exec(3) to load executable into address space. On windows there is only CreateProcess which does the same thing as fork+exec.
For portability your best bet is to use subprocess.Popen (which also does proper filename quoting on Windows unlike os.* counterparts) as in http://docs.python.org/library/subprocess.html#replacing-the-os-spawn-family

Related

Ctrl+Z does not exit Python 3.10 in Git Bash

I just downloaded the latest Git Bash (2.36.1 64-bit) and installed Python 10. I'm running Windows 11. Among a couple of other unexpected changes from my earlier setup using a previous version of Git Bash and mostly running Python 3.9 (i.e. I now have to run python -i for the interactive python interpreter, for all 2.x and 3.x versions, instead of just running python), the most frustrating is that ctrl+z followed by Enter no longer quits from the interpreter. Instead I must call exit(). Ex:
user#User MINGW64 ~
$ python -i
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> # ctrl+z, Enter pressed here
File "<stdin>", line 1
^
SyntaxError: invalid syntax
>>> exit()
user#User MINGW64 ~
$
The same is true for my other installations of python 3 (3.7, 3.8, 3.9), but python 2.7 still has the expected behavior:
user#User MINGW64 ~
$ $PYTHON\\Python27\\python -i
Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> # ctrl+z, Enter pressed here
user#User MINGW64 ~
$
What I've tried
I've done quite a bit of research but can't figure out what may have changed. In the earlier version of Git Bash, I remember that ^Z, ^X, ^C, and ^V characters (and maybe more) would display explicitly in the console when typed. Curiously, pressing ctrl+c followed by Enter comes with the error message below. Did some sort of character encoding change in the newer versions of Git Bash?
user#User MINGW64 ~
$ python
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> # ctrl+c, Enter pressed here
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py", line 14, in decode
def decode(self,input,errors='strict'):
KeyboardInterrupt
The above exception was the direct cause of the following exception:
KeyboardInterrupt: decoding with 'cp1252' codec failed (KeyboardInterrupt: )
>>>
I am too lazy to constantly type exit(). How can I restore the functionality where pressing ctrl+z, then Enter quits the interpreter for my python 3 versions?
After stumbling upon this answer, I've found a solution that restores the functionality I wanted. Instead of:
alias python3='.../Python310/python
in which case you must get to the interactive interpreter using python3 -i, and ctrl+Z keystrokes are not recognized, use:
alias python3='winpty .../Python310/python
If it's helpful to anyone, here's how I've set up my ~/.bash_aliases:
alias python2='winpty C:\Users\<user>\AppData\Local\Programs\Python/Python27/python'
alias python3.7='winpty C:\Users\<user>\AppData\Local\Programs\Python/Python37/python'
alias python3.8='winpty C:\Users\<user>\AppData\Local\Programs\Python/Python38-32/python'
alias python3.9='winpty C:\Users\<user>\AppData\Local\Programs\Python/Python39/python'
alias python3.10='winpty C:\Users\<user>\AppData\Local\Programs\Python/Python310/python'
alias python3='python3.10'
alias python='python2'
and these lines must be in ~/bashrc:
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
Now you can open the python interpreter without requiring -i (just run python), and ctrl+Z, Enter exits it.
Edit: After reading this answer, I reinstalled Git Bash with "Enable experimental support for pseudo consoles" checked and functionality is restored without needing to run Python through winpty.

Run scons on Windows 10 environment with Python 2.7 and Python 3

How can I run scons on Windows 10 when Python 3.6.1 and Python 2.7.13 is installed? When typing python into my command window I get the following output:
Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
Since I personally use Python 3.6.x this is fine for me and I do not want to change this.
When typing py -2 into my command window I get the following output:
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
scons does not work with Python 3.x. It needs to be executed with Python 2.7.x. How can I "tell" scons to use Python 2.7.x?
When I just type scons into the command prompt I get the following output:
PS C:\dev\projectX> scons
Fatal Python error: Py_Initialize: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
Current thread 0x00007050 (most recent call first):
Try Changing line 23 in scons.bat from:
python "%scriptname%" %*
to
py -2 "%scriptname%" %*
Note that work on getting SCons to run under both py 2 and py 3.5+ is mostly done and should be released in the next month (or so)
Before running scons in Powershell, amend the PATH environment variable to put your Python 2.7 installation at the front. Something like:
SET PATH=C:\Python27;%path%

Using Appkit and Python to hide mouse cursor on OSX

I'm trying to script hiding the mouse cursor on OSX 10.9. I have Chrome starting and going full screen for a kiosk and I'd like to periodically run a script to hide the cursor.
Applescript no longer directly supports "call method" to call the objective C method, so I thought the simplest method would be to use AppKit from the provided python.
It crashes:
$ python
Python 2.7.5 (default, Mar 9 2014, 22:15:05)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import AppKit
>>> AppKit.NSCursor.hide()
Assertion failed: (CGAtomicGet(&is_initialized)), function CGSConnectionByID, file Services/Connection/CGSConnection.c, line 123.
Abort trap: 6
I suspect there is a pre-requisite call I need to make to initialize something, but I haven't found anything yet while digging through docs/google.
What am I missing?
I've had luck with the Quartz included with PyObjC:
import Quartz
Quartz.CGDisplayHideCursor(Quartz.CGMainDisplayID())

python doesn't run script with 'python <script name>'

I'm gett a strange problem when running python script from linux, it doesn't seem to bother running the script file (I've put a print statement on the first line and it doesn't come out):
zl#o-xterm-71 h2bin> python main.py
Python 2.7.3 (default, Feb 4 2013, 18:00:47)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
The script runs fine on my laptop with 2.7.5, and even with 2.4.3 so I'd assume it's not a version problem. Should be something simple that I missed.. Anyone had this before? Thanks!
edit1:
dummy.py:
def main():
print "it works"
if __name__ == '__main__':
main()
output:
zl#o-xterm-71 h2bin> python dummy.py
Python 2.7.3 (default, Feb 4 2013, 18:00:47)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Typing 'python' gives the exact same thing.
tarvalon:/tmp$ cat dummy.py
def main():
print("it works")
if __name__ == '__main__':
main()
tarvalon:/tmp$ python dummy.py
it works
So, it works. There's some problem with your installation. Looks like your python file is a script that is calling the real python binary without parameters. Best commands to debug that: file which python, cat which python and, most important, python --help.
Not 100% sure about this, but I think the quotes are messing things up for you.
Change:
print “it works”
To
print "it works"
You could explain this behaviour if someone/something put a wrapper script/program named python in your PATH, that runs a real Python interpreter, but neglects to pass the arguments.

"The system cannot find the file specified" when invoking subprocess.Popen in python

I'm trying to use svnmerge.py to merge some files. Under the hood it uses python, and when I use it I get an error - "The system cannot find the file specified". Colleagues at work are running the same version of svnmerge.py, and of python (2.5.2, specifically r252:60911) without an issue.
I found this link, which describes my problem. Trying what was outlined there, I confirmed Python could find SVN (it's in my path):
P:\>python
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> i,k = os.popen4("svn --version")
>>> i.close()
>>> k.readline()
'svn, version 1.4.2 (r22196)\n'
Looking at the svnmerge.py code, though, I noticed for python versions 2.4 and higher it was following a different execution path. Rather than invoking
os.popen4() it uses subprocess.Popen(). Trying that reproduces the error:
C:\>python
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> p = subprocess.Popen("svn --version", stdout=subprocess.PIPE,
>>> close_fds=False, stderr=subprocess.PIPE)
Traceback (most recent call last):
File "", line 1, in
File "C:\Python25\lib\subprocess.py", line 594, in __init__
errread, errwrite)
File "C:\Python25\lib\subprocess.py", line 816, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
>>>
For now, I've commented out the 2.4-and-higher specific code, but I'd like to find a proper solution.
If it's not obvious, I'm a complete python newbie, but Google hasn't helped.
It's a bug, see the documentation of subprocess.Popen. There either needs to be a "shell=True" option, or the first argument needs to be a sequence ['svn', '--version']. As it is now, Popen is looking for an executable named, literally, "svn --version" which it doesn't find.
I don't know why it would work for your colleagues though, if they are running the same OS and version of Python... FWIW it gives me the same error message on a mac, and either of the two ways I gave fixes it.

Categories

Resources