##// END OF EJS Templates
update copyright to 2011/20xx-2011...
update copyright to 2011/20xx-2011 Closes #1033 (rebased to prevent recursive merge). Closes #2. 459 *.py files in : 39 empty files 176 files without copyright 36 have copyright but don't cite the dev team 208 have copyright and cite the dev team ----------------------------------------- 0 not up to date (cite dev team but not right year) FYI, list of files that don't have copyright (and are not empty..) [ 'IPython/config/profile/cluster/ipython_config.py', 'IPython/config/profile/math/ipython_config.py', 'IPython/config/profile/pylab/ipython_config.py', 'IPython/config/profile/pysh/ipython_config.py', 'IPython/config/profile/python3/ipython_config.py', 'IPython/config/profile/sympy/ipython_config.py', 'IPython/core/shadowns.py', 'IPython/core/tests/refbug.py', 'IPython/core/tests/simpleerr.py', 'IPython/core/tests/tclass.py', 'IPython/core/tests/test_application.py', 'IPython/core/tests/test_autocall.py', 'IPython/core/tests/test_completer.py', 'IPython/core/tests/test_fakemodule.py', 'IPython/core/tests/test_formatters.py', 'IPython/core/tests/test_handlers.py', 'IPython/core/tests/test_history.py', 'IPython/core/tests/test_imports.py', 'IPython/core/tests/test_iplib.py', 'IPython/core/tests/test_logger.py', 'IPython/core/tests/test_magic.py', 'IPython/core/tests/test_plugin.py', 'IPython/core/tests/test_prefilter.py', 'IPython/core/tests/test_profile.py', 'IPython/core/tests/test_run.py', 'IPython/core/tests/test_splitinput.py', 'IPython/deathrow/astyle.py', 'IPython/deathrow/dtutils.py', 'IPython/deathrow/Gnuplot2.py', 'IPython/deathrow/GnuplotInteractive.py', 'IPython/deathrow/GnuplotRuntime.py', 'IPython/deathrow/gui/wx/ipshell_nonblocking.py', 'IPython/deathrow/gui/wx/ipython_history.py', 'IPython/deathrow/gui/wx/thread_ex.py', 'IPython/deathrow/ibrowse.py', 'IPython/deathrow/igrid.py', 'IPython/deathrow/ipipe.py', 'IPython/deathrow/ipy_defaults.py', 'IPython/deathrow/ipy_kitcfg.py', 'IPython/deathrow/ipy_legacy.py', 'IPython/deathrow/ipy_p4.py', 'IPython/deathrow/ipy_profile_none.py', 'IPython/deathrow/ipy_profile_numpy.py', 'IPython/deathrow/ipy_profile_scipy.py', 'IPython/deathrow/ipy_profile_sh.py', 'IPython/deathrow/ipy_traits_completer.py', 'IPython/deathrow/ipy_vimserver.py', 'IPython/deathrow/numeric_formats.py', 'IPython/deathrow/oldfrontend/process/__init__.py', 'IPython/deathrow/oldfrontend/wx/ipythonx.py', 'IPython/deathrow/scitedirector.py', 'IPython/deathrow/tests/test_prefilter.py', 'IPython/deathrow/twshell.py', 'IPython/extensions/__init__.py', 'IPython/extensions/autoreload.py', 'IPython/extensions/storemagic.py', 'IPython/extensions/tests/test_autoreload.py', 'IPython/external/__init__.py', 'IPython/external/argparse/__init__.py', 'IPython/external/decorator/__init__.py', 'IPython/external/decorators/__init__.py', 'IPython/external/decorators/_decorators.py', 'IPython/external/decorators/_numpy_testing_noseclasses.py', 'IPython/external/decorators/_numpy_testing_utils.py', 'IPython/external/guid/__init__.py', 'IPython/external/Itpl/__init__.py', 'IPython/external/mglob/__init__.py', 'IPython/external/mglob/_mglob.py', 'IPython/external/path/__init__.py', 'IPython/external/path/_path.py', 'IPython/external/pexpect/__init__.py', 'IPython/external/pyparsing/__init__.py', 'IPython/external/qt.py', 'IPython/external/qt_for_kernel.py', 'IPython/external/simplegeneric/__init__.py', 'IPython/external/simplegeneric/_simplegeneric.py', 'IPython/frontend/html/notebook/__init__.py', 'IPython/frontend/html/notebook/tests/test_kernelsession.py', 'IPython/frontend/qt/base_frontend_mixin.py', 'IPython/frontend/qt/console/ansi_code_processor.py', 'IPython/frontend/qt/console/bracket_matcher.py', 'IPython/frontend/qt/console/call_tip_widget.py', 'IPython/frontend/qt/console/completion_lexer.py', 'IPython/frontend/qt/console/completion_widget.py', 'IPython/frontend/qt/console/console_widget.py', 'IPython/frontend/qt/console/history_console_widget.py', 'IPython/frontend/qt/console/ipython_widget.py', 'IPython/frontend/qt/console/kill_ring.py', 'IPython/frontend/qt/console/mainwindow.py', 'IPython/frontend/qt/console/pygments_highlighter.py', 'IPython/frontend/qt/console/qtconsoleapp.py', 'IPython/frontend/qt/console/rich_ipython_widget.py', 'IPython/frontend/qt/console/styles.py', 'IPython/frontend/qt/console/tests/test_ansi_code_processor.py', 'IPython/frontend/qt/console/tests/test_completion_lexer.py', 'IPython/frontend/qt/console/tests/test_kill_ring.py', 'IPython/frontend/qt/kernelmanager.py', 'IPython/frontend/qt/rich_text.py', 'IPython/frontend/qt/svg.py', 'IPython/frontend/qt/util.py', 'IPython/kernel/__init__.py', 'IPython/lib/clipboard.py', 'IPython/lib/display.py', 'IPython/lib/irunner.py', 'IPython/lib/security.py', 'IPython/lib/tests/test_imports.py', 'IPython/lib/tests/test_irunner.py', 'IPython/lib/tests/test_irunner_pylab_magic.py', 'IPython/lib/tests/test_security.py', 'IPython/nbformat/v1/tests/nbexamples.py', 'IPython/nbformat/v1/tests/test_json.py', 'IPython/nbformat/v1/tests/test_nbbase.py', 'IPython/nbformat/v2/tests/nbexamples.py', 'IPython/nbformat/v2/tests/test_json.py', 'IPython/nbformat/v2/tests/test_nbbase.py', 'IPython/nbformat/v2/tests/test_nbpy.py', 'IPython/quarantine/clearcmd.py', 'IPython/quarantine/envpersist.py', 'IPython/quarantine/ext_rescapture.py', 'IPython/quarantine/ipy_app_completers.py', 'IPython/quarantine/ipy_completers.py', 'IPython/quarantine/ipy_editors.py', 'IPython/quarantine/ipy_exportdb.py', 'IPython/quarantine/ipy_extutil.py', 'IPython/quarantine/ipy_fsops.py', 'IPython/quarantine/ipy_gnuglobal.py', 'IPython/quarantine/ipy_jot.py', 'IPython/quarantine/ipy_lookfor.py', 'IPython/quarantine/ipy_profile_doctest.py', 'IPython/quarantine/ipy_pydb.py', 'IPython/quarantine/ipy_rehashdir.py', 'IPython/quarantine/ipy_render.py', 'IPython/quarantine/ipy_server.py', 'IPython/quarantine/ipy_signals.py', 'IPython/quarantine/ipy_synchronize_with.py', 'IPython/quarantine/ipy_system_conf.py', 'IPython/quarantine/ipy_which.py', 'IPython/quarantine/ipy_winpdb.py', 'IPython/quarantine/ipy_workdir.py', 'IPython/quarantine/jobctrl.py', 'IPython/quarantine/ledit.py', 'IPython/quarantine/win32clip.py', 'IPython/testing/mkdoctests.py', 'IPython/testing/plugin/dtexample.py', 'IPython/testing/plugin/ipdoctest.py', 'IPython/testing/plugin/iptest.py', 'IPython/testing/plugin/setup.py', 'IPython/testing/plugin/show_refs.py', 'IPython/testing/plugin/simple.py', 'IPython/testing/plugin/simplevars.py', 'IPython/testing/plugin/test_ipdoctest.py', 'IPython/testing/plugin/test_refs.py', 'IPython/testing/skipdoctest.py', 'IPython/testing/tests/test_decorators.py', 'IPython/utils/autoattr.py', 'IPython/utils/nested_context.py', 'IPython/utils/pickleshare.py', 'IPython/utils/py3compat.py', 'IPython/utils/PyColorize.py', 'IPython/utils/rlineimpl.py', 'IPython/utils/strdispatch.py', 'IPython/utils/tempdir.py', 'IPython/utils/tests/test_imports.py', 'IPython/utils/tests/test_wildcard.py', 'IPython/utils/upgradedir.py', 'IPython/zmq/completer.py', 'IPython/zmq/displayhook.py', 'IPython/zmq/entry_point.py', 'IPython/zmq/frontend.py', 'IPython/zmq/iostream.py', 'IPython/zmq/ipkernel.py', 'IPython/zmq/log.py', 'IPython/zmq/parentpoller.py', 'IPython/zmq/pykernel.py', 'IPython/zmq/pylab/backend_inline.py', 'IPython/zmq/zmqshell.py' ]

