IDLE subprocess startup error - python

I have the code below in a file called code.py. I am using IDLE to edit the file. When I click Run>Run Module I get the error:
"IDLE's subprocess didn't make connection. Either IDLE can't start a
subprocess of personal firewall software is blocking the connection."
I am using Windows 7 Ultimate 64bit, but I have the 32bit version of Python 2.7 installed.
I have looked for a solution on this site as well as others but all of them seem to recommend deleting something called tkinter.py (I have no idea what this is) or to turn off my firewalls (I have none enabled aside from Microsoft Security Essentials which isn't a firewall.)
#Globals
#-------------------
x_pad = 476
y_pad = 444
import ImageGrab
import os
import time
import win32api, win32con
def screenGrab():
box = (x_pad+1,y_pad+1,x_pad+641,y_pad+480)
im = ImageGrab.grab(box)
im.save(os.getcwd() + '\\full_snap__' + str(int(time.time())) +
'.png', 'PNG')
def main():
pass
if __name__ == '__main__':
main()
def leftClick():
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
time.sleep(.1)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
print 'Click.' #completely optional. But nice for debugging purposes.
def leftDown():
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
time.sleep(.1)
print 'left Down'
def leftUp():
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
time.sleep(.1)
print 'left release'
def mousePos(cord):
win32api.SetCursorPos((x_pad + cord[0], y_pad + cord[1])
def get_cords():
x,y = win32api.GetCursorPos()
x = x - x_pad
y = y - y_pad
print x,y

The thing is "python.exe" is being obstructed by "tkinter.py") that you created(i.e., you have written a program with Tk() and named it as tkinter.py and saved that in the root folder of python). And that's it just make sure that you don't save any program file directly in the root folder of python.

Another fix!!! Hopefully this will help someone.
I had the same problem and noticed something quite interesting. I had accidentally named a file (inside the desktop folder I was working in) "tkinter" (it will cause the same problem if you rename a file by any reserved keyword, I assume). Everytime I ran or attempted to run this file, it created a pycache folder, and the error you mention above came up. Deleting the erroneously named python file solved the problem.
So - look for ANY files (in the folder you are working with or indeed the root folder) that are named after any reserved words. Delete them. Hopefully it'll work!

I had the same problem. what i did that solved it, was to move every .py file that i had created in "C:\Python33" folder, to a sub-folder that i named "Examples". seems like one of my files was the cause of this problem.

I also had the following problem. My file was named code.py, and was working fine untill I installed Canopy, and numpy.
I tried reinstalling python, but what solved the problem for me was simply renaming the file. I called my file myCode.py, everything started working fine. Strange problem...

I made a python file and named it "socket.py" so then python IDLE showing an error on startup that 'startup failure'
so the problem is that if we are using python reserved keywords or module names as our python file name that it conflicts with built-in modules.
the solution is: go to path C:\Users\sony\AppData\Local\Programs\Python\Python38 where your python files are saved and just renamed that file.
then start IDLE.

Happily using IDLE continously under python36 and windows10, it has suddenly given this error on all the programs I'm working on, with no new files created.
I terminated IDLE and tried to restart it with idle.bat but that no longer works.
Happily I have been able to restart it successfully with Lib\idlelib\idle.pyw.
All my recent programs are there and they can again be run without problems.
No need to reinstall python.

Related

How do I start a COM server? Code is in Python

I want to run Python code as a COM server. Eventually I want to run an RTD server available here. But first I want to know what exactly you have to do to getting any COM server running. So let's focus on this example.
class HelloWorld:
_reg_clsid_ = "{7CC9F362-486D-11D1-BB48-0000E838A65F}"
_reg_desc_ = "Python Test COM Server"
_reg_progid_ = "Python.TestServer"
_public_methods_ = ['Hello']
_public_attrs_ = ['softspace', 'noCalls']
_readonly_attrs_ = ['noCalls']
def __init__(self):
self.softspace = 1
self.noCalls = 0
def Hello(self, who):
self.noCalls = self.noCalls + 1
# insert "softspace" number of spaces
return "Hello" + " " * self.softspace + who
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(HelloWorld)
Ok, this works in the way that there were no errors and server is registered, hence it is available in the HKEY_CLASSES_ROOT registry. But what can I do with this? Some say you have to compile a instance and have a .dll or .exe file. WHat else do I have to do?
Well, I ran your example. The registry key for the server is at:
HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{7CC9F362-486D-11D1-BB48-0000E838A65F}
It has two subkeys... one for LocalServer32 and one for InProcServer32
I created a simple VBA macro in Excel:
Sub d()
Set obj = CreateObject("Python.TestServer")
MsgBox obj.Hello("joe")
End Sub
Macro ran just fine. My version of Excel is 64-bit. I ran the macro and then fired up Task Manager while the message box was being displayed. I could see pythonw.exe running in the background.
The only difference between my python script and yours is probably the name and also that I added a line to print to make sure I was executing the function:
if __name__=='__main__':
import win32com.server.register
print("Going to register...")
win32com.server.register.UseCommandLine(HelloWorld)
When I ran the 64-bit csript.exe test, it worked... as expected... when I ran the 32-bit version it failed.
I know why...sort of...
The registry entry for InProcServer32 is pythoncom36.dll
That's no good. It is an incomplete path. I tried modifying the path variable on my shell to add to one of the 3 places where the DLL existed on my system, but it didn't work. Also, tried coding the path in the InProcServer32. That didn't work.. kept saying it couldn't find the file.
I ran procmon, and then I observerved that it couldn't load vcruntime140.dll. Found the directory under python where those files were, and added to my path. It got further along. If I cared enough, I might try more. Eventually using procmon, I could find all the problems. But you can do that.
My simple solution was to rename the key InProcServer32 for the CLSID to be _InProcServer32. How does that work? Well, the system can't find InProcServer32 so it always uses LocalServer32--for 32-bit and 64-bit processes. If you need the speed of in process then you'd need to fix the problem by using procmon and being relentless until you solved all the File Not Found errors and such. But, if you don't need the speed of in process, then just using the LocalServer32 might solve the problem.
Caveats I'm using an Anaconda distro that my employer limits access to and I can only install it from the employee store. YMMV.

Problem with broken backup and python script

Right up front to be clear, I am not fluent in programming or python, but generally can accomplish what I need to with some research. Please excuse any bad formatting structure, as this is my first post to a board like this
I recently updated my laptop from Ubuntu 18.04 to 20.04. I created a full system backup with Dejadup, which due to a missing file, could not be restored. Research brought me to post on here from 2019 for manually restoring these files. The process called for 2 scripts, 1 to unpack and the second to reconstruct the files, both created by Hamish Downer.
The first,
"for f in duplicity-full.*.difftar.gz; do echo "$f"; tar xf "$f"; done"
seemed to work well and did unpack the files.
The second,
#!/usr/bin/env python3
import argparse
from pathlib import Path
import shutil
import sys"
is the start of a re-constructor script. Using terminal from within the directory I am trying to rebuild I enter the first line and return.
When I enter the second line of code the terminal just "hangs" with no activity, and will only come back to the prompt if I double click the cursor. I receive no errors or warnings. When I enter the third line of code
"from pathlib import Path"
and return I then get an error
from: can't read /var/mail/pathlib
The problem seems to originate with the "import argparse" command and I assume is due to a symlink.
argparse is located in /usr/local/lib/python3.8/dist-packages (1.4.0)
python3 is located in /usr/bin/
Python came with the Ubuntu 20.04 distribution package.
Any help with reconstructing these files would be greatly appreciated, especially in a batch as this script is meant to do versus trying to do them one file at a time.
Update: I have tried adding the "re-constructor" part of this script without success. This is a link to the script I want to use:
https://askubuntu.com/questions/1123058/extract-unencrypted-duplicity-backup-when-all-sigtar-and-most-manifest-files-are
Re-constructor script:
class FileReconstructor():
def __init__(self, unpacked_dir, restore_dir):
self.unpacked_path = Path(unpacked_dir).resolve()
self.restore_path = Path(restore_dir).resolve()
def reconstruct_files(self):
for leaf_dir in self.walk_unpacked_leaf_dirs():
target_path = self.target_path(leaf_dir)
target_path.parent.mkdir(parents=True, exist_ok=True)
with target_path.open('wb') as target_file:
self.copy_file_parts_to(target_file, leaf_dir)
def copy_file_parts_to(self, target_file, leaf_dir):
file_parts = sorted(leaf_dir.iterdir(), key=lambda x: int(x.name))
for file_part in file_parts:
with file_part.open('rb') as source_file:
shutil.copyfileobj(source_file, target_file)
def walk_unpacked_leaf_dirs(self):
"""
based on the assumption that all leaf files are named as numbers
"""
seen_dirs = set()
for path in self.unpacked_path.rglob('*'):
if path.is_file():
if path.parent not in seen_dirs:
seen_dirs.add(path.parent)
yield path.parent
def target_path(self, leaf_dir_path):
return self.restore_path / leaf_dir_path.relative_to(self.unpacked_path)
def parse_args(argv):
parser = argparse.ArgumentParser()
parser.add_argument(
'unpacked_dir',
help='The directory with the unpacked tar files',
)
parser.add_argument(
'restore_dir',
help='The directory to restore files into',
)
return parser.parse_args(argv)
def main(argv):
args = parse_args(argv)
reconstuctor = FileReconstructor(args.media/jerry/ubuntu, args.media/jerry/Restored)
return reconstuctor.reconstruct_files()
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
I think you are typing the commands to the shell instead of python interpreter. Please check your prompt, python (started with python3) has >>>.
Linux has an import command (part of the ImageMagick) and understands import argparse, but it does something completely different.
import - saves any visible window on an X server and outputs it as an
image file. You can capture a single window, the entire screen, or any
rectangular portion of the screen.
This matches the described behaviour. import waits for a mouse click and then creates a large output file. Check if there is a new file named argparse.
An executable script contains instruction to be processed by an interpreter and there are many possible interpreters, several shells (bash and alternatives), languages like Perl, Python, etc. and also some very specialized like nft for firewall rules.
If you execute a script from the command line, the shell reads its first line. If it starts with #! characters (called "shebang"), it uses the program listed on that line. (note: /usr/bin/env there is just a helper to find the exact location of a program).
But if you want to use an interpreter interactively, you need to start it explicitly. The shebang line has no special meaning in this situation, only as the very first line of a script. Otherwise it is just a comment and is ignored.

My code to connect and display the contents of a ftp server does not cwd beyond /[dir]/

I can't seem to be able to change directory past /ubuntu/ on archive.ubuntu.com, and I suspect my code to change to the wrong directory. Where is my bug?
from ftplib import FTP
from tkinter import *
ftp = FTP("archive.ubuntu.com")
ftp.login()
window = Tk()
window.geometry("640x480")
def listdir():
print(ftp.dir())
[child.destroy() for child in window.winfo_children()]
for x in ftp.nlst():
Button(window, text=x, command=(lambda: cdir(x))).pack()
def cdir(x):
f = ftp.pwd()+"/"+x
ftp.cwd(f)
listdir()
listdir()
window.mainloop()
this is simple code to reproduce my problem in my larger application.
system: windows
python runtime: python 3.8
How would it be possible to prevent this bug? I can change directory just fine using python command line. ftplib isn't throwing any errors, I have tried printing every command that I run on ftp.
You'll be wanting early binding in your lambda function. Change from
lambda: cdir(x)
to:
lambda y=x: cdir(y)
Otherwise you get the value of x when the function is called, rather than the one when the function was created.
(Obviously you still need to tell your code about the difference between files and directories because with above fix in place you can then get to navigate as far as buttons representing actual files, and clicking on those will give an error when it tries to change directory to them. But the above will fix the issue that you are encountering right now.)

Name 'Actor' is not defined

I have a problem with python programming, when I'm trying to write a game (introduced by the book: Coding Games Python DK 3), it says:
name 'Actor' is not defined.
here's my code:
import pgzrun
from random import randint
WIDTH = 400
HEIGHT = 400
dots = []
lines = []
next_dot = 0
for dot in range(0, 10):
actor = Actor("dot")
actor.pos = randint(20, WIDTH -20), randint (20, HEIGHT - 20)
dots.append(actor)
def draw():
screen.fill("black")
number = 1
for dot in dots:
screen.draw.text(str(number), (dot.pos[0], dot.pos[1] + 12))
dot.draw()
number = number + 1
for line in lines:
screen.draw.line(line[0], line[1], (100, 0, 0))
pgzrun.go()
You are using the Python library pgzero (indirectly via importing pgzrun).
I had refactored my game code into multiple files (imported into the main file) and did also observe the same strange
NameError: name 'Actor' is not defined
error message.
The Actor class seems to be "private", but can be imported with this simple code line:
from pgzero.builtins import Actor, animate, keyboard
For background see:
https://github.com/lordmauve/pgzero/issues/61
Update Aug 18, 2019: The screen object cannot be imported since it is created as global variable during runtime (object = instance of the Screen class) and IDE-supported code completion is not possible then. See the source code: https://github.com/lordmauve/pgzero/blob/master/pgzero/game.py (esp. the def reinit_screen part)
This page on the Pygame site will help you run it from your IDE: https://pygame-zero.readthedocs.io/en/stable/ide-mode.html
Essentially, you have to have these two lines of code:
import pgzrun
...
...
pgzrun.go()
But during coding, the IDE will still complain that objects and functions like screen and Actor are undefined. Pretty annoying. As far as I know, there's no way to fix it, you just have to ignore the complaints and hit Debug > Run. Provided you have no mistakes, the program will compile and run.
With regards to
import pgzrun
actor = pgzrun.Actor("dot")
Or
from pgzrun import *
dot=Actor("dot")
Neither of these help integrated development environments like Spyder or Visual Studio recognise objects and functions like screen and Actor
pgzrun doesn't seem to behave like a normal python library.
Pygame relies on using pgzrun to run your python script from the command line:
pgzrun mygame.py
In chapter 5, page 73 of Coding Games in Python, step 2 is to save the file as numbers.py. This creates a conflict with the built in module numbers. This is the cause of the error "name 'Actor' is not defined". The solution is to save the file with a different name (i.e. follow.py).
Please define the class Actor or import it from package if you have it in your pip packages or in same dir
From what I could find on the Pygame Documentation website, Actor is defined in the pgzrun package. With your current import statements, you would have to call the Actor constructor by
actor = pgzrun.Actor("dot")
which would show the compiler that Actor belongs to pgzrun.
Alternatively, if you wanted to just use Actor("dot"), you could change your import statement to
from pgzrun import *
which means "import everything from pgzrun". This also keeps track of what comes from pgzrun and tells the compiler, but it could lead to issues (eg. if you define your own Actor constructor in your code, the compiler wouldn't know which one you're trying to use).
well I just found out It has no problem running with cmd, it has problem with running from the software itself.
So, code is correct but I might suspect something. I think you didnt upload a picture called "dot" in pgzero.
I was getting the same error message, until finally I found this topic here. The book version is missing those pgzrun first and last lines.
If you're still getting the error after putting those lines in, I bet your 'python' points to python2. Try this at the command-line:
python -V
If it shows a version of 2, you'll need to fix that. Check
which python
If it's in /usr/bin, you can do:
sudo su
cd /usr/bin
rm python
ln -s python3 python
If it's in an update-alternatives directory, you can run that program to fix it.
I had the exact same problem at the exact same code. After weeks of deleting and rewriting everything that has to do with python on my computer, I realised that it runs if you make the screen. ... lines comments by writing # in the start of each of them. I haven't found how to fix it yet, but I will inform when I will.
I found the issue. Everything on my computer was uploaded automatically to OneDrive. As a result I had a file with the same name on my computer and on OneDrive and when I tried to run it, it always ran from OneDrive where pygame and pgzero are not installed. I solved it by disconnecting auto upload and by changing the name of the file that was on my computer. Hope this works!
the solution is very simple. do not give the file a name.py name because it conflicts with python numbers.py

Extend the functionality of a compiled Python script

I'm not a programmer, so I don't even know in what terms should I ask this. Let's say I've compiled a Python script to have an .exe (I use py2exe to do this). This is the major program. Now, I want to add some extra functionality to it, but I don't want to recompile the entire script with the added functionality. I tried to search something on the web, and I found examples of extending a C++ or other application with Python scripts (like a sort of plugin). But I can't figure out how to do it with an application already written in Python.
I tried this: I wrote major.py (this is the script from where I build the executable) and stuff.py. In major I wrote this:
def generic():
import stuff
while True:
param=input('what did you say? ')
stuff.speak(param)
generic()
And in stuff I wrote this:
def speak(param):
print(param)
Then I created a .exe with py2exe. It works as expected, when I run the program in the command line says "what did you say?" and waits until I type something, then it prints what I typed.
Then, I changed stuff.py with this:
def speak(param):
print('I said '+param)
Hoping that now upon the execution of the .exe created earlier it would print "I said.." plus whatever I typed. Obviously, it didn't work, the program continued to behave like before. So I'm guessing that once I imported stuff and created the .exe file, that import is permanent, not allowing me to change whatever is in stuff. What should I do?
py2exe packs the compiled scripts in the executable.
You need to recreate the executable (which will recompile any changed script) to see the changes take effect.
EDIT following the comments:
You can do it if you dynamically import/reimport the module from inside the executable.
In your main script you do (see code below)
mod, error = loadmodule('mystuff.py')
if mod is not None:
# loading succeeded you can now proceed and do things with it
pass
Of course you have to leave mystuff.py out of the scripts that py2exe packs into the executable. In the above example mystuff.py would be in the same directory as the executable.
The loading code:
def loadmodule(modpath, modname=''):
if not modpath.endswith('.py'):
modpath += '.py'
# generate a random name for the module
if not modname:
modpathbase = os.path.basename(modpath)
modname, _ = os.path.splitext(modpathbase)
version = (sys.version_info[0], sys.version_info[1])
if version < (3, 3):
mod, e = loadmodule2(modpath, modname)
else:
mod, e = loadmodule3(modpath, modname)
return mod, e
def loadmodule2(modpath, modname):
import imp
try:
mod = imp.load_source(modname, modpath)
except Exception as e:
return (None, e)
return (mod, None)
def loadmodule3(modpath, modname):
import importlib.machinery
try:
loader = importlib.machinery.SourceFileLoader(modname, modpath)
mod = loader.load_module()
except Exception as e:
return (None, e)
return (mod, None)
If you run your script from Python, instead of compiling it as an executable, you can make changes and run them without having to recompile. The py2exe is mostly for allowing you to distribute your application to other Windows computers that don't have Python installed. After you have finished developing it, then compile it as an executable so you can run it on other computers.
There is no way to do what you want. py2exe builds a standalone python interpreter (In the file named python.dll) with just the dependencies of your project. Then the .exe file runs your script using that interpreter
I suggest you that if you really need to provide regular upgrades then you should recompile it, or install python in the target machine, or make an updating routine that checks for updates and compiles it in the target machine (With py2exe)

Categories

Resources