Looking to use a include a redis server for storing application specific data with my pyinstaller bundled application.
Before getting into it hands-on, need some guidance.
Are these the steps to follow for it?
(1) Bundle redis-server executable. And run it as a standalone application via some script in my bundled package.
(2) Use redis client packages in python to connect to the redis-server
I guess (2) should surely work. But is there any easy way of doing (1).
You can bundle arbitrary binaries with the --add-binary option on the command line or the binaries argument to the Analysis call in your .spec file. Check out the manual for details, but one example:
pyinstaller -F main.py --add-binary=`which redis-server`:bin
I don't know of a way to run arbitrary executables, but you could have some python code in your app to detect when you're bundled, find the redis binary, and start it up. Again, you can check out the documentation for details on how to go about this but, again, a example of how this could look (optional contextmanager elegance stolen from another answer):
import sys
import os
import subprocess
from contextlib import contextmanager
#contextmanager
def bundledredis():
proc = subprocess.Popen(
[os.path.join(sys._MEIPASS, 'bin', 'redis-server')])
yield
proc.terminate()
#contextmanager
def optional(condition, context_manager):
if condition:
with context_manager:
yield
else:
yield
def realmain():
print('doing stuff')
def main():
with optional(getattr(sys, 'frozen', False), bundledredis()):
realmain()
if __name__ == '__main__':
main()
Related
I am trying to run a python program, written using Anaconda, as a Windows Service. The complexity is that I'd like to run the Windows Service from a specific conda virtual environment. The idea being that in the future, we may develop more python based windows services that may have different module dependencies, thus keeping each within its own virtual environment would be ideal.
I've found several excellent articles about how to write a python program as a windows service and they work fine. I created a very simple test program that simply writes some messages to a text file after the service starts. I can successfully install this test python program as a windows service and I see the various text messages in my file. However, when I try to import modules like Numpy or TensorFlow into my simple test python program, the service won't start and I get failure messages that their respective DLL's can't be found.
I am sure the problem is because the required conda virtual environment hasn't been activated. At the same time, I've tried replicating the various conda environment variables at the system level; tried adding all of the required python library paths from the virtual environment to the system path and system-wide python path, but to no avail.
I suspect that if I could activate the conda virtual environment as part of my python code, that would solve the problem. (I also suspect that installing all of the required modules into my base configuration would solve the problem, but i'd like to avoid that).
Here is the little test program I've written. This program works just fine with the basic Python modules like sys, os and so forth. It fails with the following error message when I try to run it and include Numpy or TensorFlow:
(This is from the Windows Event Viewer after I try and start my service - which does install correctly):
Python could not import the service's module
Traceback (most recent call last):
File "D:\TFS\Projects\DEV\AEPEnrollmentForms\src\aepenrl\Windows_Service_Example.py", line 35, in
import numpy as np
File "C:\Users\pboerner\AppData\Local\conda\conda\envs\aepenr\lib\site-packages\numpy__init__.py", line 140, in
from . import _distributor_init
File "C:\Users\pboerner\AppData\Local\conda\conda\envs\aepenr\lib\site-packages\numpy_distributor_init.py", line 34, in
from . import _mklinit
ImportError: DLL load failed: The specified module could not be found.
%2: %3
Here is the code for the simple test program. (Most of the Windows Service integration work I took from an excellent article provided by Davide Mastromatteo)
import numpy as np
import socket
import sys
import time
import win32serviceutil
import servicemanager
import win32event
import win32service
class SimpleService(win32serviceutil.ServiceFramework):
'''Base class to create winservice in Python'''
_svc_name_ = 'TestPythonSrvc'
_svc_display_name_ = 'Test Python Service'
_svc_description_ = 'Test to see how to create a windows service with python'
#classmethod
def parse_command_line(cls):
'''
ClassMethod to parse the command line
'''
win32serviceutil.HandleCommandLine(cls)
def __init__(self, args):
'''
Constructor of the winservice
'''
self.isrunning=True
self.fid = open("D:\\temp\\simple_service.txt", "w")
self.fid.write("Initialize\n")
self.fid.flush()
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
'''
Called when the service is asked to stop
'''
self.stop()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
'''
Called when the service is asked to start
'''
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def start(self):
'''
Override to add logic before the start
eg. running condition
'''
self.isrunning = True
self.fid.write("Start method called\n")
self.fid.flush()
def stop(self):
'''
Override to add logic before the stop
eg. invalidating running condition
'''
self.isrunning = False
self.fid.write("STOP method called. Setting stop flag\n")
self.fid.flush()
def main(self):
'''
Main class to be ovverridden to add logic
'''
a = np.zeros((100,1))
while True:
if self.isrunning:
self.fid.write(f"Tick. Numpy array shape {a.shape}\n")
self.fid.flush()
time.sleep(1)
else:
self.fid.write("Breaking out of main loop\n")
self.fid.flush()
break;
self.fid.write("Closing the log file\n")
self.fid.flush()
self.fid.close()
if __name__ == '__main__':
# This code block was required to get this simple service example to run
# on a Windows 10 laptop with Admin privs. Only calling the
# HandleCommandLine method alone didn'd seem to work. Not sure why but this
# code was provided as a solution on the Web.
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(SimpleService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(SimpleService)
Unfortunately the service manager of Windows is not as fexible as, let's say, systemd. The only method I found was to do the following:
make a batch file holding all your logic, e.g.
call C:\ProgramData\Anaconda3\Scripts\activate.bat C:\ProgramData\Anaconda3
call activate yourenv
cd C:/path/to/your/wd
python yourservice.py and your args
NB: your activate.bat file could be under your home folder: ~\AppData\local\Continuum\anaconda3\Scripts
Use the NSSM (which is aptly named): http://nssm.cc/download ; see also Run batch file as a Windows service . You need to start the command prompt or powershell as administrator before calling nssm.
This works to serve a bokeh server really well (using bokeh serveinstead of python). I guess it works for python script of any complexity then.
You can run a command upon stopping or exiting within the "hooks" tab.
In my case the logic within the batch file depends on the machine, so I need to make an additional python script that is called upon setting up to write the batch file.
I was stuck in the exact same situation when I came across a blog (link below) and followed the steps in it
Create a run.bat file in your working directory with the following lines.
call conda activate env
call python app.py
So that when you call your batch file it will first activate the virtual environment and then run the python script.
Download NSSM, no need to install it. Once downloaded, go to the NSSM -> win32/win64 (as per your computer architecture) and run the following command in the command prompt as administrator:
C:\nssm-2.24\win64\nssm install <service name> "C:\path\to\your\run.bat"
Your service is installed at this point but not yet started.
You might need to configure it
C:\nssm-2.24\win64\nssm edit <service name>
NSSM service editor will open after executing the above command where you can set Display names, description, log files, etc.
Once done you can start the service as
C:\nssm-2.24\win64\nssm start <service name>
Link for reference:-
Run Windows Service in its own Python virtual environment
I simply followed these steps and it worked just fine for me. I hope it will work for you as well.
I am running the code below by python win_service.py install from the normal command prompt, where I get access denied error.
Installing service TestService
Error installing service: Access is denied. (5)
which I was able to resolve when I started the command prompt by starting as administrator.
I was able to install the service, but I was unable to start the service.
Service installed
Starting service TestService
Error starting service: The service did not respond to the start or control request in a timely fashion.
import win32serviceutil
import win32service
import win32event
import servicemanager
import socket
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "TestService"
_svc_display_name_ = "Test Service"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
socket.setdefaulttimeout(60)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
def main(self):
print "running"
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
What am doing wrong, is there any other way to install the service that would solve the issue and how to dynamically run it as administrator.
I know this is old but I was stuck on this forever. For me, this specific problem was solved by copying this file - pywintypes36.dll
From -> Python36\Lib\site-packages\pywin32_system32
To -> Python36\Lib\site-packages\win32
It's possible that your service is not starting because it's unable to find the executable. I had a similar issue that was solved by adding some pywin32 related directories to my system path. You can do this using setx:
setx /M PATH "%PATH%;C:\Python27;C:\Python27\Scripts;C:\Python27\Lib\site-packages\pywin32_system32;C:\Python27\Lib\site-packages\win32"
Try running this in a cmd window with admin privileges and adjust the paths to match your own python installation.
Finally, the solution for this.
First step:
USE pyinstaller to create a standalone executable file, i.e.:
pip install pyinstaller
pyinstaller yourproject.py
cd dist\yourproject
yourproject.exe install
Second step:
Note that. When the Windows Service calls "your program", it gives a time to answer according the Service Development Protocol. All of the codes above, are not starting the service. Please, change your code as below:
if __name__ == '__main__':
if len(sys.argv) > 1:
# Called by Windows shell. Handling arguments such as: Install, Remove, etc.
win32serviceutil.HandleCommandLine(JobManager)
else:
# Called by Windows Service. Initialize the service to communicate with the system operator
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(JobManager)
servicemanager.StartServiceCtrlDispatcher()
As noted by Chip (and which I've missed while trying to figure this out), pythonservice.exe is going to run as a system service, so it will have a different environment than you do as a user. Running python service.py debug will run just fine because it's still running with your user environment, but if you run python service.py start, it may now fail instead due to the difference in environment variables. An instant timeout is most likely due to pythonservice.exe failing to execute, and it will fail to execute it it's missing either PythonXX.dll or pywintypesXX.dll.
PythonXX.dll is likely to be in your system path already (depending on how Python was installed), but if you're like me and trying to be extra careful to not alter the environment, that's going to be a problem. I was running something like .\.pyenv37\Scripts\python.exe service.py start, gets Python37.dll from the PATH, not the venv like I assumed, so it's no longer known when pythonservice.exe starts running using a different PATH, which causes it to immediately fail Windows reports it as an instant timeout.
The same goes for pywintypesXX.dll, except instead of installing it somewhere in your search path, the more portable solution is to drop it in the same directory as pythonservice.exe since the deafult DLL search path includes it. It will also cause your service to immediately timeout if it if pythonservice.exe can't find it.
Figuring this out without any sort of logs is an absolute nightmare, let me tell you!
EDIT: Here's what I'm using to verify all of that on script installation/update:
# customOptionHandler will only run after service install/update
if __name__=='__main__':
win32serviceutil.HandleCommandLine(AppServerSvc, customOptionHandler=post_service_update)
.
def post_service_update(*args):
import win32api, win32con, win32profile, pywintypes
from contextlib import closing
env_reg_key = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"
hkey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, env_reg_key, 0, win32con.KEY_ALL_ACCESS)
with closing(hkey):
system_path = win32api.RegQueryValueEx(hkey, 'PATH')[0]
# PATH may contain %SYSTEM_ROOT% or other env variables that must be expanded
# ExpandEnvironmentStringsForUser(None) only expands System variables
system_path = win32profile.ExpandEnvironmentStringsForUser(None, system_path)
system_path_list = system_path.split(os.pathsep)
core_dll_file = win32api.GetModuleFileName(sys.dllhandle)
core_dll_name = os.path.basename(core_dll_file)
for search_path_dir in system_path_list:
try:
dll_path = win32api.SearchPath(search_path_dir, core_dll_name)[0]
print(f"System python DLL: {dll_path}")
break
except pywintypes.error as ex:
if ex.args[1] != 'SearchPath': raise
continue
else:
print("*** WARNING ***")
print(f"Your current Python DLL ({core_dll_name}) is not in your SYSTEM PATH")
print("The service is likely to not launch correctly.")
from win32serviceutil import LocatePythonServiceExe
pythonservice_exe = LocatePythonServiceExe()
pywintypes_dll_file = pywintypes.__spec__.origin
pythonservice_path = os.path.dirname(pythonservice_exe)
pywintypes_dll_name = os.path.basename(pywintypes_dll_file)
try:
return win32api.SearchPath(pythonservice_path, pywintypes_dll_name)[0]
except pywintypes.error as ex:
if ex.args[1] != 'SearchPath': raise
print("*** WARNING ***")
print(f"{pywintypes_dll_name} is not is the same directory as pythonservice.exe")
print(f'Copy "{pywintypes_dll_file}" to "{pythonservice_path}"')
print("The service is likely to not launch correctly.")
It may seem like a lot, but it will at leastkeep you from forgetting to do those steps when deploying the service on a new machine/virtual environment or when updating python.
Before you start debugging, I recommend to make sure that the two steps described at https://github.com/mhammond/pywin32, which are
pip install pywin32
and
python Scripts/pywin32_postinstall.py -install
were completed.
if you are using anaconda python, be sure python36.dll is in your system path. This took me a long time to find.
credit: Can't start Windows service written in Python (win32serviceutil)
Make sure you run the application with a different user than the default Local System user. Replace it with the user you successfully be able to run the debug command with.
To replace the user go to the windows services (start > services.msc)
Right click on the service you created > properties > Log On
Uncheck the Local System Account and enter your own.
from all python windows service can not start{error 1053} worked for me.
Because I just set PATH for user login, not for System. You can recheck your PATH for System Variables.
I was also facing the same problem but, After messing out for 4 days, Finally I'm able to find the solution for this problem.
So, Here is the step by step Beginner Guide : https://github.com/PushpenderIndia/PythonWindowsService
Also Posting the same solution here as well.
Steps To Create an Python Windows Service
(1) Copy Paste These Codes to a Python File (e.g. server.py)
import servicemanager
import sys
import win32serviceutil
from mainserver import FlaskServer # Import your code, I've written a module called mainserver which contains FlaskServer Code using OOPs
import threading
import concurrent.futures
import time
class workingthread(threading.Thread):
def __init__(self, quitEvent):
self.quitEvent = quitEvent
self.waitTime = 1
threading.Thread.__init__(self)
def run(self):
try:
# Running start_flask() function on different thread, so that it doesn't blocks the code
executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)
executor.submit(self.start_flask)
except:
pass
# Following Lines are written so that, the program doesn't get quit
# Will Run a Endless While Loop till Stop signal is not received from Windows Service API
while not self.quitEvent.isSet(): # If stop signal is triggered, exit
time.sleep(1)
def start_flask(self):
# This Function contains the actual logic, of windows service
# This is case, we are running our flaskserver
test = FlaskServer()
test.start()
class FlaskService(win32serviceutil.ServiceFramework):
_svc_name_ = "AA Testing"
_svc_display_name_ = "AAA Testing"
_svc_description_ = "This is my service"
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = threading.Event()
self.thread = workingthread(self.hWaitStop)
def SvcStop(self):
self.hWaitStop.set()
def SvcDoRun(self):
self.thread.start()
self.hWaitStop.wait()
self.thread.join()
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(FlaskService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(FlaskService)
(2) Install the latest pywin32.exe
NOTE: If you install pywin32 using pip, then it will not going to install properly, thus will show you some errors,
Visit https://github.com/mhammond/pywin32/releases
And Download the latest exe, If you are using Python 32bit then download pywin32-302.win32-py3.x.exe
If using Python 64 bit, then download pywin32-302.win-amd64-py3.x.exe
(3) Compile your server.py using pyinstaller
Compiling service executable
C:\Users\Pushpender\Desktop> python -m pip install servicemanager
C:\Users\Pushpender\Desktop> pyinstaller --onefile server.py --hidden-import=win32timezone --clean --uac-admin
Installing & Running service executable (Run CMD as Administrator)
C:\WINDOWS\system32>cd C:\Users\Pushpender\Desktop>
C:\WINDOWS\system32>d:
C:\Users\Pushpender\Desktop>server.exe --startup=auto install # Installing service with startup == Automatic
C:\Users\Pushpender\Desktop>server.exe start # For starting service (You can start from Windows Service or From Task Manager)
C:\Users\Pushpender\Desktop>server.exe stop # For stopping service (You can stop from Windows Service or From Task Manager)
C:\Users\Pushpender\Desktop>server.exe remove # For removing installed service
(4) You can run server.py directly without compiling (Run CMD as Administrator)
C:\WINDOWS\system32>cd C:\Users\Pushpender\Desktop>
C:\WINDOWS\system32>d:
C:\Users\Pushpender\Desktop>python server.py --startup=auto install # Installing service with startup == Automatic
C:\Users\Pushpender\Desktop>python server.py start # For starting service (You can start from Windows Service or From Task Manager)
C:\Users\Pushpender\Desktop>python server.py stop # For stopping service (You can stop from Windows Service or From Task Manager)
C:\Users\Pushpender\Desktop>python server.py remove # For removing installed service
NOTE:
You can tweak the above code, for example, you can change the following things
_svc_display_name_ = "AAA Testing"
_svc_description_ = "This is my service"
Also you can change the classes names of FlaskService , workingthread
Please change this line in your code from mainserver import FlaskServer
You can change the startup type to lots of things, type server.exe --help in order to know more about settings
If you want to set the StartUp= Manaull, then don't use --startup=auto, while installing service
If you want to set the StartUp= Automatic (Delayed), then use --startup=delayed, while installing service
Use --startup argument before install argument
(4) Integrate Windows server with Inno Setup Builder
If you want to create a Installer which will Install your service at Installion process & will remove it at Uninstall, then
Add these block of code in your script.iss
[Run]
Filename: "{app}\{#MyAppExeName}"; StatusMsg: "Installing Windows Service ... "; Parameters: "--startup=delayed install"; Flags: runhidden waituntilterminated
Filename: "{app}\{#MyAppExeName}"; StatusMsg: "Running Windows Service ... "; Parameters: "start"; Flags: runhidden waituntilterminated
[UninstallRun]
Filename: "{app}\{#MyAppExeName}"; Parameters: "remove"; Flags: runhidden
Please ensure the below paths are added in your system variables path. The below paths are added for Python 3.7. ensure to add the path as per your python installed version.
C:\Users\1022226\AppData\Local\Programs\Python\Python37\Scripts
C:\Users\1022226\AppData\Local\Programs\Python\Python37
If you use embedded python on windows (portable python) add the folder to path.
C:\[...]\python-3.9.5-embed-amd64
This solved in my case.
I just can't figure out why this is happening...
in my fabric file I have this...
def func():
local("source ../venv/bin/activate")
It is returning 127 on the source command and I am not sure why, when i try to run source in my terminal manually it works. When I try a different command in fabric, like...
local("echo 'foo'")
it also works. Why would source be causing problems? I can't see any reason why this would be happening.
source is unknown by sh. If you want to run a command in the context of a virtual environment, use Fabric's context managers and run the activate binary without source. I've adapted from this answer.
from __future__ import with_statement
from fabric.api import *
from contextlib import contextmanager as _contextmanager
env.activate = '. ./.env/bin/activate'
#_contextmanager
def virtualenv():
with prefix(env.activate):
yield
def deploy():
with virtualenv():
local('echo hello world!')
I created a nice python Twisted app with a plugin for the twistd runner, as specified in the Twisted Documentation: http://twistedmatrix.com/documents/current/core/howto/tap.html. I am having problems packaging this with PyInstaller: my twistd plugin is not found during execution of the frozen application.
To ship my project, I created my own top-level startup script using the twistd runner modules, e.g.
#!/usr/bin/env python
from twisted.scripts.twistd import run
from sys import argv
argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
'myapp_plugin'
]
run()
Next, I use PyInstaller to freeze this as a single directory deployment. Executing the frozen script above fails as it cannot find my twistd plugin (edited for brevity):
~/pyinstall/dist/bin/mystartup?16632/twisted/python/modules.py:758:
UserWarning: ~/pyinstall/dist/mystartup?16632 (for module twisted.plugins)
not in path importer cache (PEP 302 violation - check your local configuration).
~/pyinstall/dist/bin/mystartup: Unknown command: myapp_plugin
Normally, Twistd inspects the Python system path to discover my plugin in twisted/plugins/myapp_plugin.py. If I print the list of twistd plugins in my startup script, the list is empty in the executable resulting from PyInstaller, e.g.
from twisted.plugin import IPlugin, getPlugins
plugins = list(getPlugins(IPlugin))
print "Twistd plugins=%s" % plugins
I use a somewhat default PyInstaller spec file, no hidden imports or import hooks specified.
I like the functionality of twistd with logging, pid files, etc, so I would like to avoid having to abandon the twistd runner altogether to circumvent the plugin issue.
Is there a way to ensure my twistd plugin is found in the frozen executable?
I found a workaround by reverse engineering some of the twisted code. Here I hardcode the plugin import. This works fine with PyInstaller for me.
#!/usr/bin/env python
import sys
from twisted.application import app
from twisted.scripts.twistd import runApp, ServerOptions
import myapp_plugin as myplugin
plug = myplugin.serviceMaker
class MyServerOptions(ServerOptions):
"""
See twisted.application.app.ServerOptions.subCommands().
Override to specify a single plugin subcommand and load the plugin
explictly.
"""
def subCommands(self):
self.loadedPlugins = {plug.tapname:plug}
yield (plug.tapname,
None,
# Avoid resolving the options attribute right away, in case
# it's a property with a non-trivial getter (eg, one which
# imports modules).
lambda plug=plug: plug.options(),
plug.description)
subCommands = property(subCommands)
def run():
"""
Replace twisted.application.app.run()
To use our ServerOptions.
"""
app.run(runApp, MyServerOptions)
sys.argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
plug.tapname] + sys.argv[1:]
run()
I am trying to run the following HelloWorld Script at Command Line
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def main():
tornado.options.parse_command_line()
application = tornado.web.Application([
(r"/", MainHandler),
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
and I am getting the following error
File "helloworld.py", line 17, in ?
import tornado.httpserver
File "/home/username/public_html/tornado-1.2.1/tornado/httpserver.py", line 28, in ?
from tornado import ioloop
File "/home/username/public_html/tornado-1.2.1/tornado/ioloop.py", line 184
action if action is not None else signal.SIG_DFL)
^
SyntaxError: invalid syntax
Brand New to Python, can someone explain what the problem being pointed out is? P.S. helloworld.py is in the /home/username/public_html/tornado-1.2.1/ directory, and there is a tornado subdirectory in the same directory.
Edit: (Ignore this edit now)
The command i am running is
python helloworld.py
The result of python -V is
Python 2.4.3
Unfortunately Tornado doesn't work with versions before 2.5 so this might be the problem. However, I have installed Python 2.6.6 How do I ensure that it is running with the correct version of Python and not the older one?
EDIT II
Now I have set Python to 2.6.6
and running
python helloworld.py
doesn't produce any output. The program just freezes at the command line.
Any thoughts here?
As you've found out yourself, the problem is that python 2.4 does not support the conditional expression operator.
How you can switch to another Python version depends on your system. On debian and Ubuntu, you can edit /usr/share/python/debian_defaults. On all Linux systems, you can remove /usr/bin/python and link to the version you'd like:
sudo mv /usr/bin/python /usr/bin/python.dist
sudo ln -s /usr/bin/python2.5 /usr/bin/python
Alternatively, you can modify the PATH environment variable to contain a directory with the desired python binary before /usr/bin (this is probably the way to go on Windows). You can make this permanent by editing ~/.profile (at every login) or ~/.bashrc (in interactive, bash shells).
To get Python 2.6 as default make sure you've mapped python to /usr/bin/python2.6 in your .bash_rc.
If you're trying to fix this, you'll need to go through and swap out the conditional operator:
if seconds is not None:
signal.signal(signal.SIGALRM,
action if action is not None else signal.SIG_DFL)
This syntax (action if action is not None else signal.SIG_DFL) is only available in Python 2.>=5
The alt? Not as nice but workable:
if seconds is not None:
if action is not None:
tmpaction = action
else
tmpaction = signal.SIG_DFL
signal.signal(signal.SIGALRM,tmpaction)
I HIGHLY RECOMMEND THAT YOU SIMPLY UPGRADE TO THE LATEST VERSION OF PYTHON. THERE IS NO GUARANTEE THAT YOU WON'T FIND OTHER ISSUES. (Unless, of course, you want the learning experience).