File last commit:

r4872:34c10438
r5390:c82649ea
Show More
jobctrl.py
242 lines | 6.3 KiB | text/x-python | PythonLexer
""" Preliminary "job control" extensions for IPython
requires python 2.4 (or separate 'subprocess' module
This provides 2 features, launching background jobs and killing foreground jobs from another IPython instance.
Launching background jobs:
Usage:
[ipython]|2> import jobctrl
[ipython]|3> &ls
<3> <jobctrl.IpyPopen object at 0x00D87FD0>
[ipython]|4> _3.go
-----------> _3.go()
ChangeLog
IPython
MANIFEST.in
README
README_Windows.txt
...
Killing foreground tasks:
Launch IPython instance, run a blocking command:
[Q:/ipython]|1> import jobctrl
[Q:/ipython]|2> cat
Now launch a new IPython prompt and kill the process:
IPython 0.8.3.svn.r2919 [on Py 2.5]
[Q:/ipython]|1> import jobctrl
[Q:/ipython]|2> %tasks
6020: 'cat ' (Q:\ipython)
[Q:/ipython]|3> %kill
SUCCESS: The process with PID 6020 has been terminated.
[Q:/ipython]|4>
(you don't need to specify PID for %kill if only one task is running)
"""
from subprocess import *
import os,shlex,sys,time
import threading,Queue
from IPython.core import ipapi
from IPython.core.error import TryNext
from IPython.utils.text import make_quoted_expr
if os.name == 'nt':
def kill_process(pid):
os.system('taskkill /F /PID %d' % pid)
else:
def kill_process(pid):
os.system('kill -9 %d' % pid)
class IpyPopen(Popen):
def go(self):
print self.communicate()[0]
def __repr__(self):
return '<IPython job "%s" PID=%d>' % (self.line, self.pid)
def kill(self):
kill_process(self.pid)
def startjob(job):
p = IpyPopen(shlex.split(job), stdout=PIPE, shell = False)
p.line = job
return p
class AsyncJobQ(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.q = Queue.Queue()
self.output = []
self.stop = False
def run(self):
while 1:
cmd,cwd = self.q.get()
if self.stop:
self.output.append("** Discarding: '%s' - %s" % (cmd,cwd))
continue
self.output.append("** Task started: '%s' - %s" % (cmd,cwd))
p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd = cwd)
out = p.stdout.read()
self.output.append("** Task complete: '%s'\n" % cmd)
self.output.append(out)
def add(self,cmd):
self.q.put_nowait((cmd, os.getcwdu()))
def dumpoutput(self):
while self.output:
item = self.output.pop(0)
print item
_jobq = None
def jobqueue_f(self, line):
global _jobq
if not _jobq:
print "Starting jobqueue - do '&some_long_lasting_system_command' to enqueue"
_jobq = AsyncJobQ()
_jobq.setDaemon(True)
_jobq.start()
ip.jobq = _jobq.add
return
if line.strip() == 'stop':
print "Stopping and clearing jobqueue, %jobqueue start to start again"
_jobq.stop = True
return
if line.strip() == 'start':
_jobq.stop = False
return
def jobctrl_prefilter_f(self,line):
if line.startswith('&'):
pre,fn,rest = self.split_user_input(line[1:])
line = ip.expand_aliases(fn,rest)
if not _jobq:
return 'get_ipython().startjob(%s)' % make_quoted_expr(line)
return 'get_ipython().jobq(%s)' % make_quoted_expr(line)
raise TryNext
def jobq_output_hook(self):
if not _jobq:
return
_jobq.dumpoutput()
def job_list(ip):
keys = ip.db.keys('tasks/*')
ents = [ip.db[k] for k in keys]
return ents
def magic_tasks(self,line):
""" Show a list of tasks.
A 'task' is a process that has been started in IPython when 'jobctrl' extension is enabled.
Tasks can be killed with %kill.
'%tasks clear' clears the task list (from stale tasks)
"""
ip = self.getapi()
if line.strip() == 'clear':
for k in ip.db.keys('tasks/*'):
print "Clearing",ip.db[k]
del ip.db[k]
return
ents = job_list(ip)
if not ents:
print "No tasks running"
for pid,cmd,cwd,t in ents:
dur = int(time.time()-t)
print "%d: '%s' (%s) %d:%02d" % (pid,cmd,cwd, dur / 60,dur%60)
def magic_kill(self,line):
""" Kill a task
Without args, either kill one task (if only one running) or show list (if many)
With arg, assume it's the process id.
%kill is typically (much) more powerful than trying to terminate a process with ctrl+C.
"""
ip = self.getapi()
jobs = job_list(ip)
if not line.strip():
if len(jobs) == 1:
kill_process(jobs[0][0])
else:
magic_tasks(self,line)
return
try:
pid = int(line)
kill_process(pid)
except ValueError:
magic_tasks(self,line)
if sys.platform == 'win32':
shell_internal_commands = 'break chcp cls copy ctty date del erase dir md mkdir path prompt rd rmdir start time type ver vol'.split()
PopenExc = WindowsError
else:
# todo linux commands
shell_internal_commands = []
PopenExc = OSError
def jobctrl_shellcmd(ip,cmd):
""" os.system replacement that stores process info to db['tasks/t1234'] """
cmd = cmd.strip()
cmdname = cmd.split(None,1)[0]
if cmdname in shell_internal_commands or '|' in cmd or '>' in cmd or '<' in cmd:
use_shell = True
else:
use_shell = False
jobentry = None
try:
try:
p = Popen(cmd,shell = use_shell)
except PopenExc :
if use_shell:
# try with os.system
os.system(cmd)
return
else:
# have to go via shell, sucks
p = Popen(cmd,shell = True)
jobentry = 'tasks/t' + str(p.pid)
ip.db[jobentry] = (p.pid,cmd,os.getcwdu(),time.time())
p.communicate()
finally:
if jobentry:
del ip.db[jobentry]
def install():
global ip
ip = ipapi.get()
# needed to make startjob visible as _ip.startjob('blah')
ip.startjob = startjob
ip.set_hook('input_prefilter', jobctrl_prefilter_f)
ip.set_hook('shell_hook', jobctrl_shellcmd)
ip.define_magic('kill',magic_kill)
ip.define_magic('tasks',magic_tasks)
ip.define_magic('jobqueue',jobqueue_f)
ip.set_hook('pre_prompt_hook', jobq_output_hook)
install()